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 9123258 : neg_poly_int_rtx (machine_mode mode, const_rtx i)
56 : {
57 9123258 : 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 6230625 : mode_signbit_p (machine_mode mode, const_rtx x)
65 : {
66 6230625 : unsigned HOST_WIDE_INT val;
67 6230625 : unsigned int width;
68 6230625 : scalar_int_mode int_mode;
69 :
70 6230625 : if (!is_int_mode (mode, &int_mode))
71 : return false;
72 :
73 6230617 : width = GET_MODE_PRECISION (int_mode);
74 6230617 : if (width == 0)
75 : return false;
76 :
77 6230617 : if (width <= HOST_BITS_PER_WIDE_INT
78 6229082 : && CONST_INT_P (x))
79 6078410 : val = INTVAL (x);
80 : #if TARGET_SUPPORTS_WIDE_INT
81 152207 : else if (CONST_WIDE_INT_P (x))
82 : {
83 483 : unsigned int i;
84 483 : unsigned int elts = CONST_WIDE_INT_NUNITS (x);
85 483 : if (elts != (width + HOST_BITS_PER_WIDE_INT - 1) / HOST_BITS_PER_WIDE_INT)
86 : return false;
87 906 : for (i = 0; i < elts - 1; i++)
88 483 : if (CONST_WIDE_INT_ELT (x, i) != 0)
89 : return false;
90 423 : val = CONST_WIDE_INT_ELT (x, elts - 1);
91 423 : width %= HOST_BITS_PER_WIDE_INT;
92 423 : if (width == 0)
93 : width = HOST_BITS_PER_WIDE_INT;
94 : }
95 : #else
96 : else if (width <= HOST_BITS_PER_DOUBLE_INT
97 : && CONST_DOUBLE_AS_INT_P (x)
98 : && CONST_DOUBLE_LOW (x) == 0)
99 : {
100 : val = CONST_DOUBLE_HIGH (x);
101 : width -= HOST_BITS_PER_WIDE_INT;
102 : }
103 : #endif
104 : else
105 : /* X is not an integer constant. */
106 : return false;
107 :
108 6078410 : if (width < HOST_BITS_PER_WIDE_INT)
109 5527197 : val &= (HOST_WIDE_INT_1U << width) - 1;
110 6078833 : 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 3797934 : val_signbit_p (machine_mode mode, unsigned HOST_WIDE_INT val)
119 : {
120 3797934 : unsigned int width;
121 3797934 : scalar_int_mode int_mode;
122 :
123 3797934 : if (!is_int_mode (mode, &int_mode))
124 : return false;
125 :
126 3797898 : width = GET_MODE_PRECISION (int_mode);
127 3797898 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
128 : return false;
129 :
130 3792912 : val &= GET_MODE_MASK (int_mode);
131 3792912 : 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 2628813 : val_signbit_known_set_p (machine_mode mode, unsigned HOST_WIDE_INT val)
138 : {
139 2628813 : unsigned int width;
140 :
141 2628813 : scalar_int_mode int_mode;
142 2628813 : if (!is_int_mode (mode, &int_mode))
143 : return false;
144 :
145 2582625 : width = GET_MODE_PRECISION (int_mode);
146 2582625 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
147 : return false;
148 :
149 2582625 : val &= HOST_WIDE_INT_1U << (width - 1);
150 2582625 : 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 7824665 : val_signbit_known_clear_p (machine_mode mode, unsigned HOST_WIDE_INT val)
157 : {
158 7824665 : unsigned int width;
159 :
160 7824665 : scalar_int_mode int_mode;
161 7824665 : if (!is_int_mode (mode, &int_mode))
162 : return false;
163 :
164 7467352 : width = GET_MODE_PRECISION (int_mode);
165 7467352 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
166 : return false;
167 :
168 7356697 : val &= HOST_WIDE_INT_1U << (width - 1);
169 7356697 : 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 121734712 : simplify_context::simplify_gen_binary (rtx_code code, machine_mode mode,
177 : rtx op0, rtx op1)
178 : {
179 121734712 : rtx tem;
180 :
181 : /* If this simplifies, do it. */
182 121734712 : tem = simplify_binary_operation (code, mode, op0, op1);
183 121734712 : if (tem)
184 : return tem;
185 :
186 : /* Put complex operands first and constants second if commutative. */
187 77307523 : if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
188 77307523 : && swap_commutative_operands_p (op0, op1))
189 : std::swap (op0, op1);
190 :
191 77307523 : 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 2786504311 : avoid_constant_pool_reference (rtx x)
198 : {
199 2786504311 : rtx c, tmp, addr;
200 2786504311 : machine_mode cmode;
201 2786504311 : poly_int64 offset = 0;
202 :
203 2786504311 : switch (GET_CODE (x))
204 : {
205 266861124 : case MEM:
206 266861124 : break;
207 :
208 916183 : case FLOAT_EXTEND:
209 : /* Handle float extensions of constant pool references. */
210 916183 : tmp = XEXP (x, 0);
211 916183 : c = avoid_constant_pool_reference (tmp);
212 916183 : if (c != tmp && CONST_DOUBLE_AS_FLOAT_P (c))
213 124932 : return const_double_from_real_value (*CONST_DOUBLE_REAL_VALUE (c),
214 124932 : GET_MODE (x));
215 : return x;
216 :
217 : default:
218 : return x;
219 : }
220 :
221 266861124 : if (GET_MODE (x) == BLKmode)
222 : return x;
223 :
224 262772168 : addr = XEXP (x, 0);
225 :
226 : /* Call target hook to avoid the effects of -fpic etc.... */
227 262772168 : addr = targetm.delegitimize_address (addr);
228 :
229 : /* Split the address into a base and integer offset. */
230 262772168 : addr = strip_offset (addr, &offset);
231 :
232 262772168 : 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 262772168 : if (GET_CODE (addr) == SYMBOL_REF
238 262772168 : && CONSTANT_POOL_ADDRESS_P (addr))
239 : {
240 5387842 : c = get_pool_constant (addr);
241 5387842 : 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 5387842 : if (known_eq (offset, 0) && cmode == GET_MODE (x))
247 : return c;
248 44856 : else if (known_in_range_p (offset, 0, GET_MODE_SIZE (cmode)))
249 : {
250 14952 : rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset);
251 14952 : if (tem && CONSTANT_P (tem))
252 14835 : 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 3564842858 : 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 3564842858 : if (MEM_P (x)
269 63227483 : && MEM_EXPR (x)
270 3604138686 : && MEM_OFFSET_KNOWN_P (x))
271 : {
272 36296774 : tree decl = MEM_EXPR (x);
273 36296774 : machine_mode mode = GET_MODE (x);
274 36296774 : poly_int64 offset = 0;
275 :
276 36296774 : switch (TREE_CODE (decl))
277 : {
278 : default:
279 : decl = NULL;
280 : break;
281 :
282 : case VAR_DECL:
283 : break;
284 :
285 10218974 : case ARRAY_REF:
286 10218974 : case ARRAY_RANGE_REF:
287 10218974 : case COMPONENT_REF:
288 10218974 : case BIT_FIELD_REF:
289 10218974 : case REALPART_EXPR:
290 10218974 : case IMAGPART_EXPR:
291 10218974 : case VIEW_CONVERT_EXPR:
292 10218974 : {
293 10218974 : poly_int64 bitsize, bitpos, bytepos, toffset_val = 0;
294 10218974 : tree toffset;
295 10218974 : int unsignedp, reversep, volatilep = 0;
296 :
297 10218974 : decl
298 10218974 : = get_inner_reference (decl, &bitsize, &bitpos, &toffset, &mode,
299 : &unsignedp, &reversep, &volatilep);
300 20437948 : if (maybe_ne (bitsize, GET_MODE_BITSIZE (mode))
301 10515296 : || !multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
302 19997593 : || (toffset && !poly_int_tree_p (toffset, &toffset_val)))
303 : decl = NULL;
304 : else
305 9482297 : offset += bytepos + toffset_val;
306 10218974 : break;
307 : }
308 : }
309 :
310 736677 : if (decl
311 21328520 : && mode == GET_MODE (x)
312 21057694 : && VAR_P (decl)
313 13761545 : && (TREE_STATIC (decl)
314 12530142 : || DECL_THREAD_LOCAL_P (decl))
315 1268369 : && DECL_RTL_SET_P (decl)
316 10750196 : && MEM_P (DECL_RTL (decl)))
317 : {
318 1267899 : rtx newx;
319 :
320 1267899 : offset += MEM_OFFSET (x);
321 :
322 1267899 : newx = DECL_RTL (decl);
323 :
324 1267899 : if (MEM_P (newx))
325 : {
326 1267899 : rtx n = XEXP (newx, 0), o = XEXP (x, 0);
327 1267899 : 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 1267899 : n = strip_offset (n, &n_offset);
336 1267899 : o = strip_offset (o, &o_offset);
337 2507962 : if (!(known_eq (o_offset, n_offset + offset)
338 1240063 : && rtx_equal_p (o, n)))
339 212538 : 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 3564842858 : 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 7134498 : simplify_context::simplify_gen_unary (rtx_code code, machine_mode mode, rtx op,
355 : machine_mode op_mode)
356 : {
357 7134498 : rtx tem;
358 :
359 : /* If this simplifies, use it. */
360 7134498 : if ((tem = simplify_unary_operation (code, mode, op, op_mode)) != 0)
361 : return tem;
362 :
363 2440005 : return gen_rtx_fmt_e (code, mode, op);
364 : }
365 :
366 : /* Likewise for ternary operations. */
367 :
368 : rtx
369 2430018 : 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 2430018 : rtx tem;
374 :
375 : /* If this simplifies, use it. */
376 2430018 : if ((tem = simplify_ternary_operation (code, mode, op0_mode,
377 : op0, op1, op2)) != 0)
378 : return tem;
379 :
380 2178870 : 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 21808476 : simplify_context::simplify_gen_relational (rtx_code code, machine_mode mode,
388 : machine_mode cmp_mode,
389 : rtx op0, rtx op1)
390 : {
391 21808476 : rtx tem;
392 :
393 21808476 : if ((tem = simplify_relational_operation (code, mode, cmp_mode,
394 : op0, op1)) != 0)
395 : return tem;
396 :
397 19630035 : 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 504157799 : simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
407 : rtx (*fn) (rtx, const_rtx, void *), void *data)
408 : {
409 504157799 : enum rtx_code code = GET_CODE (x);
410 504157799 : machine_mode mode = GET_MODE (x);
411 504157799 : machine_mode op_mode;
412 504157799 : const char *fmt;
413 504157799 : rtx op0, op1, op2, newx, op;
414 504157799 : rtvec vec, newvec;
415 504157799 : int i, j;
416 :
417 504157799 : if (UNLIKELY (fn != NULL))
418 : {
419 441838527 : newx = fn (x, old_rtx, data);
420 441838527 : if (newx)
421 : return newx;
422 : }
423 62319272 : else if (rtx_equal_p (x, old_rtx))
424 5199091 : return copy_rtx ((rtx) data);
425 :
426 397504366 : switch (GET_RTX_CLASS (code))
427 : {
428 2062448 : case RTX_UNARY:
429 2062448 : op0 = XEXP (x, 0);
430 2062448 : op_mode = GET_MODE (op0);
431 2062448 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
432 2062448 : if (op0 == XEXP (x, 0))
433 : return x;
434 650596 : return simplify_gen_unary (code, mode, op0, op_mode);
435 :
436 76442747 : case RTX_BIN_ARITH:
437 76442747 : case RTX_COMM_ARITH:
438 76442747 : op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
439 76442747 : op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
440 76442747 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
441 : return x;
442 23653460 : return simplify_gen_binary (code, mode, op0, op1);
443 :
444 9765795 : case RTX_COMPARE:
445 9765795 : case RTX_COMM_COMPARE:
446 9765795 : op0 = XEXP (x, 0);
447 9765795 : op1 = XEXP (x, 1);
448 9765795 : op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
449 9765795 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
450 9765795 : op1 = simplify_replace_fn_rtx (op1, old_rtx, fn, data);
451 9765795 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
452 : return x;
453 2339180 : return simplify_gen_relational (code, mode, op_mode, op0, op1);
454 :
455 5875596 : case RTX_TERNARY:
456 5875596 : case RTX_BITFIELD_OPS:
457 5875596 : op0 = XEXP (x, 0);
458 5875596 : op_mode = GET_MODE (op0);
459 5875596 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
460 5875596 : op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
461 5875596 : op2 = simplify_replace_fn_rtx (XEXP (x, 2), old_rtx, fn, data);
462 5875596 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2))
463 : return x;
464 1686004 : if (op_mode == VOIDmode)
465 1662360 : op_mode = GET_MODE (op0);
466 1686004 : return simplify_gen_ternary (code, mode, op_mode, op0, op1, op2);
467 :
468 90584053 : case RTX_EXTRA:
469 90584053 : if (code == SUBREG)
470 : {
471 619288 : op0 = simplify_replace_fn_rtx (SUBREG_REG (x), old_rtx, fn, data);
472 619288 : if (op0 == SUBREG_REG (x))
473 : return x;
474 133684 : op0 = simplify_gen_subreg (GET_MODE (x), op0,
475 66842 : GET_MODE (SUBREG_REG (x)),
476 66842 : SUBREG_BYTE (x));
477 66842 : return op0 ? op0 : x;
478 : }
479 : break;
480 :
481 63317177 : case RTX_OBJ:
482 63317177 : if (code == MEM)
483 : {
484 10869518 : op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
485 10869518 : if (op0 == XEXP (x, 0))
486 : return x;
487 162563 : return replace_equiv_address_nv (x, op0);
488 : }
489 52447659 : 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 291868974 : newx = x;
515 291868974 : fmt = GET_RTX_FORMAT (code);
516 631210098 : for (i = 0; fmt[i]; i++)
517 339341124 : switch (fmt[i])
518 : {
519 3251835 : case 'E':
520 3251835 : vec = XVEC (x, i);
521 3251835 : newvec = XVEC (newx, i);
522 13572421 : for (j = 0; j < GET_NUM_ELEM (vec); j++)
523 : {
524 10320586 : op = simplify_replace_fn_rtx (RTVEC_ELT (vec, j),
525 : old_rtx, fn, data);
526 10320586 : if (op != RTVEC_ELT (vec, j))
527 : {
528 356706 : if (newvec == vec)
529 : {
530 342146 : newvec = shallow_copy_rtvec (vec);
531 342146 : if (x == newx)
532 342146 : newx = shallow_copy_rtx (x);
533 342146 : XVEC (newx, i) = newvec;
534 : }
535 356706 : RTVEC_ELT (newvec, j) = op;
536 : }
537 : }
538 : break;
539 :
540 81938459 : case 'e':
541 81938459 : if (XEXP (x, i))
542 : {
543 81938408 : op = simplify_replace_fn_rtx (XEXP (x, i), old_rtx, fn, data);
544 81938408 : if (op != XEXP (x, i))
545 : {
546 4652217 : if (x == newx)
547 4649034 : newx = shallow_copy_rtx (x);
548 4652217 : 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 12796126 : simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx)
561 : {
562 12796126 : 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 23474838 : simplify_context::simplify_truncation (machine_mode mode, rtx op,
614 : machine_mode op_mode)
615 : {
616 23474838 : unsigned int precision = GET_MODE_UNIT_PRECISION (mode);
617 23474838 : unsigned int op_precision = GET_MODE_UNIT_PRECISION (op_mode);
618 23474838 : scalar_int_mode int_mode, int_op_mode, subreg_mode;
619 :
620 23474838 : gcc_assert (precision <= op_precision);
621 :
622 : /* Optimize truncations of zero and sign extended values. */
623 23474838 : if (GET_CODE (op) == ZERO_EXTEND
624 23474838 : || 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 374602 : machine_mode origmode = GET_MODE (XEXP (op, 0));
633 374602 : if (mode == origmode)
634 : return XEXP (op, 0);
635 26756 : else if (precision <= GET_MODE_UNIT_PRECISION (origmode))
636 10528 : return simplify_gen_unary (TRUNCATE, mode,
637 10528 : XEXP (op, 0), origmode);
638 : else
639 2850 : return simplify_gen_unary (GET_CODE (op), mode,
640 2850 : 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 23100236 : if (1
647 : && (!WORD_REGISTER_OPERATIONS || precision >= BITS_PER_WORD)
648 : && (GET_CODE (op) == PLUS
649 : || GET_CODE (op) == MINUS
650 23100236 : || GET_CODE (op) == MULT))
651 : {
652 1408536 : rtx op0 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0), op_mode);
653 1408536 : if (op0)
654 : {
655 1408536 : rtx op1 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 1), op_mode);
656 1408536 : if (op1)
657 1408536 : 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 21691700 : if ((GET_CODE (op) == LSHIFTRT
665 21691700 : || 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 1914296 : && 2 * precision <= op_precision
671 1914296 : && CONST_INT_P (XEXP (op, 1))
672 1812997 : && 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 21691676 : if ((GET_CODE (op) == LSHIFTRT
682 : || GET_CODE (op) == ASHIFTRT)
683 1914272 : && CONST_INT_P (XEXP (op, 1))
684 1812973 : && GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
685 805 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
686 805 : && UINTVAL (XEXP (op, 1)) < precision)
687 788 : return simplify_gen_binary (LSHIFTRT, mode,
688 788 : 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 21690888 : if (GET_CODE (op) == ASHIFT
694 837727 : && CONST_INT_P (XEXP (op, 1))
695 778143 : && (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
696 778143 : || GET_CODE (XEXP (op, 0)) == SIGN_EXTEND)
697 674 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
698 666 : && UINTVAL (XEXP (op, 1)) < precision)
699 621 : return simplify_gen_binary (ASHIFT, mode,
700 621 : 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 21690267 : if (GET_CODE (op) == AND
706 790920 : && (GET_CODE (XEXP (op, 0)) == LSHIFTRT
707 790920 : || GET_CODE (XEXP (op, 0)) == ASHIFTRT)
708 45802 : && CONST_INT_P (XEXP (XEXP (op, 0), 1))
709 45700 : && CONST_INT_P (XEXP (op, 1)))
710 : {
711 45667 : rtx op0 = (XEXP (XEXP (op, 0), 0));
712 45667 : rtx shift_op = XEXP (XEXP (op, 0), 1);
713 45667 : rtx mask_op = XEXP (op, 1);
714 45667 : unsigned HOST_WIDE_INT shift = UINTVAL (shift_op);
715 45667 : unsigned HOST_WIDE_INT mask = UINTVAL (mask_op);
716 :
717 45667 : if (shift < precision
718 : /* If doing this transform works for an X with all bits set,
719 : it works for any X. */
720 29817 : && ((GET_MODE_MASK (mode) >> shift) & mask)
721 29817 : == ((GET_MODE_MASK (op_mode) >> shift) & mask)
722 6697 : && (op0 = simplify_gen_unary (TRUNCATE, mode, op0, op_mode))
723 52364 : && (op0 = simplify_gen_binary (LSHIFTRT, mode, op0, shift_op)))
724 : {
725 6697 : mask_op = GEN_INT (trunc_int_for_mode (mask, mode));
726 6697 : return simplify_gen_binary (AND, mode, op0, mask_op);
727 : }
728 : }
729 :
730 : /* Turn (truncate:M1 (*_extract:M2 (reg:M3) (len) (pos))) into
731 : (*_extract:M1 (truncate:M1 (reg:M3)) (len) (pos')) if possible. */
732 21683570 : if ((GET_CODE (op) == ZERO_EXTRACT || GET_CODE (op) == SIGN_EXTRACT)
733 1120100 : && precision <= GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (op, 0)))
734 558437 : && CONST_INT_P (XEXP (op, 1))
735 22242007 : && CONST_INT_P (XEXP (op, 2)))
736 : {
737 523511 : rtx op0 = XEXP (op, 0);
738 523511 : unsigned HOST_WIDE_INT len = UINTVAL (XEXP (op, 1));
739 523511 : unsigned HOST_WIDE_INT pos = UINTVAL (XEXP (op, 2));
740 523511 : if (BITS_BIG_ENDIAN && pos >= op_precision - precision)
741 : {
742 : if (GET_MODE (op0) != mode)
743 : op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
744 : if (op0)
745 : {
746 : pos -= op_precision - precision;
747 : return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
748 : XEXP (op, 1), GEN_INT (pos));
749 : }
750 : }
751 523511 : else if (!BITS_BIG_ENDIAN && precision >= len + pos)
752 : {
753 174238 : if (GET_MODE (op0) != mode)
754 133214 : op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
755 133214 : if (op0)
756 174238 : return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
757 174238 : XEXP (op, 1), XEXP (op, 2));
758 : }
759 : }
760 :
761 : /* Recognize a word extraction from a multi-word subreg. */
762 21509332 : if ((GET_CODE (op) == LSHIFTRT
763 21509332 : || GET_CODE (op) == ASHIFTRT)
764 1913484 : && SCALAR_INT_MODE_P (mode)
765 1910394 : && SCALAR_INT_MODE_P (op_mode)
766 2048327 : && precision >= BITS_PER_WORD
767 61844 : && 2 * precision <= op_precision
768 61844 : && CONST_INT_P (XEXP (op, 1))
769 52267 : && (INTVAL (XEXP (op, 1)) & (precision - 1)) == 0
770 2113 : && UINTVAL (XEXP (op, 1)) < op_precision)
771 : {
772 2113 : poly_int64 byte = subreg_lowpart_offset (mode, op_mode);
773 2113 : int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
774 2113 : return simplify_gen_subreg (mode, XEXP (op, 0), op_mode,
775 : (WORDS_BIG_ENDIAN
776 2113 : ? byte - shifted_bytes
777 2113 : : 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 21507219 : if ((GET_CODE (op) == LSHIFTRT
784 : || GET_CODE (op) == ASHIFTRT)
785 1908281 : && is_a <scalar_int_mode> (mode, &int_mode)
786 21506531 : && is_a <scalar_int_mode> (op_mode, &int_op_mode)
787 1908281 : && MEM_P (XEXP (op, 0))
788 11280 : && CONST_INT_P (XEXP (op, 1))
789 20660 : && INTVAL (XEXP (op, 1)) % GET_MODE_BITSIZE (int_mode) == 0
790 731 : && INTVAL (XEXP (op, 1)) > 0
791 1462 : && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (int_op_mode)
792 731 : && ! mode_dependent_address_p (XEXP (XEXP (op, 0), 0),
793 731 : MEM_ADDR_SPACE (XEXP (op, 0)))
794 731 : && ! MEM_VOLATILE_P (XEXP (op, 0))
795 21507219 : && (GET_MODE_SIZE (int_mode) >= UNITS_PER_WORD
796 : || WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN))
797 : {
798 688 : poly_int64 byte = subreg_lowpart_offset (int_mode, int_op_mode);
799 688 : int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
800 688 : 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 21506531 : if ((GET_CODE (op) == ABS
809 21506531 : || GET_CODE (op) == NEG)
810 21121 : && (GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
811 21121 : || 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 21506530 : if (GET_CODE (op) == SUBREG
818 21507079 : && is_a <scalar_int_mode> (mode, &int_mode)
819 116424 : && SCALAR_INT_MODE_P (op_mode)
820 116424 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &subreg_mode)
821 21622459 : && subreg_lowpart_p (op))
822 : {
823 : /* (truncate:A (subreg:B (truncate:C X) 0)) is (truncate:A X). */
824 115909 : 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 115909 : if (is_a <scalar_int_mode> (op_mode, &int_op_mode))
841 : {
842 115909 : unsigned int int_op_prec = GET_MODE_PRECISION (int_op_mode);
843 115909 : unsigned int subreg_prec = GET_MODE_PRECISION (subreg_mode);
844 115909 : if (int_op_prec > subreg_prec)
845 : {
846 85788 : 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 30121 : else if (int_op_prec < subreg_prec
855 30121 : && GET_MODE_PRECISION (int_mode) < int_op_prec)
856 30121 : return simplify_gen_unary (TRUNCATE, int_mode,
857 30121 : SUBREG_REG (op), subreg_mode);
858 : }
859 : }
860 :
861 : /* (truncate:A (truncate:B X)) is (truncate:A X). */
862 21390655 : 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 21390655 : if (GET_CODE (op) == IOR
869 38352 : && SCALAR_INT_MODE_P (mode)
870 38352 : && SCALAR_INT_MODE_P (op_mode)
871 38352 : && CONST_INT_P (XEXP (op, 1))
872 21399722 : && 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 29747262 : simplify_context::simplify_unary_operation (rtx_code code, machine_mode mode,
883 : rtx op, machine_mode op_mode)
884 : {
885 29747262 : rtx trueop, tem;
886 :
887 29747262 : trueop = avoid_constant_pool_reference (op);
888 :
889 29747262 : tem = simplify_const_unary_operation (code, mode, trueop, op_mode);
890 29747262 : if (tem)
891 : return tem;
892 :
893 24328368 : 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 2833 : exact_int_to_float_conversion_p (const_rtx op)
901 : {
902 2833 : 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 2833 : if (op0_mode == VOIDmode)
906 : return false;
907 5664 : int out_bits = significand_size (GET_MODE_INNER (GET_MODE (op)));
908 2832 : int in_prec = GET_MODE_UNIT_PRECISION (op0_mode);
909 2832 : int in_bits = in_prec;
910 2832 : if (HWI_COMPUTABLE_MODE_P (op0_mode))
911 : {
912 2742 : unsigned HOST_WIDE_INT nonzero = nonzero_bits (XEXP (op, 0), op0_mode);
913 2742 : if (GET_CODE (op) == FLOAT)
914 2621 : in_bits -= num_sign_bit_copies (XEXP (op, 0), op0_mode);
915 121 : else if (GET_CODE (op) == UNSIGNED_FLOAT)
916 121 : in_bits = wi::min_precision (wi::uhwi (nonzero, in_prec), UNSIGNED);
917 : else
918 0 : gcc_unreachable ();
919 2742 : in_bits -= wi::ctz (wi::uhwi (nonzero, in_prec));
920 : }
921 2832 : 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 24328368 : simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
928 : rtx op)
929 : {
930 24328368 : enum rtx_code reversed;
931 24328368 : rtx temp, elt, base, step;
932 24328368 : scalar_int_mode inner, int_mode, op_mode, op0_mode;
933 :
934 24328368 : switch (code)
935 : {
936 2330368 : case NOT:
937 : /* (not (not X)) == X. */
938 2330368 : if (GET_CODE (op) == NOT)
939 3141 : 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 2327227 : if (COMPARISON_P (op)
944 17101 : && ((SCALAR_INT_MODE_P (mode) && STORE_FLAG_VALUE == -1)
945 : #ifdef VECTOR_STORE_FLAG_VALUE
946 17101 : || (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
947 : && VECTOR_STORE_FLAG_VALUE (mode) == constm1_rtx)
948 : #endif
949 11831 : || mode == BImode)
950 2332497 : && ((reversed = reversed_comparison_code (op, NULL)) != UNKNOWN))
951 5101 : return simplify_gen_relational (reversed, mode, VOIDmode,
952 5101 : XEXP (op, 0), XEXP (op, 1));
953 :
954 : /* (not (neg (eq X Y))) is (neg (ne X Y)), etc. if the result of
955 : the comparison is one. */
956 2322126 : if (GET_CODE (op) == NEG
957 71207 : && COMPARISON_P (XEXP (op, 0))
958 6 : && ((SCALAR_INT_MODE_P (mode) && STORE_FLAG_VALUE == 1)
959 : #ifdef VECTOR_STORE_FLAG_VALUE
960 0 : || (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
961 0 : && VECTOR_STORE_FLAG_VALUE (mode) == const1_rtx)
962 : #endif
963 : )
964 2322132 : && ((reversed = reversed_comparison_code (XEXP (op, 0), NULL))
965 : != UNKNOWN))
966 : {
967 12 : temp = simplify_gen_relational (reversed, mode, VOIDmode,
968 : XEXP (XEXP (op, 0), 0),
969 6 : XEXP (XEXP (op, 0), 1));
970 6 : return simplify_gen_unary (NEG, mode, temp, mode);
971 : }
972 :
973 : /* (not (plus X -1)) can become (neg X). */
974 2322120 : if (GET_CODE (op) == PLUS
975 249074 : && XEXP (op, 1) == constm1_rtx)
976 4623 : return simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
977 :
978 : /* Similarly, (not (neg X)) is (plus X -1). Only do this for
979 : modes that have CONSTM1_RTX, i.e. MODE_INT, MODE_PARTIAL_INT
980 : and MODE_VECTOR_INT. */
981 2317497 : if (GET_CODE (op) == NEG && CONSTM1_RTX (mode))
982 71198 : return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
983 71198 : CONSTM1_RTX (mode));
984 :
985 : /* (not (xor X C)) for C constant is (xor X D) with D = ~C. */
986 2246299 : if (GET_CODE (op) == XOR
987 19320 : && CONST_INT_P (XEXP (op, 1))
988 2250870 : && (temp = simplify_unary_operation (NOT, mode,
989 : XEXP (op, 1), mode)) != 0)
990 4571 : return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
991 :
992 : /* (not (plus X C)) for signbit C is (xor X D) with D = ~C. */
993 2241728 : if (GET_CODE (op) == PLUS
994 244451 : && CONST_INT_P (XEXP (op, 1))
995 137307 : && mode_signbit_p (mode, XEXP (op, 1))
996 2245548 : && (temp = simplify_unary_operation (NOT, mode,
997 : XEXP (op, 1), mode)) != 0)
998 3820 : return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
999 :
1000 :
1001 : /* (not (ashift 1 X)) is (rotate ~1 X). We used to do this for
1002 : operands other than 1, but that is not valid. We could do a
1003 : similar simplification for (not (lshiftrt C X)) where C is
1004 : just the sign bit, but this doesn't seem common enough to
1005 : bother with. */
1006 2237908 : if (GET_CODE (op) == ASHIFT
1007 31395 : && XEXP (op, 0) == const1_rtx)
1008 : {
1009 1139 : temp = simplify_gen_unary (NOT, mode, const1_rtx, mode);
1010 1139 : return simplify_gen_binary (ROTATE, mode, temp, XEXP (op, 1));
1011 : }
1012 :
1013 : /* (not (ashiftrt foo C)) where C is the number of bits in FOO
1014 : minus 1 is (ge foo (const_int 0)) if STORE_FLAG_VALUE is -1,
1015 : so we can perform the above simplification. */
1016 2236769 : if (STORE_FLAG_VALUE == -1
1017 : && is_a <scalar_int_mode> (mode, &int_mode)
1018 : && GET_CODE (op) == ASHIFTRT
1019 : && CONST_INT_P (XEXP (op, 1))
1020 : && INTVAL (XEXP (op, 1)) == GET_MODE_PRECISION (int_mode) - 1)
1021 : return simplify_gen_relational (GE, int_mode, VOIDmode,
1022 : XEXP (op, 0), const0_rtx);
1023 :
1024 :
1025 2236769 : if (partial_subreg_p (op)
1026 603865 : && subreg_lowpart_p (op)
1027 603553 : && GET_CODE (SUBREG_REG (op)) == ASHIFT
1028 621547 : && XEXP (SUBREG_REG (op), 0) == const1_rtx)
1029 : {
1030 163 : machine_mode inner_mode = GET_MODE (SUBREG_REG (op));
1031 163 : rtx x;
1032 :
1033 163 : x = gen_rtx_ROTATE (inner_mode,
1034 : simplify_gen_unary (NOT, inner_mode, const1_rtx,
1035 : inner_mode),
1036 : XEXP (SUBREG_REG (op), 1));
1037 163 : temp = rtl_hooks.gen_lowpart_no_emit (mode, x);
1038 163 : if (temp)
1039 : return temp;
1040 : }
1041 :
1042 : /* Apply De Morgan's laws to reduce number of patterns for machines
1043 : with negating logical insns (and-not, nand, etc.). If result has
1044 : only one NOT, put it first, since that is how the patterns are
1045 : coded. */
1046 2236606 : if (GET_CODE (op) == IOR || GET_CODE (op) == AND)
1047 : {
1048 14084 : rtx in1 = XEXP (op, 0), in2 = XEXP (op, 1);
1049 14084 : machine_mode op_mode;
1050 :
1051 14084 : op_mode = GET_MODE (in1);
1052 14084 : in1 = simplify_gen_unary (NOT, op_mode, in1, op_mode);
1053 :
1054 14084 : op_mode = GET_MODE (in2);
1055 14084 : if (op_mode == VOIDmode)
1056 5426 : op_mode = mode;
1057 14084 : in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode);
1058 :
1059 14084 : if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT)
1060 : std::swap (in1, in2);
1061 :
1062 28168 : return gen_rtx_fmt_ee (GET_CODE (op) == IOR ? AND : IOR,
1063 : mode, in1, in2);
1064 : }
1065 :
1066 : /* (not (bswap x)) -> (bswap (not x)). */
1067 2222522 : if (GET_CODE (op) == BSWAP || GET_CODE (op) == BITREVERSE)
1068 : {
1069 0 : rtx x = simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1070 0 : return simplify_gen_unary (GET_CODE (op), mode, x, mode);
1071 : }
1072 : break;
1073 :
1074 1814223 : case NEG:
1075 : /* (neg (neg X)) == X. */
1076 1814223 : if (GET_CODE (op) == NEG)
1077 6687 : return XEXP (op, 0);
1078 :
1079 : /* (neg (x ? (neg y) : y)) == !x ? (neg y) : y.
1080 : If comparison is not reversible use
1081 : x ? y : (neg y). */
1082 1807536 : if (GET_CODE (op) == IF_THEN_ELSE)
1083 : {
1084 3332 : rtx cond = XEXP (op, 0);
1085 3332 : rtx true_rtx = XEXP (op, 1);
1086 3332 : rtx false_rtx = XEXP (op, 2);
1087 :
1088 3332 : if ((GET_CODE (true_rtx) == NEG
1089 0 : && rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
1090 3332 : || (GET_CODE (false_rtx) == NEG
1091 0 : && rtx_equal_p (XEXP (false_rtx, 0), true_rtx)))
1092 : {
1093 0 : if (reversed_comparison_code (cond, NULL) != UNKNOWN)
1094 0 : temp = reversed_comparison (cond, mode);
1095 : else
1096 : {
1097 : temp = cond;
1098 : std::swap (true_rtx, false_rtx);
1099 : }
1100 0 : return simplify_gen_ternary (IF_THEN_ELSE, mode,
1101 0 : mode, temp, true_rtx, false_rtx);
1102 : }
1103 : }
1104 :
1105 : /* (neg (plus X 1)) can become (not X). */
1106 1807536 : if (GET_CODE (op) == PLUS
1107 139913 : && XEXP (op, 1) == const1_rtx)
1108 54443 : return simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1109 :
1110 : /* Similarly, (neg (not X)) is (plus X 1). */
1111 1753093 : if (GET_CODE (op) == NOT)
1112 341 : return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
1113 341 : CONST1_RTX (mode));
1114 :
1115 : /* (neg (minus X Y)) can become (minus Y X). This transformation
1116 : isn't safe for modes with signed zeros, since if X and Y are
1117 : both +0, (minus Y X) is the same as (minus X Y). If the
1118 : rounding mode is towards +infinity (or -infinity) then the two
1119 : expressions will be rounded differently. */
1120 1752752 : if (GET_CODE (op) == MINUS
1121 24972 : && !HONOR_SIGNED_ZEROS (mode)
1122 1776312 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1123 23560 : return simplify_gen_binary (MINUS, mode, XEXP (op, 1), XEXP (op, 0));
1124 :
1125 1729192 : if (GET_CODE (op) == PLUS
1126 85470 : && !HONOR_SIGNED_ZEROS (mode)
1127 1814237 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1128 : {
1129 : /* (neg (plus A C)) is simplified to (minus -C A). */
1130 85045 : if (CONST_SCALAR_INT_P (XEXP (op, 1))
1131 5570 : || CONST_DOUBLE_AS_FLOAT_P (XEXP (op, 1)))
1132 : {
1133 79475 : temp = simplify_unary_operation (NEG, mode, XEXP (op, 1), mode);
1134 79475 : if (temp)
1135 79475 : return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 0));
1136 : }
1137 :
1138 : /* (neg (plus A B)) is canonicalized to (minus (neg A) B). */
1139 5570 : temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
1140 5570 : return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 1));
1141 : }
1142 :
1143 : /* (neg (mult A B)) becomes (mult A (neg B)).
1144 : This works even for floating-point values. */
1145 1644147 : if (GET_CODE (op) == MULT
1146 1644147 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1147 : {
1148 27585 : temp = simplify_gen_unary (NEG, mode, XEXP (op, 1), mode);
1149 27585 : return simplify_gen_binary (MULT, mode, XEXP (op, 0), temp);
1150 : }
1151 :
1152 : /* NEG commutes with ASHIFT since it is multiplication. Only do
1153 : this if we can then eliminate the NEG (e.g., if the operand
1154 : is a constant). */
1155 1616562 : if (GET_CODE (op) == ASHIFT)
1156 : {
1157 53599 : temp = simplify_unary_operation (NEG, mode, XEXP (op, 0), mode);
1158 53599 : if (temp)
1159 12348 : return simplify_gen_binary (ASHIFT, mode, temp, XEXP (op, 1));
1160 : }
1161 :
1162 : /* (neg (ashiftrt X C)) can be replaced by (lshiftrt X C) when
1163 : C is equal to the width of MODE minus 1. */
1164 1604214 : if (GET_CODE (op) == ASHIFTRT
1165 29414 : && CONST_INT_P (XEXP (op, 1))
1166 1662934 : && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1167 776 : return simplify_gen_binary (LSHIFTRT, mode,
1168 776 : XEXP (op, 0), XEXP (op, 1));
1169 :
1170 : /* (neg (lshiftrt X C)) can be replaced by (ashiftrt X C) when
1171 : C is equal to the width of MODE minus 1. */
1172 1603438 : if (GET_CODE (op) == LSHIFTRT
1173 9155 : && CONST_INT_P (XEXP (op, 1))
1174 1621616 : && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1175 3645 : return simplify_gen_binary (ASHIFTRT, mode,
1176 3645 : XEXP (op, 0), XEXP (op, 1));
1177 :
1178 : /* (neg (xor A 1)) is (plus A -1) if A is known to be either 0 or 1. */
1179 1599793 : if (GET_CODE (op) == XOR
1180 10771 : && XEXP (op, 1) == const1_rtx
1181 1599868 : && nonzero_bits (XEXP (op, 0), mode) == 1)
1182 32 : return plus_constant (mode, XEXP (op, 0), -1);
1183 :
1184 : /* (neg (lt x 0)) is (ashiftrt X C) if STORE_FLAG_VALUE is 1. */
1185 : /* (neg (lt x 0)) is (lshiftrt X C) if STORE_FLAG_VALUE is -1. */
1186 1599761 : if (GET_CODE (op) == LT
1187 3135 : && XEXP (op, 1) == const0_rtx
1188 1602068 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op, 0)), &inner))
1189 : {
1190 489 : int_mode = as_a <scalar_int_mode> (mode);
1191 489 : int isize = GET_MODE_PRECISION (inner);
1192 489 : if (STORE_FLAG_VALUE == 1)
1193 : {
1194 489 : temp = simplify_gen_binary (ASHIFTRT, inner, XEXP (op, 0),
1195 : gen_int_shift_amount (inner,
1196 489 : isize - 1));
1197 489 : if (int_mode == inner)
1198 : return temp;
1199 260 : if (GET_MODE_PRECISION (int_mode) > isize)
1200 187 : return simplify_gen_unary (SIGN_EXTEND, int_mode, temp, inner);
1201 73 : return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1202 : }
1203 : else if (STORE_FLAG_VALUE == -1)
1204 : {
1205 : temp = simplify_gen_binary (LSHIFTRT, inner, XEXP (op, 0),
1206 : gen_int_shift_amount (inner,
1207 : isize - 1));
1208 : if (int_mode == inner)
1209 : return temp;
1210 : if (GET_MODE_PRECISION (int_mode) > isize)
1211 : return simplify_gen_unary (ZERO_EXTEND, int_mode, temp, inner);
1212 : return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1213 : }
1214 : }
1215 :
1216 1599272 : if (vec_series_p (op, &base, &step))
1217 : {
1218 : /* Only create a new series if we can simplify both parts. In other
1219 : cases this isn't really a simplification, and it's not necessarily
1220 : a win to replace a vector operation with a scalar operation. */
1221 276 : scalar_mode inner_mode = GET_MODE_INNER (mode);
1222 276 : base = simplify_unary_operation (NEG, inner_mode, base, inner_mode);
1223 276 : if (base)
1224 : {
1225 276 : step = simplify_unary_operation (NEG, inner_mode,
1226 : step, inner_mode);
1227 276 : if (step)
1228 276 : return gen_vec_series (mode, base, step);
1229 : }
1230 : }
1231 : break;
1232 :
1233 2246768 : case TRUNCATE:
1234 : /* Don't optimize (lshiftrt (mult ...)) as it would interfere
1235 : with the umulXi3_highpart patterns. */
1236 2246768 : if (GET_CODE (op) == LSHIFTRT
1237 20190 : && GET_CODE (XEXP (op, 0)) == MULT)
1238 : break;
1239 :
1240 2239617 : if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
1241 : {
1242 12 : if (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
1243 : {
1244 12 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1245 12 : if (temp)
1246 : return temp;
1247 : }
1248 : /* We can't handle truncation to a partial integer mode here
1249 : because we don't know the real bitsize of the partial
1250 : integer mode. */
1251 : break;
1252 : }
1253 :
1254 2239605 : if (GET_MODE (op) != VOIDmode)
1255 : {
1256 2239605 : temp = simplify_truncation (mode, op, GET_MODE (op));
1257 2239605 : if (temp)
1258 : return temp;
1259 : }
1260 :
1261 : /* If we know that the value is already truncated, we can
1262 : replace the TRUNCATE with a SUBREG. */
1263 1940759 : if (known_eq (GET_MODE_NUNITS (mode), 1)
1264 1940759 : && (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op))
1265 0 : || truncated_to_mode (mode, op)))
1266 : {
1267 1928350 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1268 1928350 : if (temp)
1269 : return temp;
1270 : }
1271 :
1272 : /* A truncate of a comparison can be replaced with a subreg if
1273 : STORE_FLAG_VALUE permits. This is like the previous test,
1274 : but it works even if the comparison is done in a mode larger
1275 : than HOST_BITS_PER_WIDE_INT. */
1276 12570 : if (HWI_COMPUTABLE_MODE_P (mode)
1277 161 : && COMPARISON_P (op)
1278 0 : && (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0
1279 12570 : && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
1280 : {
1281 0 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1282 0 : if (temp)
1283 : return temp;
1284 : }
1285 :
1286 : /* A truncate of a memory is just loading the low part of the memory
1287 : if we are not changing the meaning of the address. */
1288 12570 : if (GET_CODE (op) == MEM
1289 278 : && !VECTOR_MODE_P (mode)
1290 159 : && !MEM_VOLATILE_P (op)
1291 12723 : && !mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op)))
1292 : {
1293 153 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1294 153 : if (temp)
1295 : return temp;
1296 : }
1297 :
1298 : /* Check for useless truncation. */
1299 12570 : if (GET_MODE (op) == mode)
1300 : return op;
1301 : break;
1302 :
1303 174717 : case FLOAT_TRUNCATE:
1304 : /* Check for useless truncation. */
1305 174717 : if (GET_MODE (op) == mode)
1306 : return op;
1307 :
1308 174717 : if (DECIMAL_FLOAT_MODE_P (mode))
1309 : break;
1310 :
1311 : /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF. */
1312 174563 : if (GET_CODE (op) == FLOAT_EXTEND
1313 5 : && GET_MODE (XEXP (op, 0)) == mode)
1314 : return XEXP (op, 0);
1315 :
1316 : /* (float_truncate:SF (float_truncate:DF foo:XF))
1317 : = (float_truncate:SF foo:XF).
1318 : This may eliminate double rounding, so it is unsafe.
1319 :
1320 : (float_truncate:SF (float_extend:XF foo:DF))
1321 : = (float_truncate:SF foo:DF).
1322 :
1323 : (float_truncate:DF (float_extend:XF foo:SF))
1324 : = (float_extend:DF foo:SF). */
1325 174561 : if ((GET_CODE (op) == FLOAT_TRUNCATE
1326 145 : && flag_unsafe_math_optimizations)
1327 174557 : || GET_CODE (op) == FLOAT_EXTEND)
1328 14 : return simplify_gen_unary (GET_MODE_UNIT_SIZE (GET_MODE (XEXP (op, 0)))
1329 7 : > GET_MODE_UNIT_SIZE (mode)
1330 : ? FLOAT_TRUNCATE : FLOAT_EXTEND,
1331 : mode,
1332 14 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1333 :
1334 : /* (float_truncate (float x)) is (float x) */
1335 174554 : if ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1336 174554 : && (flag_unsafe_math_optimizations
1337 1410 : || exact_int_to_float_conversion_p (op)))
1338 1409 : return simplify_gen_unary (GET_CODE (op), mode,
1339 : XEXP (op, 0),
1340 1409 : GET_MODE (XEXP (op, 0)));
1341 :
1342 : /* (float_truncate:SF (OP:DF (float_extend:DF foo:sf))) is
1343 : (OP:SF foo:SF) if OP is NEG or ABS. */
1344 173145 : if ((GET_CODE (op) == ABS
1345 173145 : || GET_CODE (op) == NEG)
1346 210 : && GET_CODE (XEXP (op, 0)) == FLOAT_EXTEND
1347 28 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
1348 28 : return simplify_gen_unary (GET_CODE (op), mode,
1349 28 : XEXP (XEXP (op, 0), 0), mode);
1350 :
1351 : /* (float_truncate:SF (subreg:DF (float_truncate:SF X) 0))
1352 : is (float_truncate:SF x). */
1353 173117 : if (GET_CODE (op) == SUBREG
1354 307 : && subreg_lowpart_p (op)
1355 173421 : && GET_CODE (SUBREG_REG (op)) == FLOAT_TRUNCATE)
1356 : return SUBREG_REG (op);
1357 : break;
1358 :
1359 602081 : case FLOAT_EXTEND:
1360 : /* Check for useless extension. */
1361 602081 : if (GET_MODE (op) == mode)
1362 : return op;
1363 :
1364 602081 : if (DECIMAL_FLOAT_MODE_P (mode))
1365 : break;
1366 :
1367 : /* (float_extend (float_extend x)) is (float_extend x)
1368 :
1369 : (float_extend (float x)) is (float x) assuming that double
1370 : rounding can't happen.
1371 : */
1372 601978 : if (GET_CODE (op) == FLOAT_EXTEND
1373 601978 : || ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1374 1423 : && exact_int_to_float_conversion_p (op)))
1375 557 : return simplify_gen_unary (GET_CODE (op), mode,
1376 : XEXP (op, 0),
1377 557 : GET_MODE (XEXP (op, 0)));
1378 :
1379 : break;
1380 :
1381 330046 : case ABS:
1382 : /* (abs (neg <foo>)) -> (abs <foo>) */
1383 330046 : if (GET_CODE (op) == NEG)
1384 18 : return simplify_gen_unary (ABS, mode, XEXP (op, 0),
1385 18 : GET_MODE (XEXP (op, 0)));
1386 :
1387 : /* If the mode of the operand is VOIDmode (i.e. if it is ASM_OPERANDS),
1388 : do nothing. */
1389 330028 : if (GET_MODE (op) == VOIDmode)
1390 : break;
1391 :
1392 : /* If operand is something known to be positive, ignore the ABS. */
1393 330028 : if (val_signbit_known_clear_p (GET_MODE (op),
1394 : nonzero_bits (op, GET_MODE (op))))
1395 : return op;
1396 :
1397 : /* Using nonzero_bits doesn't (currently) work for modes wider than
1398 : HOST_WIDE_INT, so the following transformations help simplify
1399 : ABS for TImode and wider. */
1400 329822 : switch (GET_CODE (op))
1401 : {
1402 : case ABS:
1403 : case CLRSB:
1404 : case FFS:
1405 : case PARITY:
1406 : case POPCOUNT:
1407 : case SS_ABS:
1408 : return op;
1409 :
1410 0 : case LSHIFTRT:
1411 0 : if (CONST_INT_P (XEXP (op, 1))
1412 0 : && INTVAL (XEXP (op, 1)) > 0
1413 329822 : && is_a <scalar_int_mode> (mode, &int_mode)
1414 0 : && INTVAL (XEXP (op, 1)) < GET_MODE_PRECISION (int_mode))
1415 : return op;
1416 : break;
1417 :
1418 : default:
1419 : break;
1420 : }
1421 :
1422 : /* If operand is known to be only -1 or 0, convert ABS to NEG. */
1423 329822 : if (is_a <scalar_int_mode> (mode, &int_mode)
1424 57443 : && (num_sign_bit_copies (op, int_mode)
1425 57443 : == GET_MODE_PRECISION (int_mode)))
1426 74 : return gen_rtx_NEG (int_mode, op);
1427 :
1428 : break;
1429 :
1430 0 : case FFS:
1431 : /* (ffs (*_extend <X>)) = (*_extend (ffs <X>)). */
1432 0 : if (GET_CODE (op) == SIGN_EXTEND
1433 0 : || GET_CODE (op) == ZERO_EXTEND)
1434 : {
1435 0 : temp = simplify_gen_unary (FFS, GET_MODE (XEXP (op, 0)),
1436 0 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1437 0 : return simplify_gen_unary (GET_CODE (op), mode, temp,
1438 0 : GET_MODE (temp));
1439 : }
1440 : break;
1441 :
1442 3441 : case POPCOUNT:
1443 3441 : switch (GET_CODE (op))
1444 : {
1445 0 : case BSWAP:
1446 0 : case BITREVERSE:
1447 : /* (popcount (bswap <X>)) = (popcount <X>). */
1448 0 : return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1449 0 : GET_MODE (XEXP (op, 0)));
1450 :
1451 44 : case ZERO_EXTEND:
1452 : /* (popcount (zero_extend <X>)) = (zero_extend (popcount <X>)). */
1453 88 : temp = simplify_gen_unary (POPCOUNT, GET_MODE (XEXP (op, 0)),
1454 44 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1455 44 : return simplify_gen_unary (ZERO_EXTEND, mode, temp,
1456 44 : GET_MODE (temp));
1457 :
1458 0 : case ROTATE:
1459 0 : case ROTATERT:
1460 : /* Rotations don't affect popcount. */
1461 0 : if (!side_effects_p (XEXP (op, 1)))
1462 0 : return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1463 0 : GET_MODE (XEXP (op, 0)));
1464 : break;
1465 :
1466 : default:
1467 : break;
1468 : }
1469 : break;
1470 :
1471 0 : case PARITY:
1472 0 : switch (GET_CODE (op))
1473 : {
1474 0 : case NOT:
1475 0 : case BSWAP:
1476 0 : case BITREVERSE:
1477 0 : return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1478 0 : GET_MODE (XEXP (op, 0)));
1479 :
1480 0 : case ZERO_EXTEND:
1481 0 : case SIGN_EXTEND:
1482 0 : temp = simplify_gen_unary (PARITY, GET_MODE (XEXP (op, 0)),
1483 0 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1484 0 : return simplify_gen_unary (GET_CODE (op), mode, temp,
1485 0 : GET_MODE (temp));
1486 :
1487 0 : case ROTATE:
1488 0 : case ROTATERT:
1489 : /* Rotations don't affect parity. */
1490 0 : if (!side_effects_p (XEXP (op, 1)))
1491 0 : return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1492 0 : GET_MODE (XEXP (op, 0)));
1493 : break;
1494 :
1495 : case PARITY:
1496 : /* (parity (parity x)) -> parity (x). */
1497 : return op;
1498 :
1499 : default:
1500 : break;
1501 : }
1502 : break;
1503 :
1504 31065 : case BSWAP:
1505 : /* (bswap (bswap x)) -> x. */
1506 31065 : if (GET_CODE (op) == BSWAP)
1507 184 : return XEXP (op, 0);
1508 : break;
1509 :
1510 0 : case BITREVERSE:
1511 : /* (bitreverse (bitreverse x)) -> x. */
1512 0 : if (GET_CODE (op) == BITREVERSE)
1513 0 : return XEXP (op, 0);
1514 : break;
1515 :
1516 903794 : case FLOAT:
1517 : /* (float (sign_extend <X>)) = (float <X>). */
1518 903794 : if (GET_CODE (op) == SIGN_EXTEND)
1519 9658 : return simplify_gen_unary (FLOAT, mode, XEXP (op, 0),
1520 9658 : GET_MODE (XEXP (op, 0)));
1521 : break;
1522 :
1523 3107610 : case SIGN_EXTEND:
1524 : /* Check for useless extension. */
1525 3107610 : if (GET_MODE (op) == mode)
1526 : return op;
1527 :
1528 : /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
1529 : becomes just the MINUS if its mode is MODE. This allows
1530 : folding switch statements on machines using casesi (such as
1531 : the VAX). */
1532 3107570 : if (GET_CODE (op) == TRUNCATE
1533 62 : && GET_MODE (XEXP (op, 0)) == mode
1534 62 : && GET_CODE (XEXP (op, 0)) == MINUS
1535 0 : && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
1536 0 : && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
1537 : return XEXP (op, 0);
1538 :
1539 : /* Extending a widening multiplication should be canonicalized to
1540 : a wider widening multiplication. */
1541 3107570 : if (GET_CODE (op) == MULT)
1542 : {
1543 67503 : rtx lhs = XEXP (op, 0);
1544 67503 : rtx rhs = XEXP (op, 1);
1545 67503 : enum rtx_code lcode = GET_CODE (lhs);
1546 67503 : enum rtx_code rcode = GET_CODE (rhs);
1547 :
1548 : /* Widening multiplies usually extend both operands, but sometimes
1549 : they use a shift to extract a portion of a register. */
1550 67503 : if ((lcode == SIGN_EXTEND
1551 67374 : || (lcode == ASHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1552 888 : && (rcode == SIGN_EXTEND
1553 868 : || (rcode == ASHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1554 : {
1555 105 : machine_mode lmode = GET_MODE (lhs);
1556 105 : machine_mode rmode = GET_MODE (rhs);
1557 105 : int bits;
1558 :
1559 105 : if (lcode == ASHIFTRT)
1560 : /* Number of bits not shifted off the end. */
1561 89 : bits = (GET_MODE_UNIT_PRECISION (lmode)
1562 89 : - INTVAL (XEXP (lhs, 1)));
1563 : else /* lcode == SIGN_EXTEND */
1564 : /* Size of inner mode. */
1565 32 : bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1566 :
1567 105 : if (rcode == ASHIFTRT)
1568 85 : bits += (GET_MODE_UNIT_PRECISION (rmode)
1569 85 : - INTVAL (XEXP (rhs, 1)));
1570 : else /* rcode == SIGN_EXTEND */
1571 40 : bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1572 :
1573 : /* We can only widen multiplies if the result is mathematiclly
1574 : equivalent. I.e. if overflow was impossible. */
1575 210 : if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1576 48 : return simplify_gen_binary
1577 48 : (MULT, mode,
1578 : simplify_gen_unary (SIGN_EXTEND, mode, lhs, lmode),
1579 48 : simplify_gen_unary (SIGN_EXTEND, mode, rhs, rmode));
1580 : }
1581 : }
1582 :
1583 : /* Check for a sign extension of a subreg of a promoted
1584 : variable, where the promotion is sign-extended, and the
1585 : target mode is the same as the variable's promotion. */
1586 3107522 : if (GET_CODE (op) == SUBREG
1587 215754 : && SUBREG_PROMOTED_VAR_P (op)
1588 3113670 : && SUBREG_PROMOTED_SIGNED_P (op))
1589 : {
1590 0 : rtx subreg = SUBREG_REG (op);
1591 0 : machine_mode subreg_mode = GET_MODE (subreg);
1592 0 : if (!paradoxical_subreg_p (mode, subreg_mode))
1593 : {
1594 0 : temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
1595 0 : if (temp)
1596 : {
1597 : /* Preserve SUBREG_PROMOTED_VAR_P. */
1598 0 : if (partial_subreg_p (temp))
1599 : {
1600 0 : SUBREG_PROMOTED_VAR_P (temp) = 1;
1601 0 : SUBREG_PROMOTED_SET (temp, SRP_SIGNED);
1602 : }
1603 : return temp;
1604 : }
1605 : }
1606 : else
1607 : /* Sign-extending a sign-extended subreg. */
1608 0 : return simplify_gen_unary (SIGN_EXTEND, mode,
1609 0 : subreg, subreg_mode);
1610 : }
1611 :
1612 : /* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
1613 : (sign_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1614 3107522 : if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND)
1615 : {
1616 20025 : gcc_assert (GET_MODE_UNIT_PRECISION (mode)
1617 : > GET_MODE_UNIT_PRECISION (GET_MODE (op)));
1618 6675 : return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0),
1619 6675 : GET_MODE (XEXP (op, 0)));
1620 : }
1621 :
1622 : /* (sign_extend:M (ashiftrt:N (ashift <X> (const_int I)) (const_int I)))
1623 : is (sign_extend:M (subreg:O <X>)) if there is mode with
1624 : GET_MODE_BITSIZE (N) - I bits.
1625 : (sign_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1626 : is similarly (zero_extend:M (subreg:O <X>)). */
1627 3100847 : if ((GET_CODE (op) == ASHIFTRT || GET_CODE (op) == LSHIFTRT)
1628 89739 : && GET_CODE (XEXP (op, 0)) == ASHIFT
1629 3103464 : && is_a <scalar_int_mode> (mode, &int_mode)
1630 5221 : && CONST_INT_P (XEXP (op, 1))
1631 5221 : && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1632 3105939 : && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1633 5092 : GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1634 : {
1635 5092 : scalar_int_mode tmode;
1636 5092 : gcc_assert (GET_MODE_PRECISION (int_mode)
1637 : > GET_MODE_PRECISION (op_mode));
1638 5092 : if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1639 7580 : - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1640 : {
1641 2604 : rtx inner =
1642 2604 : rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1643 2604 : if (inner)
1644 2604 : return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
1645 : ? SIGN_EXTEND : ZERO_EXTEND,
1646 2604 : int_mode, inner, tmode);
1647 : }
1648 : }
1649 :
1650 : /* (sign_extend:M (lshiftrt:N <X> (const_int I))) is better as
1651 : (zero_extend:M (lshiftrt:N <X> (const_int I))) if I is not 0. */
1652 3098243 : if (GET_CODE (op) == LSHIFTRT
1653 181 : && CONST_INT_P (XEXP (op, 1))
1654 181 : && XEXP (op, 1) != const0_rtx)
1655 181 : return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1656 :
1657 : /* (sign_extend:M (truncate:N (lshiftrt:O <X> (const_int I)))) where
1658 : I is GET_MODE_PRECISION(O) - GET_MODE_PRECISION(N), simplifies to
1659 : (ashiftrt:M <X> (const_int I)) if modes M and O are the same, and
1660 : (truncate:M (ashiftrt:O <X> (const_int I))) if M is narrower than
1661 : O, and (sign_extend:M (ashiftrt:O <X> (const_int I))) if M is
1662 : wider than O. */
1663 3098062 : if (GET_CODE (op) == TRUNCATE
1664 62 : && GET_CODE (XEXP (op, 0)) == LSHIFTRT
1665 0 : && CONST_INT_P (XEXP (XEXP (op, 0), 1)))
1666 : {
1667 0 : scalar_int_mode m_mode, n_mode, o_mode;
1668 0 : rtx old_shift = XEXP (op, 0);
1669 0 : if (is_a <scalar_int_mode> (mode, &m_mode)
1670 0 : && is_a <scalar_int_mode> (GET_MODE (op), &n_mode)
1671 0 : && is_a <scalar_int_mode> (GET_MODE (old_shift), &o_mode)
1672 0 : && GET_MODE_PRECISION (o_mode) - GET_MODE_PRECISION (n_mode)
1673 0 : == INTVAL (XEXP (old_shift, 1)))
1674 : {
1675 0 : rtx new_shift = simplify_gen_binary (ASHIFTRT,
1676 : GET_MODE (old_shift),
1677 : XEXP (old_shift, 0),
1678 : XEXP (old_shift, 1));
1679 0 : if (GET_MODE_PRECISION (m_mode) > GET_MODE_PRECISION (o_mode))
1680 0 : return simplify_gen_unary (SIGN_EXTEND, mode, new_shift,
1681 0 : GET_MODE (new_shift));
1682 0 : if (mode != GET_MODE (new_shift))
1683 0 : return simplify_gen_unary (TRUNCATE, mode, new_shift,
1684 0 : GET_MODE (new_shift));
1685 : return new_shift;
1686 : }
1687 : }
1688 :
1689 : /* We can canonicalize SIGN_EXTEND (op) as ZERO_EXTEND (op) when
1690 : we know the sign bit of OP must be clear. */
1691 3098062 : if (val_signbit_known_clear_p (GET_MODE (op),
1692 3098062 : nonzero_bits (op, GET_MODE (op))))
1693 39736 : return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1694 :
1695 : /* (sign_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1696 3058326 : if (GET_CODE (op) == SUBREG
1697 215469 : && subreg_lowpart_p (op)
1698 215357 : && GET_MODE (SUBREG_REG (op)) == mode
1699 3242504 : && is_a <scalar_int_mode> (mode, &int_mode)
1700 190956 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1701 190956 : && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
1702 189149 : && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
1703 3247475 : && (nonzero_bits (SUBREG_REG (op), mode)
1704 189149 : & ~(GET_MODE_MASK (op_mode) >> 1)) == 0)
1705 6778 : return SUBREG_REG (op);
1706 :
1707 : #if defined(POINTERS_EXTEND_UNSIGNED)
1708 : /* As we do not know which address space the pointer is referring to,
1709 : we can do this only if the target does not support different pointer
1710 : or address modes depending on the address space. */
1711 3051548 : if (target_default_pointer_address_modes_p ()
1712 : && ! POINTERS_EXTEND_UNSIGNED
1713 : && mode == Pmode && GET_MODE (op) == ptr_mode
1714 : && (CONSTANT_P (op)
1715 : || (GET_CODE (op) == SUBREG
1716 : && REG_P (SUBREG_REG (op))
1717 : && REG_POINTER (SUBREG_REG (op))
1718 : && GET_MODE (SUBREG_REG (op)) == Pmode))
1719 : && !targetm.have_ptr_extend ())
1720 : {
1721 : temp
1722 : = convert_memory_address_addr_space_1 (Pmode, op,
1723 : ADDR_SPACE_GENERIC, false,
1724 : true);
1725 : if (temp)
1726 : return temp;
1727 : }
1728 : #endif
1729 : break;
1730 :
1731 11601053 : case ZERO_EXTEND:
1732 : /* Check for useless extension. */
1733 11601053 : if (GET_MODE (op) == mode)
1734 : return op;
1735 :
1736 : /* (zero_extend:SI (and:QI X (const))) -> (and:SI (lowpart:SI X) const)
1737 : where const does not sign bit set. */
1738 11601011 : if (GET_CODE (op) == AND
1739 118322 : && CONST_INT_P (XEXP (op, 1))
1740 91796 : && INTVAL (XEXP (op, 1)) > 0)
1741 : {
1742 84487 : rtx tem = rtl_hooks.gen_lowpart_no_emit (mode, XEXP (op, 0));
1743 84487 : if (tem)
1744 68264 : return simplify_gen_binary (AND, mode, tem, XEXP (op, 1));
1745 : }
1746 :
1747 : /* Check for a zero extension of a subreg of a promoted
1748 : variable, where the promotion is zero-extended, and the
1749 : target mode is the same as the variable's promotion. */
1750 11532747 : if (GET_CODE (op) == SUBREG
1751 1674996 : && SUBREG_PROMOTED_VAR_P (op)
1752 11533253 : && SUBREG_PROMOTED_UNSIGNED_P (op))
1753 : {
1754 506 : rtx subreg = SUBREG_REG (op);
1755 506 : machine_mode subreg_mode = GET_MODE (subreg);
1756 506 : if (!paradoxical_subreg_p (mode, subreg_mode))
1757 : {
1758 320 : temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
1759 320 : if (temp)
1760 : {
1761 : /* Preserve SUBREG_PROMOTED_VAR_P. */
1762 320 : if (partial_subreg_p (temp))
1763 : {
1764 129 : SUBREG_PROMOTED_VAR_P (temp) = 1;
1765 129 : SUBREG_PROMOTED_SET (temp, SRP_UNSIGNED);
1766 : }
1767 : return temp;
1768 : }
1769 : }
1770 : else
1771 : /* Zero-extending a zero-extended subreg. */
1772 186 : return simplify_gen_unary (ZERO_EXTEND, mode,
1773 186 : subreg, subreg_mode);
1774 : }
1775 :
1776 : /* Extending a widening multiplication should be canonicalized to
1777 : a wider widening multiplication. */
1778 11532241 : if (GET_CODE (op) == MULT)
1779 : {
1780 183940 : rtx lhs = XEXP (op, 0);
1781 183940 : rtx rhs = XEXP (op, 1);
1782 183940 : enum rtx_code lcode = GET_CODE (lhs);
1783 183940 : enum rtx_code rcode = GET_CODE (rhs);
1784 :
1785 : /* Widening multiplies usually extend both operands, but sometimes
1786 : they use a shift to extract a portion of a register. */
1787 183940 : if ((lcode == ZERO_EXTEND
1788 183316 : || (lcode == LSHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1789 822 : && (rcode == ZERO_EXTEND
1790 772 : || (rcode == LSHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1791 : {
1792 62 : machine_mode lmode = GET_MODE (lhs);
1793 62 : machine_mode rmode = GET_MODE (rhs);
1794 62 : int bits;
1795 :
1796 62 : if (lcode == LSHIFTRT)
1797 : /* Number of bits not shifted off the end. */
1798 12 : bits = (GET_MODE_UNIT_PRECISION (lmode)
1799 12 : - INTVAL (XEXP (lhs, 1)));
1800 : else /* lcode == ZERO_EXTEND */
1801 : /* Size of inner mode. */
1802 100 : bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1803 :
1804 62 : if (rcode == LSHIFTRT)
1805 12 : bits += (GET_MODE_UNIT_PRECISION (rmode)
1806 12 : - INTVAL (XEXP (rhs, 1)));
1807 : else /* rcode == ZERO_EXTEND */
1808 100 : bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1809 :
1810 : /* We can only widen multiplies if the result is mathematiclly
1811 : equivalent. I.e. if overflow was impossible. */
1812 124 : if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1813 50 : return simplify_gen_binary
1814 50 : (MULT, mode,
1815 : simplify_gen_unary (ZERO_EXTEND, mode, lhs, lmode),
1816 50 : simplify_gen_unary (ZERO_EXTEND, mode, rhs, rmode));
1817 : }
1818 : }
1819 :
1820 : /* (zero_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1821 11532191 : if (GET_CODE (op) == ZERO_EXTEND)
1822 21664 : return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0),
1823 21664 : GET_MODE (XEXP (op, 0)));
1824 :
1825 : /* (zero_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1826 : is (zero_extend:M (subreg:O <X>)) if there is mode with
1827 : GET_MODE_PRECISION (N) - I bits. */
1828 11510527 : if (GET_CODE (op) == LSHIFTRT
1829 71796 : && GET_CODE (XEXP (op, 0)) == ASHIFT
1830 11510550 : && is_a <scalar_int_mode> (mode, &int_mode)
1831 23 : && CONST_INT_P (XEXP (op, 1))
1832 18 : && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1833 11510527 : && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1834 0 : GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1835 : {
1836 0 : scalar_int_mode tmode;
1837 0 : if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1838 0 : - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1839 : {
1840 0 : rtx inner =
1841 0 : rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1842 0 : if (inner)
1843 0 : return simplify_gen_unary (ZERO_EXTEND, int_mode,
1844 0 : inner, tmode);
1845 : }
1846 : }
1847 :
1848 : /* (zero_extend:M (subreg:N <X:O>)) is <X:O> (for M == O) or
1849 : (zero_extend:M <X:O>), if X doesn't have any non-zero bits outside
1850 : of mode N. E.g.
1851 : (zero_extend:SI (subreg:QI (and:SI (reg:SI) (const_int 63)) 0)) is
1852 : (and:SI (reg:SI) (const_int 63)). */
1853 11510527 : if (partial_subreg_p (op)
1854 13109750 : && is_a <scalar_int_mode> (mode, &int_mode)
1855 1621583 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &op0_mode)
1856 1621177 : && GET_MODE_PRECISION (op0_mode) <= HOST_BITS_PER_WIDE_INT
1857 1296776 : && GET_MODE_PRECISION (int_mode) >= GET_MODE_PRECISION (op0_mode)
1858 1274926 : && subreg_lowpart_p (op)
1859 2502471 : && (nonzero_bits (SUBREG_REG (op), op0_mode)
1860 827981 : & ~GET_MODE_MASK (GET_MODE (op))) == 0)
1861 : {
1862 22360 : if (GET_MODE_PRECISION (int_mode) == GET_MODE_PRECISION (op0_mode))
1863 14863 : return SUBREG_REG (op);
1864 7497 : return simplify_gen_unary (ZERO_EXTEND, int_mode, SUBREG_REG (op),
1865 7497 : op0_mode);
1866 : }
1867 :
1868 : /* (zero_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1869 11488167 : if (GET_CODE (op) == SUBREG
1870 1652130 : && subreg_lowpart_p (op)
1871 945309 : && GET_MODE (SUBREG_REG (op)) == mode
1872 12293136 : && is_a <scalar_int_mode> (mode, &int_mode)
1873 804969 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1874 804969 : && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
1875 741493 : && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
1876 12229660 : && (nonzero_bits (SUBREG_REG (op), mode)
1877 741493 : & ~GET_MODE_MASK (op_mode)) == 0)
1878 0 : return SUBREG_REG (op);
1879 :
1880 : /* Trying to optimize:
1881 : (zero_extend:M (subreg:N (not:M (X:M)))) ->
1882 : (xor:M (zero_extend:M (subreg:N (X:M)), mask))
1883 : where the mask is GET_MODE_MASK (N).
1884 : For the cases when X:M doesn't have any non-zero bits
1885 : outside of mode N, (zero_extend:M (subreg:N (X:M))
1886 : will be simplified to just (X:M)
1887 : and whole optimization will be -> (xor:M (X:M, mask)). */
1888 11488167 : if (partial_subreg_p (op)
1889 1599223 : && GET_CODE (XEXP (op, 0)) == NOT
1890 1436 : && GET_MODE (XEXP (op, 0)) == mode
1891 1418 : && subreg_lowpart_p (op)
1892 11488533 : && HWI_COMPUTABLE_MODE_P (mode)
1893 370 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1894 1652500 : && (nonzero_bits (XEXP (XEXP (op, 0), 0), mode)
1895 370 : & ~GET_MODE_MASK (op_mode)) == 0)
1896 : {
1897 4 : unsigned HOST_WIDE_INT mask = GET_MODE_MASK (op_mode);
1898 8 : return simplify_gen_binary (XOR, mode,
1899 4 : XEXP (XEXP (op, 0), 0),
1900 4 : gen_int_mode (mask, mode));
1901 : }
1902 :
1903 : #if defined(POINTERS_EXTEND_UNSIGNED)
1904 : /* As we do not know which address space the pointer is referring to,
1905 : we can do this only if the target does not support different pointer
1906 : or address modes depending on the address space. */
1907 11488163 : if (target_default_pointer_address_modes_p ()
1908 : && POINTERS_EXTEND_UNSIGNED > 0
1909 13104458 : && mode == Pmode && GET_MODE (op) == ptr_mode
1910 673 : && (CONSTANT_P (op)
1911 652 : || (GET_CODE (op) == SUBREG
1912 0 : && REG_P (SUBREG_REG (op))
1913 0 : && REG_POINTER (SUBREG_REG (op))
1914 0 : && GET_MODE (SUBREG_REG (op)) == Pmode))
1915 11488184 : && !targetm.have_ptr_extend ())
1916 : {
1917 21 : temp
1918 21 : = convert_memory_address_addr_space_1 (Pmode, op,
1919 : ADDR_SPACE_GENERIC, false,
1920 : true);
1921 21 : if (temp)
1922 : return temp;
1923 : }
1924 : #endif
1925 : break;
1926 :
1927 806352 : case VEC_DUPLICATE:
1928 806352 : if (GET_CODE (op) == VEC_DUPLICATE)
1929 2 : return simplify_gen_unary (VEC_DUPLICATE, mode, XEXP (op, 0),
1930 2 : GET_MODE (XEXP (op, 0)));
1931 : break;
1932 :
1933 : default:
1934 : break;
1935 : }
1936 :
1937 19740523 : if (VECTOR_MODE_P (mode)
1938 1856563 : && vec_duplicate_p (op, &elt)
1939 21603038 : && code != VEC_DUPLICATE)
1940 : {
1941 5952 : if (code == SIGN_EXTEND || code == ZERO_EXTEND)
1942 : /* Enforce a canonical order of VEC_DUPLICATE wrt other unary
1943 : operations by promoting VEC_DUPLICATE to the root of the expression
1944 : (as far as possible). */
1945 4896 : temp = simplify_gen_unary (code, GET_MODE_INNER (mode),
1946 9792 : elt, GET_MODE_INNER (GET_MODE (op)));
1947 : else
1948 : /* Try applying the operator to ELT and see if that simplifies.
1949 : We can duplicate the result if so.
1950 :
1951 : The reason we traditionally haven't used simplify_gen_unary
1952 : for these codes is that it didn't necessarily seem to be a
1953 : win to convert things like:
1954 :
1955 : (neg:V (vec_duplicate:V (reg:S R)))
1956 :
1957 : to:
1958 :
1959 : (vec_duplicate:V (neg:S (reg:S R)))
1960 :
1961 : The first might be done entirely in vector registers while the
1962 : second might need a move between register files.
1963 :
1964 : However, there also cases where promoting the vec_duplicate is
1965 : more efficient, and there is definite value in having a canonical
1966 : form when matching instruction patterns. We should consider
1967 : extending the simplify_gen_unary code above to more cases. */
1968 1056 : temp = simplify_unary_operation (code, GET_MODE_INNER (mode),
1969 2112 : elt, GET_MODE_INNER (GET_MODE (op)));
1970 5952 : if (temp)
1971 5476 : return gen_vec_duplicate (mode, temp);
1972 : }
1973 :
1974 : return 0;
1975 : }
1976 :
1977 : /* Try to compute the value of a unary operation CODE whose output mode is to
1978 : be MODE with input operand OP whose mode was originally OP_MODE.
1979 : Return zero if the value cannot be computed. */
1980 : rtx
1981 29748248 : simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
1982 : rtx op, machine_mode op_mode)
1983 : {
1984 29748248 : scalar_int_mode result_mode;
1985 :
1986 29748248 : if (code == VEC_DUPLICATE)
1987 : {
1988 1951803 : gcc_assert (VECTOR_MODE_P (mode));
1989 1951803 : if (GET_MODE (op) != VOIDmode)
1990 : {
1991 847011 : if (!VECTOR_MODE_P (GET_MODE (op)))
1992 1680642 : gcc_assert (GET_MODE_INNER (mode) == GET_MODE (op));
1993 : else
1994 20070 : gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER
1995 : (GET_MODE (op)));
1996 : }
1997 1951803 : if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op))
1998 1144695 : return gen_const_vec_duplicate (mode, op);
1999 807108 : if (GET_CODE (op) == CONST_VECTOR
2000 807108 : && (CONST_VECTOR_DUPLICATE_P (op)
2001 756 : || CONST_VECTOR_NUNITS (op).is_constant ()))
2002 : {
2003 756 : unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op)
2004 756 : ? CONST_VECTOR_NPATTERNS (op)
2005 1510 : : CONST_VECTOR_NUNITS (op).to_constant ());
2006 2268 : gcc_assert (multiple_p (GET_MODE_NUNITS (mode), npatterns));
2007 756 : rtx_vector_builder builder (mode, npatterns, 1);
2008 3888 : for (unsigned i = 0; i < npatterns; i++)
2009 2376 : builder.quick_push (CONST_VECTOR_ELT (op, i));
2010 756 : return builder.build ();
2011 756 : }
2012 : }
2013 :
2014 27095864 : if (VECTOR_MODE_P (mode)
2015 1904949 : && GET_CODE (op) == CONST_VECTOR
2016 28706570 : && known_eq (GET_MODE_NUNITS (mode), CONST_VECTOR_NUNITS (op)))
2017 : {
2018 34591 : gcc_assert (GET_MODE (op) == op_mode);
2019 :
2020 34591 : rtx_vector_builder builder;
2021 34591 : if (!builder.new_unary_operation (mode, op, false))
2022 : return 0;
2023 :
2024 34591 : unsigned int count = builder.encoded_nelts ();
2025 153777 : for (unsigned int i = 0; i < count; i++)
2026 : {
2027 239410 : rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
2028 : CONST_VECTOR_ELT (op, i),
2029 239410 : GET_MODE_INNER (op_mode));
2030 119705 : if (!x || !valid_for_const_vector_p (mode, x))
2031 519 : return 0;
2032 119186 : builder.quick_push (x);
2033 : }
2034 34072 : return builder.build ();
2035 34591 : }
2036 :
2037 : /* The order of these tests is critical so that, for example, we don't
2038 : check the wrong mode (input vs. output) for a conversion operation,
2039 : such as FIX. At some point, this should be simplified. */
2040 :
2041 28568206 : if (code == FLOAT && CONST_SCALAR_INT_P (op))
2042 : {
2043 7872 : REAL_VALUE_TYPE d;
2044 :
2045 7872 : if (op_mode == VOIDmode)
2046 : {
2047 : /* CONST_INT have VOIDmode as the mode. We assume that all
2048 : the bits of the constant are significant, though, this is
2049 : a dangerous assumption as many times CONST_INTs are
2050 : created and used with garbage in the bits outside of the
2051 : precision of the implied mode of the const_int. */
2052 64 : op_mode = MAX_MODE_INT;
2053 : }
2054 :
2055 7872 : real_from_integer (&d, mode, rtx_mode_t (op, op_mode), SIGNED);
2056 :
2057 : /* Avoid the folding if flag_signaling_nans is on and
2058 : operand is a signaling NaN. */
2059 7872 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2060 : return 0;
2061 :
2062 7872 : d = real_value_truncate (mode, d);
2063 :
2064 : /* Avoid the folding if flag_rounding_math is on and the
2065 : conversion is not exact. */
2066 7872 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2067 : {
2068 1011 : bool fail = false;
2069 1011 : wide_int w = real_to_integer (&d, &fail,
2070 : GET_MODE_PRECISION
2071 1011 : (as_a <scalar_int_mode> (op_mode)));
2072 2022 : if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
2073 905 : return 0;
2074 1011 : }
2075 :
2076 6967 : return const_double_from_real_value (d, mode);
2077 : }
2078 28560334 : else if (code == UNSIGNED_FLOAT && CONST_SCALAR_INT_P (op))
2079 : {
2080 2134 : REAL_VALUE_TYPE d;
2081 :
2082 2134 : if (op_mode == VOIDmode)
2083 : {
2084 : /* CONST_INT have VOIDmode as the mode. We assume that all
2085 : the bits of the constant are significant, though, this is
2086 : a dangerous assumption as many times CONST_INTs are
2087 : created and used with garbage in the bits outside of the
2088 : precision of the implied mode of the const_int. */
2089 8 : op_mode = MAX_MODE_INT;
2090 : }
2091 :
2092 2134 : real_from_integer (&d, mode, rtx_mode_t (op, op_mode), UNSIGNED);
2093 :
2094 : /* Avoid the folding if flag_signaling_nans is on and
2095 : operand is a signaling NaN. */
2096 2134 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2097 : return 0;
2098 :
2099 2134 : d = real_value_truncate (mode, d);
2100 :
2101 : /* Avoid the folding if flag_rounding_math is on and the
2102 : conversion is not exact. */
2103 2134 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2104 : {
2105 16 : bool fail = false;
2106 16 : wide_int w = real_to_integer (&d, &fail,
2107 : GET_MODE_PRECISION
2108 16 : (as_a <scalar_int_mode> (op_mode)));
2109 28 : if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
2110 16 : return 0;
2111 16 : }
2112 :
2113 2118 : return const_double_from_real_value (d, mode);
2114 : }
2115 :
2116 28558200 : if (CONST_SCALAR_INT_P (op) && is_a <scalar_int_mode> (mode, &result_mode))
2117 : {
2118 3819198 : unsigned int width = GET_MODE_PRECISION (result_mode);
2119 3819198 : if (width > MAX_BITSIZE_MODE_ANY_INT)
2120 : return 0;
2121 :
2122 3819198 : wide_int result;
2123 3819198 : scalar_int_mode imode = (op_mode == VOIDmode
2124 3819198 : ? result_mode
2125 3818982 : : as_a <scalar_int_mode> (op_mode));
2126 3819198 : rtx_mode_t op0 = rtx_mode_t (op, imode);
2127 3819198 : int int_value;
2128 :
2129 : #if TARGET_SUPPORTS_WIDE_INT == 0
2130 : /* This assert keeps the simplification from producing a result
2131 : that cannot be represented in a CONST_DOUBLE but a lot of
2132 : upstream callers expect that this function never fails to
2133 : simplify something and so you if you added this to the test
2134 : above the code would die later anyway. If this assert
2135 : happens, you just need to make the port support wide int. */
2136 : gcc_assert (width <= HOST_BITS_PER_DOUBLE_INT);
2137 : #endif
2138 :
2139 3819198 : switch (code)
2140 : {
2141 176554 : case NOT:
2142 176554 : result = wi::bit_not (op0);
2143 176554 : break;
2144 :
2145 1865337 : case NEG:
2146 1865337 : result = wi::neg (op0);
2147 1865337 : break;
2148 :
2149 7087 : case ABS:
2150 7087 : result = wi::abs (op0);
2151 7087 : break;
2152 :
2153 0 : case FFS:
2154 0 : result = wi::shwi (wi::ffs (op0), result_mode);
2155 0 : break;
2156 :
2157 168 : case CLZ:
2158 168 : if (wi::ne_p (op0, 0))
2159 38 : int_value = wi::clz (op0);
2160 260 : else if (! CLZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2161 : return NULL_RTX;
2162 38 : result = wi::shwi (int_value, result_mode);
2163 38 : break;
2164 :
2165 0 : case CLRSB:
2166 0 : result = wi::shwi (wi::clrsb (op0), result_mode);
2167 0 : break;
2168 :
2169 0 : case CTZ:
2170 0 : if (wi::ne_p (op0, 0))
2171 0 : int_value = wi::ctz (op0);
2172 0 : else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2173 : return NULL_RTX;
2174 0 : result = wi::shwi (int_value, result_mode);
2175 0 : break;
2176 :
2177 160 : case POPCOUNT:
2178 160 : result = wi::shwi (wi::popcount (op0), result_mode);
2179 160 : break;
2180 :
2181 0 : case PARITY:
2182 0 : result = wi::shwi (wi::parity (op0), result_mode);
2183 0 : break;
2184 :
2185 1761 : case BSWAP:
2186 1761 : result = wi::bswap (op0);
2187 1761 : break;
2188 :
2189 0 : case BITREVERSE:
2190 0 : result = wi::bitreverse (op0);
2191 0 : break;
2192 :
2193 1588879 : case TRUNCATE:
2194 1588879 : case ZERO_EXTEND:
2195 1588879 : result = wide_int::from (op0, width, UNSIGNED);
2196 1588879 : break;
2197 :
2198 14478 : case US_TRUNCATE:
2199 14478 : case SS_TRUNCATE:
2200 14478 : {
2201 14478 : signop sgn = code == US_TRUNCATE ? UNSIGNED : SIGNED;
2202 14478 : wide_int nmax
2203 14478 : = wide_int::from (wi::max_value (width, sgn),
2204 28956 : GET_MODE_PRECISION (imode), sgn);
2205 14478 : wide_int nmin
2206 14478 : = wide_int::from (wi::min_value (width, sgn),
2207 28956 : GET_MODE_PRECISION (imode), sgn);
2208 14478 : result = wi::min (wi::max (op0, nmin, sgn), nmax, sgn);
2209 14478 : result = wide_int::from (result, width, sgn);
2210 14478 : break;
2211 14478 : }
2212 164774 : case SIGN_EXTEND:
2213 164774 : result = wide_int::from (op0, width, SIGNED);
2214 164774 : break;
2215 :
2216 0 : case SS_NEG:
2217 0 : if (wi::only_sign_bit_p (op0))
2218 0 : result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
2219 : else
2220 0 : result = wi::neg (op0);
2221 : break;
2222 :
2223 0 : case SS_ABS:
2224 0 : if (wi::only_sign_bit_p (op0))
2225 0 : result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
2226 : else
2227 0 : result = wi::abs (op0);
2228 : break;
2229 :
2230 : case SQRT:
2231 : default:
2232 : return 0;
2233 : }
2234 :
2235 3819068 : return immed_wide_int_const (result, result_mode);
2236 3819198 : }
2237 :
2238 24739002 : else if (CONST_DOUBLE_AS_FLOAT_P (op)
2239 414971 : && SCALAR_FLOAT_MODE_P (mode)
2240 412923 : && SCALAR_FLOAT_MODE_P (GET_MODE (op)))
2241 : {
2242 412923 : REAL_VALUE_TYPE d = *CONST_DOUBLE_REAL_VALUE (op);
2243 412923 : switch (code)
2244 : {
2245 : case SQRT:
2246 : return 0;
2247 544 : case ABS:
2248 544 : d = real_value_abs (&d);
2249 544 : break;
2250 15749 : case NEG:
2251 15749 : d = real_value_negate (&d);
2252 15749 : break;
2253 2284 : case FLOAT_TRUNCATE:
2254 : /* Don't perform the operation if flag_signaling_nans is on
2255 : and the operand is a signaling NaN. */
2256 2284 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2257 : return NULL_RTX;
2258 : /* Or if flag_rounding_math is on and the truncation is not
2259 : exact. */
2260 2284 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2261 2284 : && !exact_real_truncate (mode, &d))
2262 231 : return NULL_RTX;
2263 2053 : d = real_value_truncate (mode, d);
2264 2053 : break;
2265 387806 : case FLOAT_EXTEND:
2266 : /* Don't perform the operation if flag_signaling_nans is on
2267 : and the operand is a signaling NaN. */
2268 387806 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2269 : return NULL_RTX;
2270 : /* All this does is change the mode, unless changing
2271 : mode class. */
2272 387804 : if (GET_MODE_CLASS (mode) != GET_MODE_CLASS (GET_MODE (op)))
2273 0 : real_convert (&d, mode, &d);
2274 : break;
2275 0 : case FIX:
2276 : /* Don't perform the operation if flag_signaling_nans is on
2277 : and the operand is a signaling NaN. */
2278 0 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2279 : return NULL_RTX;
2280 0 : real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
2281 0 : break;
2282 5931 : case NOT:
2283 5931 : {
2284 5931 : long tmp[4];
2285 5931 : int i;
2286 :
2287 5931 : real_to_target (tmp, &d, GET_MODE (op));
2288 29655 : for (i = 0; i < 4; i++)
2289 23724 : tmp[i] = ~tmp[i];
2290 5931 : real_from_target (&d, tmp, mode);
2291 5931 : break;
2292 : }
2293 0 : default:
2294 0 : gcc_unreachable ();
2295 : }
2296 412081 : return const_double_from_real_value (d, mode);
2297 : }
2298 2048 : else if (CONST_DOUBLE_AS_FLOAT_P (op)
2299 2048 : && SCALAR_FLOAT_MODE_P (GET_MODE (op))
2300 24328127 : && is_int_mode (mode, &result_mode))
2301 : {
2302 2048 : unsigned int width = GET_MODE_PRECISION (result_mode);
2303 2048 : if (width > MAX_BITSIZE_MODE_ANY_INT)
2304 : return 0;
2305 :
2306 : /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
2307 : operators are intentionally left unspecified (to ease implementation
2308 : by target backends), for consistency, this routine implements the
2309 : same semantics for constant folding as used by the middle-end. */
2310 :
2311 : /* This was formerly used only for non-IEEE float.
2312 : eggert@twinsun.com says it is safe for IEEE also. */
2313 2048 : REAL_VALUE_TYPE t;
2314 2048 : const REAL_VALUE_TYPE *x = CONST_DOUBLE_REAL_VALUE (op);
2315 2048 : wide_int wmax, wmin;
2316 : /* This is part of the abi to real_to_integer, but we check
2317 : things before making this call. */
2318 2048 : bool fail;
2319 :
2320 2048 : switch (code)
2321 : {
2322 2040 : case FIX:
2323 : /* According to IEEE standard, for conversions from floating point to
2324 : integer. When a NaN or infinite operand cannot be represented in
2325 : the destination format and this cannot otherwise be indicated, the
2326 : invalid operation exception shall be signaled. When a numeric
2327 : operand would convert to an integer outside the range of the
2328 : destination format, the invalid operation exception shall be
2329 : signaled if this situation cannot otherwise be indicated. */
2330 2040 : if (REAL_VALUE_ISNAN (*x))
2331 955 : return flag_trapping_math ? NULL_RTX : const0_rtx;
2332 :
2333 1085 : if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
2334 : return NULL_RTX;
2335 :
2336 : /* Test against the signed upper bound. */
2337 125 : wmax = wi::max_value (width, SIGNED);
2338 125 : real_from_integer (&t, VOIDmode, wmax, SIGNED);
2339 125 : if (real_less (&t, x))
2340 3 : return (flag_trapping_math
2341 3 : ? NULL_RTX : immed_wide_int_const (wmax, mode));
2342 :
2343 : /* Test against the signed lower bound. */
2344 122 : wmin = wi::min_value (width, SIGNED);
2345 122 : real_from_integer (&t, VOIDmode, wmin, SIGNED);
2346 122 : if (real_less (x, &t))
2347 8 : return immed_wide_int_const (wmin, mode);
2348 :
2349 114 : return immed_wide_int_const (real_to_integer (x, &fail, width),
2350 : mode);
2351 :
2352 8 : case UNSIGNED_FIX:
2353 8 : if (REAL_VALUE_ISNAN (*x) || REAL_VALUE_NEGATIVE (*x))
2354 6 : return flag_trapping_math ? NULL_RTX : const0_rtx;
2355 :
2356 2 : if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
2357 : return NULL_RTX;
2358 :
2359 : /* Test against the unsigned upper bound. */
2360 0 : wmax = wi::max_value (width, UNSIGNED);
2361 0 : real_from_integer (&t, VOIDmode, wmax, UNSIGNED);
2362 0 : if (real_less (&t, x))
2363 0 : return (flag_trapping_math
2364 0 : ? NULL_RTX : immed_wide_int_const (wmax, mode));
2365 :
2366 0 : return immed_wide_int_const (real_to_integer (x, &fail, width),
2367 : mode);
2368 :
2369 0 : default:
2370 0 : gcc_unreachable ();
2371 : }
2372 2048 : }
2373 :
2374 : /* Handle polynomial integers. */
2375 : else if (CONST_POLY_INT_P (op))
2376 : {
2377 : poly_wide_int result;
2378 : switch (code)
2379 : {
2380 : case NEG:
2381 : result = -const_poly_int_value (op);
2382 : break;
2383 :
2384 : case NOT:
2385 : result = ~const_poly_int_value (op);
2386 : break;
2387 :
2388 : default:
2389 : return NULL_RTX;
2390 : }
2391 : return immed_wide_int_const (result, mode);
2392 : }
2393 :
2394 : return NULL_RTX;
2395 : }
2396 :
2397 : /* Subroutine of simplify_binary_operation to simplify a binary operation
2398 : CODE that can commute with byte swapping, with result mode MODE and
2399 : operating on OP0 and OP1. CODE is currently one of AND, IOR or XOR.
2400 : Return zero if no simplification or canonicalization is possible. */
2401 :
2402 : rtx
2403 37536743 : simplify_context::simplify_byte_swapping_operation (rtx_code code,
2404 : machine_mode mode,
2405 : rtx op0, rtx op1)
2406 : {
2407 37536743 : rtx tem;
2408 :
2409 : /* (op (bswap x) C1)) -> (bswap (op x C2)) with C2 swapped. */
2410 37536743 : if (GET_CODE (op0) == BSWAP && CONST_SCALAR_INT_P (op1))
2411 : {
2412 254 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0),
2413 : simplify_gen_unary (BSWAP, mode, op1, mode));
2414 254 : return simplify_gen_unary (BSWAP, mode, tem, mode);
2415 : }
2416 :
2417 : /* (op (bswap x) (bswap y)) -> (bswap (op x y)). */
2418 37536489 : if (GET_CODE (op0) == BSWAP && GET_CODE (op1) == BSWAP)
2419 : {
2420 0 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0), XEXP (op1, 0));
2421 0 : return simplify_gen_unary (BSWAP, mode, tem, mode);
2422 : }
2423 :
2424 : return NULL_RTX;
2425 : }
2426 :
2427 : /* Subroutine of simplify_binary_operation to simplify a commutative,
2428 : associative binary operation CODE with result mode MODE, operating
2429 : on OP0 and OP1. CODE is currently one of PLUS, MULT, AND, IOR, XOR,
2430 : SMIN, SMAX, UMIN or UMAX. Return zero if no simplification or
2431 : canonicalization is possible. */
2432 :
2433 : rtx
2434 48305053 : simplify_context::simplify_associative_operation (rtx_code code,
2435 : machine_mode mode,
2436 : rtx op0, rtx op1)
2437 : {
2438 48305053 : rtx tem;
2439 :
2440 : /* Normally expressions simplified by simplify-rtx.cc are combined
2441 : at most from a few machine instructions and therefore the
2442 : expressions should be fairly small. During var-tracking
2443 : we can see arbitrarily large expressions though and reassociating
2444 : those can be quadratic, so punt after encountering max_assoc_count
2445 : simplify_associative_operation calls during outermost simplify_*
2446 : call. */
2447 48305053 : if (++assoc_count >= max_assoc_count)
2448 : return NULL_RTX;
2449 :
2450 : /* Linearize the operator to the left. */
2451 48300653 : if (GET_CODE (op1) == code)
2452 : {
2453 : /* "(a op b) op (c op d)" becomes "((a op b) op c) op d)". */
2454 19137 : if (GET_CODE (op0) == code)
2455 : {
2456 4993 : tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
2457 4993 : return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
2458 : }
2459 :
2460 : /* "a op (b op c)" becomes "(b op c) op a". */
2461 14144 : if (! swap_commutative_operands_p (op1, op0))
2462 14144 : return simplify_gen_binary (code, mode, op1, op0);
2463 :
2464 : std::swap (op0, op1);
2465 : }
2466 :
2467 48281516 : if (GET_CODE (op0) == code)
2468 : {
2469 : /* Canonicalize "(x op c) op y" as "(x op y) op c". */
2470 1336881 : if (swap_commutative_operands_p (XEXP (op0, 1), op1))
2471 : {
2472 269166 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
2473 269166 : return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2474 : }
2475 :
2476 : /* Attempt to simplify "(a op b) op c" as "a op (b op c)". */
2477 1067715 : tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
2478 1067715 : if (tem != 0)
2479 80656 : return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
2480 :
2481 : /* Attempt to simplify "(a op b) op c" as "(a op c) op b". */
2482 987059 : tem = simplify_binary_operation (code, mode, XEXP (op0, 0), op1);
2483 987059 : if (tem != 0)
2484 32241 : return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2485 : }
2486 :
2487 : return 0;
2488 : }
2489 :
2490 : /* If COMPARISON can be treated as an unsigned comparison, return a mask
2491 : that represents it (8 if it includes <, 4 if it includes > and 2
2492 : if it includes ==). Return 0 otherwise. */
2493 : static int
2494 18890 : unsigned_comparison_to_mask (rtx_code comparison)
2495 : {
2496 0 : switch (comparison)
2497 : {
2498 : case LTU:
2499 : return 8;
2500 : case GTU:
2501 : return 4;
2502 : case EQ:
2503 : return 2;
2504 :
2505 : case LEU:
2506 : return 10;
2507 : case GEU:
2508 : return 6;
2509 :
2510 : case NE:
2511 : return 12;
2512 :
2513 : default:
2514 : return 0;
2515 : }
2516 : }
2517 :
2518 : /* Reverse the mapping in unsigned_comparison_to_mask, going from masks
2519 : to comparisons. */
2520 : static rtx_code
2521 6608 : mask_to_unsigned_comparison (int mask)
2522 : {
2523 6608 : switch (mask)
2524 : {
2525 : case 8:
2526 : return LTU;
2527 160 : case 4:
2528 160 : return GTU;
2529 2514 : case 2:
2530 2514 : return EQ;
2531 :
2532 160 : case 10:
2533 160 : return LEU;
2534 160 : case 6:
2535 160 : return GEU;
2536 :
2537 3454 : case 12:
2538 3454 : return NE;
2539 :
2540 0 : default:
2541 0 : gcc_unreachable ();
2542 : }
2543 : }
2544 :
2545 : /* Return a mask describing the COMPARISON. */
2546 : static int
2547 2666 : comparison_to_mask (enum rtx_code comparison)
2548 : {
2549 2666 : switch (comparison)
2550 : {
2551 : case LT:
2552 : return 8;
2553 472 : case GT:
2554 472 : return 4;
2555 419 : case EQ:
2556 419 : return 2;
2557 19 : case UNORDERED:
2558 19 : return 1;
2559 :
2560 0 : case LTGT:
2561 0 : return 12;
2562 441 : case LE:
2563 441 : return 10;
2564 441 : case GE:
2565 441 : return 6;
2566 0 : case UNLT:
2567 0 : return 9;
2568 0 : case UNGT:
2569 0 : return 5;
2570 0 : case UNEQ:
2571 0 : return 3;
2572 :
2573 0 : case ORDERED:
2574 0 : return 14;
2575 400 : case NE:
2576 400 : return 13;
2577 0 : case UNLE:
2578 0 : return 11;
2579 0 : case UNGE:
2580 0 : return 7;
2581 :
2582 0 : default:
2583 0 : gcc_unreachable ();
2584 : }
2585 : }
2586 :
2587 : /* Return a comparison corresponding to the MASK. */
2588 : static enum rtx_code
2589 1014 : mask_to_comparison (int mask)
2590 : {
2591 1014 : switch (mask)
2592 : {
2593 : case 8:
2594 : return LT;
2595 : case 4:
2596 : return GT;
2597 : case 2:
2598 : return EQ;
2599 : case 1:
2600 : return UNORDERED;
2601 :
2602 : case 12:
2603 : return LTGT;
2604 : case 10:
2605 : return LE;
2606 : case 6:
2607 : return GE;
2608 : case 9:
2609 : return UNLT;
2610 : case 5:
2611 : return UNGT;
2612 : case 3:
2613 : return UNEQ;
2614 :
2615 : case 14:
2616 : return ORDERED;
2617 : case 13:
2618 : return NE;
2619 : case 11:
2620 : return UNLE;
2621 : case 7:
2622 : return UNGE;
2623 :
2624 0 : default:
2625 0 : gcc_unreachable ();
2626 : }
2627 : }
2628 :
2629 : /* Canonicalize RES, a scalar const0_rtx/const_true_rtx to the right
2630 : false/true value of comparison with MODE where comparison operands
2631 : have CMP_MODE. */
2632 :
2633 : static rtx
2634 785949 : relational_result (machine_mode mode, machine_mode cmp_mode, rtx res)
2635 : {
2636 785949 : if (SCALAR_FLOAT_MODE_P (mode))
2637 : {
2638 197 : if (res == const0_rtx)
2639 193 : return CONST0_RTX (mode);
2640 : #ifdef FLOAT_STORE_FLAG_VALUE
2641 : REAL_VALUE_TYPE val = FLOAT_STORE_FLAG_VALUE (mode);
2642 : return const_double_from_real_value (val, mode);
2643 : #else
2644 : return NULL_RTX;
2645 : #endif
2646 : }
2647 785752 : if (VECTOR_MODE_P (mode))
2648 : {
2649 406 : if (res == const0_rtx)
2650 79 : return CONST0_RTX (mode);
2651 : #ifdef VECTOR_STORE_FLAG_VALUE
2652 327 : rtx val = VECTOR_STORE_FLAG_VALUE (mode);
2653 317 : if (val == NULL_RTX)
2654 : return NULL_RTX;
2655 317 : if (val == const1_rtx)
2656 0 : return CONST1_RTX (mode);
2657 :
2658 317 : return gen_const_vec_duplicate (mode, val);
2659 : #else
2660 : return NULL_RTX;
2661 : #endif
2662 : }
2663 : /* For vector comparison with scalar int result, it is unknown
2664 : if the target means here a comparison into an integral bitmask,
2665 : or comparison where all comparisons true mean const_true_rtx
2666 : whole result, or where any comparisons true mean const_true_rtx
2667 : whole result. For const0_rtx all the cases are the same. */
2668 785346 : if (VECTOR_MODE_P (cmp_mode)
2669 0 : && SCALAR_INT_MODE_P (mode)
2670 0 : && res == const_true_rtx)
2671 0 : return NULL_RTX;
2672 :
2673 : return res;
2674 : }
2675 :
2676 : /* Simplify a logical operation CODE with result mode MODE, operating on OP0
2677 : and OP1, in the case where both are relational operations. Assume that
2678 : OP0 is inverted if INVERT0_P is true.
2679 :
2680 : Return 0 if no such simplification is possible. */
2681 : rtx
2682 13584876 : simplify_context::simplify_logical_relational_operation (rtx_code code,
2683 : machine_mode mode,
2684 : rtx op0, rtx op1,
2685 : bool invert0_p)
2686 : {
2687 13584876 : if (!(COMPARISON_P (op0) && COMPARISON_P (op1)))
2688 : return 0;
2689 :
2690 21685 : if (!(rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2691 9873 : && rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))))
2692 : return 0;
2693 :
2694 9445 : if (side_effects_p (op0))
2695 : return 0;
2696 :
2697 9445 : enum rtx_code code0 = GET_CODE (op0);
2698 9445 : enum rtx_code code1 = GET_CODE (op1);
2699 9445 : machine_mode cmp_mode = GET_MODE (XEXP (op0, 0));
2700 9445 : if (cmp_mode == VOIDmode)
2701 0 : cmp_mode = GET_MODE (XEXP (op0, 1));
2702 :
2703 : /* Assume at first that the comparisons are on integers, and that the
2704 : operands are therefore ordered. */
2705 9445 : int all = 14;
2706 9445 : int mask0 = unsigned_comparison_to_mask (code0);
2707 9445 : int mask1 = unsigned_comparison_to_mask (code1);
2708 18890 : bool unsigned_p = (IN_RANGE (mask0 & 12, 4, 8)
2709 9445 : || IN_RANGE (mask1 & 12, 4, 8));
2710 1333 : if (unsigned_p)
2711 : {
2712 : /* We only reach here when comparing integers. Reject mixtures of signed
2713 : and unsigned comparisons. */
2714 8112 : if (mask0 == 0 || mask1 == 0)
2715 : return 0;
2716 : }
2717 : else
2718 : {
2719 : /* See whether the operands might be unordered. Assume that all
2720 : results are possible for CC modes, and punt later if we don't get an
2721 : always-true or always-false answer. */
2722 1333 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC || HONOR_NANS (cmp_mode))
2723 : all = 15;
2724 1333 : mask0 = comparison_to_mask (code0) & all;
2725 1333 : mask1 = comparison_to_mask (code1) & all;
2726 : }
2727 :
2728 8165 : if (invert0_p)
2729 4582 : mask0 = mask0 ^ all;
2730 :
2731 8165 : int mask;
2732 8165 : if (code == AND)
2733 960 : mask = mask0 & mask1;
2734 7205 : else if (code == IOR)
2735 948 : mask = mask0 | mask1;
2736 6257 : else if (code == XOR)
2737 6257 : mask = mask0 ^ mask1;
2738 : else
2739 : return 0;
2740 :
2741 8165 : if (mask == all)
2742 232 : return relational_result (mode, GET_MODE (op0), const_true_rtx);
2743 :
2744 7933 : if (mask == 0)
2745 232 : return relational_result (mode, GET_MODE (op0), const0_rtx);
2746 :
2747 7701 : if (unsigned_p)
2748 6608 : code = mask_to_unsigned_comparison (mask);
2749 : else
2750 : {
2751 1093 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
2752 : return 0;
2753 :
2754 1014 : code = mask_to_comparison (mask);
2755 : /* LTGT and NE are arithmetically equivalent for ordered operands,
2756 : with NE being the canonical choice. */
2757 1014 : if (code == LTGT && all == 14)
2758 184 : code = NE;
2759 : }
2760 :
2761 7622 : op0 = XEXP (op1, 0);
2762 7622 : op1 = XEXP (op1, 1);
2763 :
2764 7622 : return simplify_gen_relational (code, mode, VOIDmode, op0, op1);
2765 : }
2766 :
2767 : /* We are going to IOR together OP0/OP1. If there is a common term in OP0/OP1
2768 : then we may be able to simplify the expression. We're primarily trying to
2769 : simplify down to IOR/XOR expression right now, but there may be other
2770 : simplifications we can do in the future.
2771 :
2772 : Return the simplified expression or NULL_RTX if no simplification was
2773 : possible. */
2774 : rtx
2775 27705991 : simplify_context::simplify_ior_with_common_term (machine_mode mode, rtx op0, rtx op1)
2776 : {
2777 : /* (ior X (plus/xor X C)) can be simplified into (ior X C) when
2778 : X and C have no bits in common. */
2779 27705991 : if ((GET_CODE (op1) == PLUS || GET_CODE (op1) == XOR)
2780 227131 : && rtx_equal_p (op0, XEXP (op1, 0))
2781 8333 : && ((nonzero_bits (op0, GET_MODE (op0))
2782 8333 : & nonzero_bits (XEXP (op1, 1), GET_MODE (op1))) == 0)
2783 27705991 : && !side_effects_p (op1))
2784 0 : return simplify_gen_binary (IOR, mode, op0, XEXP (op1, 1));
2785 :
2786 : /* (ior (and A C1) (and (not A) C2)) can be converted
2787 : into (and (xor A C2) (C1 + C2)) when there are no bits
2788 : in common between C1 and C2. */
2789 27705991 : if (GET_CODE (op0) == AND
2790 4008151 : && GET_CODE (op1) == AND
2791 392449 : && GET_CODE (XEXP (op1, 0)) == NOT
2792 19085 : && rtx_equal_p (XEXP (op0, 0), XEXP (XEXP (op1, 0), 0))
2793 3515 : && CONST_INT_P (XEXP (op0, 1))
2794 91 : && CONST_INT_P (XEXP (op1, 1))
2795 27706082 : && (INTVAL (XEXP (op0, 1)) & INTVAL (XEXP (op1, 1))) == 0)
2796 : {
2797 91 : rtx c = GEN_INT (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1)));
2798 :
2799 91 : rtx tem = simplify_gen_binary (XOR, mode, XEXP (op0, 0), XEXP (op1, 1));
2800 91 : if (tem)
2801 : {
2802 91 : tem = simplify_gen_binary (AND, mode, tem, c);
2803 :
2804 91 : if (tem)
2805 : return tem;
2806 : }
2807 : }
2808 :
2809 : /* Another variant seen on some target particularly those with
2810 : sub-word operations.
2811 :
2812 : (ior (and A C1) (plus (and A C2) C2)) can be simplified into
2813 : (and (xor (A C2) (C1 + C2).
2814 :
2815 : Where C2 is the sign bit for A's mode. So 0x80 for QI,
2816 : 0x8000 for HI, etc. In this case we know there is no carry
2817 : from the PLUS into relevant bits of the output. */
2818 27705900 : if (GET_CODE (op0) == AND
2819 4008060 : && GET_CODE (op1) == PLUS
2820 5819 : && GET_CODE (XEXP (op1, 0)) == AND
2821 300 : && rtx_equal_p (XEXP (op0, 0), XEXP (XEXP (op1, 0), 0))
2822 276 : && CONST_INT_P (XEXP (op0, 1))
2823 276 : && CONST_INT_P (XEXP (op1, 1))
2824 276 : && CONST_INT_P (XEXP (XEXP (op1, 0), 1))
2825 276 : && INTVAL (XEXP (op1, 1)) == INTVAL (XEXP (XEXP (op1, 0), 1))
2826 72 : && GET_MODE_BITSIZE (GET_MODE (op1)).is_constant ()
2827 144 : && ((INTVAL (XEXP (op1, 1)) & GET_MODE_MASK (GET_MODE (op1)))
2828 144 : == HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (GET_MODE (op1)).to_constant () - 1))
2829 27705900 : && (INTVAL (XEXP (op0, 1)) & INTVAL (XEXP (op1, 1))) == 0)
2830 : {
2831 0 : rtx c = GEN_INT (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1)));
2832 :
2833 0 : rtx tem = simplify_gen_binary (XOR, mode, XEXP (op0, 0), XEXP (op1, 1));
2834 0 : if (tem)
2835 : {
2836 0 : tem = simplify_gen_binary (AND, mode, tem, c);
2837 0 : if (tem)
2838 : return tem;
2839 : }
2840 : }
2841 : return NULL_RTX;
2842 : }
2843 :
2844 :
2845 : /* Simplify a binary operation CODE with result mode MODE, operating on OP0
2846 : and OP1. Return 0 if no simplification is possible.
2847 :
2848 : Don't use this for relational operations such as EQ or LT.
2849 : Use simplify_relational_operation instead. */
2850 : rtx
2851 490317097 : simplify_context::simplify_binary_operation (rtx_code code, machine_mode mode,
2852 : rtx op0, rtx op1)
2853 : {
2854 490317097 : rtx trueop0, trueop1;
2855 490317097 : rtx tem;
2856 :
2857 : /* Relational operations don't work here. We must know the mode
2858 : of the operands in order to do the comparison correctly.
2859 : Assuming a full word can give incorrect results.
2860 : Consider comparing 128 with -128 in QImode. */
2861 490317097 : gcc_assert (GET_RTX_CLASS (code) != RTX_COMPARE);
2862 490317097 : gcc_assert (GET_RTX_CLASS (code) != RTX_COMM_COMPARE);
2863 :
2864 : /* Make sure the constant is second. */
2865 490317097 : if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
2866 490317097 : && swap_commutative_operands_p (op0, op1))
2867 : std::swap (op0, op1);
2868 :
2869 490317097 : trueop0 = avoid_constant_pool_reference (op0);
2870 490317097 : trueop1 = avoid_constant_pool_reference (op1);
2871 :
2872 490317097 : tem = simplify_const_binary_operation (code, mode, trueop0, trueop1);
2873 490317097 : if (tem)
2874 : return tem;
2875 459915835 : tem = simplify_binary_operation_1 (code, mode, op0, op1, trueop0, trueop1);
2876 :
2877 459915835 : if (tem)
2878 : return tem;
2879 :
2880 : /* If the above steps did not result in a simplification and op0 or op1
2881 : were constant pool references, use the referenced constants directly. */
2882 395439596 : if (trueop0 != op0 || trueop1 != op1)
2883 577382 : return simplify_gen_binary (code, mode, trueop0, trueop1);
2884 :
2885 : return NULL_RTX;
2886 : }
2887 :
2888 : /* Subroutine of simplify_binary_operation_1 that looks for cases in
2889 : which OP0 and OP1 are both vector series or vector duplicates
2890 : (which are really just series with a step of 0). If so, try to
2891 : form a new series by applying CODE to the bases and to the steps.
2892 : Return null if no simplification is possible.
2893 :
2894 : MODE is the mode of the operation and is known to be a vector
2895 : integer mode. */
2896 :
2897 : rtx
2898 2523218 : simplify_context::simplify_binary_operation_series (rtx_code code,
2899 : machine_mode mode,
2900 : rtx op0, rtx op1)
2901 : {
2902 2523218 : rtx base0, step0;
2903 2523218 : if (vec_duplicate_p (op0, &base0))
2904 73119 : step0 = const0_rtx;
2905 2450099 : else if (!vec_series_p (op0, &base0, &step0))
2906 : return NULL_RTX;
2907 :
2908 73839 : rtx base1, step1;
2909 73839 : if (vec_duplicate_p (op1, &base1))
2910 422 : step1 = const0_rtx;
2911 73417 : else if (!vec_series_p (op1, &base1, &step1))
2912 : return NULL_RTX;
2913 :
2914 : /* Only create a new series if we can simplify both parts. In other
2915 : cases this isn't really a simplification, and it's not necessarily
2916 : a win to replace a vector operation with a scalar operation. */
2917 5646 : scalar_mode inner_mode = GET_MODE_INNER (mode);
2918 5646 : rtx new_base = simplify_binary_operation (code, inner_mode, base0, base1);
2919 5646 : if (!new_base)
2920 : return NULL_RTX;
2921 :
2922 4704 : rtx new_step = simplify_binary_operation (code, inner_mode, step0, step1);
2923 4704 : if (!new_step)
2924 : return NULL_RTX;
2925 :
2926 4704 : return gen_vec_series (mode, new_base, new_step);
2927 : }
2928 :
2929 : /* Subroutine of simplify_binary_operation_1. Un-distribute a binary
2930 : operation CODE with result mode MODE, operating on OP0 and OP1.
2931 : e.g. simplify (xor (and A C) (and (B C)) to (and (xor (A B) C).
2932 : Returns NULL_RTX if no simplification is possible. */
2933 :
2934 : rtx
2935 1329519 : simplify_context::simplify_distributive_operation (rtx_code code,
2936 : machine_mode mode,
2937 : rtx op0, rtx op1)
2938 : {
2939 1329519 : enum rtx_code op = GET_CODE (op0);
2940 1329519 : gcc_assert (GET_CODE (op1) == op);
2941 :
2942 1329519 : if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))
2943 1329519 : && ! side_effects_p (XEXP (op0, 1)))
2944 328918 : return simplify_gen_binary (op, mode,
2945 : simplify_gen_binary (code, mode,
2946 : XEXP (op0, 0),
2947 : XEXP (op1, 0)),
2948 328918 : XEXP (op0, 1));
2949 :
2950 1000601 : if (GET_RTX_CLASS (op) == RTX_COMM_ARITH)
2951 : {
2952 982806 : if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2953 982806 : && ! side_effects_p (XEXP (op0, 0)))
2954 484276 : return simplify_gen_binary (op, mode,
2955 : simplify_gen_binary (code, mode,
2956 : XEXP (op0, 1),
2957 : XEXP (op1, 1)),
2958 484276 : XEXP (op0, 0));
2959 498530 : if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 1))
2960 498530 : && ! side_effects_p (XEXP (op0, 0)))
2961 54 : return simplify_gen_binary (op, mode,
2962 : simplify_gen_binary (code, mode,
2963 : XEXP (op0, 1),
2964 : XEXP (op1, 0)),
2965 54 : XEXP (op0, 0));
2966 498476 : if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 0))
2967 498476 : && ! side_effects_p (XEXP (op0, 1)))
2968 254194 : return simplify_gen_binary (op, mode,
2969 : simplify_gen_binary (code, mode,
2970 : XEXP (op0, 0),
2971 : XEXP (op1, 1)),
2972 254194 : XEXP (op0, 1));
2973 : }
2974 :
2975 : return NULL_RTX;
2976 : }
2977 :
2978 : /* Return TRUE if a rotate in mode MODE with a constant count in OP1
2979 : should be reversed.
2980 :
2981 : If the rotate should not be reversed, return FALSE.
2982 :
2983 : LEFT indicates if this is a rotate left or a rotate right. */
2984 :
2985 : bool
2986 149611 : reverse_rotate_by_imm_p (machine_mode mode, unsigned int left, rtx op1)
2987 : {
2988 149611 : if (!CONST_INT_P (op1))
2989 : return false;
2990 :
2991 : /* Some targets may only be able to rotate by a constant
2992 : in one direction. So we need to query the optab interface
2993 : to see what is possible. */
2994 112851 : optab binoptab = left ? rotl_optab : rotr_optab;
2995 48613 : optab re_binoptab = left ? rotr_optab : rotl_optab;
2996 112851 : enum insn_code icode = optab_handler (binoptab, mode);
2997 112851 : enum insn_code re_icode = optab_handler (re_binoptab, mode);
2998 :
2999 : /* If the target can not support the reversed optab, then there
3000 : is nothing to do. */
3001 112851 : if (re_icode == CODE_FOR_nothing)
3002 : return false;
3003 :
3004 : /* If the target does not support the requested rotate-by-immediate,
3005 : then we want to try reversing the rotate. We also want to try
3006 : reversing to minimize the count. */
3007 110369 : if ((icode == CODE_FOR_nothing)
3008 110369 : || (!insn_operand_matches (icode, 2, op1))
3009 551845 : || (IN_RANGE (INTVAL (op1),
3010 : GET_MODE_UNIT_PRECISION (mode) / 2 + left,
3011 : GET_MODE_UNIT_PRECISION (mode) - 1)))
3012 15518 : return (insn_operand_matches (re_icode, 2, op1));
3013 : return false;
3014 : }
3015 :
3016 : /* Analyse argument X to see if it represents an (ASHIFT X Y) operation
3017 : and return the expression to be shifted in SHIFT_OPND and the shift amount
3018 : in SHIFT_AMNT. This is primarily used to group handling of ASHIFT (X, CST)
3019 : and (PLUS (X, X)) in one place. If the expression is not equivalent to an
3020 : ASHIFT then return FALSE and set SHIFT_OPND and SHIFT_AMNT to NULL. */
3021 :
3022 : static bool
3023 539978297 : extract_ashift_operands_p (rtx x, rtx *shift_opnd, rtx *shift_amnt)
3024 : {
3025 539978297 : if (GET_CODE (x) == ASHIFT)
3026 : {
3027 13831737 : *shift_opnd = XEXP (x, 0);
3028 13831737 : *shift_amnt = XEXP (x, 1);
3029 13831737 : return true;
3030 : }
3031 526146560 : if (GET_CODE (x) == PLUS && rtx_equal_p (XEXP (x, 0), XEXP (x, 1)))
3032 : {
3033 11884 : *shift_opnd = XEXP (x, 0);
3034 11884 : *shift_amnt = CONST1_RTX (GET_MODE (x));
3035 11884 : return true;
3036 : }
3037 526134676 : *shift_opnd = NULL_RTX;
3038 526134676 : *shift_amnt = NULL_RTX;
3039 526134676 : return false;
3040 : }
3041 :
3042 : /* OP0 and OP1 are combined under an operation of mode MODE that can
3043 : potentially result in a ROTATE expression. Analyze the OP0 and OP1
3044 : and return the resulting ROTATE expression if so. Return NULL otherwise.
3045 : This is used in detecting the patterns (X << C1) [+,|,^] (X >> C2) where
3046 : C1 + C2 == GET_MODE_UNIT_PRECISION (mode).
3047 : (X << C1) and (C >> C2) would be OP0 and OP1. */
3048 :
3049 : static rtx
3050 272821377 : simplify_rotate_op (rtx op0, rtx op1, machine_mode mode)
3051 : {
3052 : /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3053 : mode size to (rotate A CX). */
3054 :
3055 272821377 : rtx opleft = op0;
3056 272821377 : rtx opright = op1;
3057 272821377 : rtx ashift_opnd, ashift_amnt;
3058 : /* In some cases the ASHIFT is not a direct ASHIFT. Look deeper and extract
3059 : the relevant operands here. */
3060 272821377 : bool ashift_op_p
3061 272821377 : = extract_ashift_operands_p (op1, &ashift_opnd, &ashift_amnt);
3062 :
3063 272821377 : if (ashift_op_p
3064 271125819 : || GET_CODE (op1) == SUBREG)
3065 : {
3066 : opleft = op1;
3067 : opright = op0;
3068 : }
3069 : else
3070 : {
3071 267156920 : opright = op1;
3072 267156920 : opleft = op0;
3073 267156920 : ashift_op_p
3074 267156920 : = extract_ashift_operands_p (opleft, &ashift_opnd, &ashift_amnt);
3075 : }
3076 :
3077 13843621 : if (ashift_op_p && GET_CODE (opright) == LSHIFTRT
3078 271178840 : && rtx_equal_p (ashift_opnd, XEXP (opright, 0)))
3079 : {
3080 9403 : rtx leftcst = unwrap_const_vec_duplicate (ashift_amnt);
3081 9403 : rtx rightcst = unwrap_const_vec_duplicate (XEXP (opright, 1));
3082 :
3083 5590 : if (CONST_INT_P (leftcst) && CONST_INT_P (rightcst)
3084 14993 : && (INTVAL (leftcst) + INTVAL (rightcst)
3085 5590 : == GET_MODE_UNIT_PRECISION (mode)))
3086 5089 : return gen_rtx_ROTATE (mode, XEXP (opright, 0), ashift_amnt);
3087 : }
3088 :
3089 : /* Same, but for ashift that has been "simplified" to a wider mode
3090 : by simplify_shift_const. */
3091 272816288 : scalar_int_mode int_mode, inner_mode;
3092 :
3093 272816288 : if (GET_CODE (opleft) == SUBREG
3094 278417751 : && is_a <scalar_int_mode> (mode, &int_mode)
3095 5596374 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (opleft)),
3096 : &inner_mode)
3097 5559446 : && GET_CODE (SUBREG_REG (opleft)) == ASHIFT
3098 189247 : && GET_CODE (opright) == LSHIFTRT
3099 888 : && GET_CODE (XEXP (opright, 0)) == SUBREG
3100 230 : && known_eq (SUBREG_BYTE (opleft), SUBREG_BYTE (XEXP (opright, 0)))
3101 456 : && GET_MODE_SIZE (int_mode) < GET_MODE_SIZE (inner_mode)
3102 221 : && rtx_equal_p (XEXP (SUBREG_REG (opleft), 0),
3103 221 : SUBREG_REG (XEXP (opright, 0)))
3104 5 : && CONST_INT_P (XEXP (SUBREG_REG (opleft), 1))
3105 5 : && CONST_INT_P (XEXP (opright, 1))
3106 272816288 : && (INTVAL (XEXP (SUBREG_REG (opleft), 1))
3107 5 : + INTVAL (XEXP (opright, 1))
3108 5 : == GET_MODE_PRECISION (int_mode)))
3109 1 : return gen_rtx_ROTATE (int_mode, XEXP (opright, 0),
3110 : XEXP (SUBREG_REG (opleft), 1));
3111 : return NULL_RTX;
3112 : }
3113 :
3114 : /* Returns true if OP0 and OP1 match the pattern (OP (plus (A - 1)) (neg A)),
3115 : and the pattern can be simplified (there are no side effects). */
3116 :
3117 : static bool
3118 39614791 : match_plus_neg_pattern (rtx op0, rtx op1, machine_mode mode)
3119 : {
3120 : /* Remove SUBREG from OP0 and OP1, if needed. */
3121 39614791 : if (GET_CODE (op0) == SUBREG
3122 7194931 : && GET_CODE (op1) == SUBREG
3123 297762 : && subreg_lowpart_p (op0)
3124 39911892 : && subreg_lowpart_p (op1))
3125 : {
3126 297092 : op0 = XEXP (op0, 0);
3127 297092 : op1 = XEXP (op1, 0);
3128 : }
3129 :
3130 : /* Check for the pattern (OP (plus (A - 1)) (neg A)). */
3131 39614791 : if (((GET_CODE (op1) == NEG
3132 4004 : && GET_CODE (op0) == PLUS
3133 2133 : && XEXP (op0, 1) == CONSTM1_RTX (mode))
3134 39614101 : || (GET_CODE (op0) == NEG
3135 82652 : && GET_CODE (op1) == PLUS
3136 0 : && XEXP (op1, 1) == CONSTM1_RTX (mode)))
3137 690 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3138 39614793 : && !side_effects_p (XEXP (op0, 0)))
3139 2 : return true;
3140 : return false;
3141 : }
3142 :
3143 : /* Check if OP matches the pattern of (subreg (not X)) and the subreg is
3144 : non-paradoxical. */
3145 :
3146 : static bool
3147 75075958 : non_paradoxical_subreg_not_p (rtx op)
3148 : {
3149 75075958 : return GET_CODE (op) == SUBREG
3150 8744747 : && !paradoxical_subreg_p (op)
3151 77890359 : && GET_CODE (SUBREG_REG (op)) == NOT;
3152 : }
3153 :
3154 : /* Convert (binop (subreg (not X)) Y) into (binop (not (subreg X)) Y), or
3155 : (binop X (subreg (not Y))) into (binop X (not (subreg Y))) to expose
3156 : opportunities to combine another binary logical operation with NOT. */
3157 :
3158 : static rtx
3159 37539244 : simplify_with_subreg_not (rtx_code binop, machine_mode mode, rtx op0, rtx op1)
3160 : {
3161 37539244 : rtx opn = NULL_RTX;
3162 37539244 : if (non_paradoxical_subreg_not_p (op0))
3163 : opn = op0;
3164 37536714 : else if (non_paradoxical_subreg_not_p (op1))
3165 : opn = op1;
3166 :
3167 2553 : if (opn == NULL_RTX)
3168 : return NULL_RTX;
3169 :
3170 5106 : rtx new_subreg = simplify_gen_subreg (mode,
3171 : XEXP (SUBREG_REG (opn), 0),
3172 2553 : GET_MODE (SUBREG_REG (opn)),
3173 2553 : SUBREG_BYTE (opn));
3174 :
3175 2553 : if (!new_subreg)
3176 : return NULL_RTX;
3177 :
3178 2501 : rtx new_not = simplify_gen_unary (NOT, mode, new_subreg, mode);
3179 2501 : if (opn == op0)
3180 2478 : return simplify_gen_binary (binop, mode, new_not, op1);
3181 : else
3182 23 : return simplify_gen_binary (binop, mode, op0, new_not);
3183 : }
3184 :
3185 : /* Return TRUE iff NOP is a negated form of OP, or vice-versa. */
3186 : static bool
3187 6706277 : negated_ops_p (rtx nop, rtx op)
3188 : {
3189 : /* Explicit negation. */
3190 6706277 : if (GET_CODE (nop) == NOT
3191 6706277 : && rtx_equal_p (XEXP (nop, 0), op))
3192 : return true;
3193 6702956 : if (GET_CODE (op) == NOT
3194 6702956 : && rtx_equal_p (XEXP (op, 0), nop))
3195 : return true;
3196 :
3197 : /* (~C <r A) is a negated form of (C << A) if C == 1. */
3198 6699880 : if (GET_CODE (op) == ASHIFT
3199 1436306 : && GET_CODE (nop) == ROTATE
3200 0 : && XEXP (op, 0) == CONST1_RTX (GET_MODE (op))
3201 0 : && CONST_INT_P (XEXP (nop, 0))
3202 0 : && INTVAL (XEXP (nop, 0)) == -2
3203 6699880 : && rtx_equal_p (XEXP (op, 1), XEXP (nop, 1)))
3204 : return true;
3205 6699880 : if (GET_CODE (nop) == ASHIFT
3206 152535 : && GET_CODE (op) == ROTATE
3207 0 : && XEXP (nop, 0) == CONST1_RTX (GET_MODE (op))
3208 0 : && CONST_INT_P (XEXP (nop, 0))
3209 0 : && INTVAL (XEXP (nop, 0)) == -2
3210 6699880 : && rtx_equal_p (XEXP (op, 1), XEXP (nop, 1)))
3211 : return true;
3212 :
3213 : /* ??? Should we consider rotations of C and ~C by the same amount? */
3214 :
3215 : return false;
3216 : }
3217 :
3218 : /* Subroutine of simplify_binary_operation. Simplify a binary operation
3219 : CODE with result mode MODE, operating on OP0 and OP1. If OP0 and/or
3220 : OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the
3221 : actual constants. */
3222 :
3223 : rtx
3224 459915835 : simplify_context::simplify_binary_operation_1 (rtx_code code,
3225 : machine_mode mode,
3226 : rtx op0, rtx op1,
3227 : rtx trueop0, rtx trueop1)
3228 : {
3229 459915835 : rtx tem, reversed, elt0, elt1;
3230 459915835 : HOST_WIDE_INT val;
3231 459915835 : scalar_int_mode int_mode, inner_mode;
3232 459915835 : poly_int64 offset;
3233 :
3234 : /* Even if we can't compute a constant result,
3235 : there are some cases worth simplifying. */
3236 :
3237 459915835 : switch (code)
3238 : {
3239 262425734 : case PLUS:
3240 : /* Maybe simplify x + 0 to x. The two expressions are equivalent
3241 : when x is NaN, infinite, or finite and nonzero. They aren't
3242 : when x is -0 and the rounding mode is not towards -infinity,
3243 : since (-0) + 0 is then 0. */
3244 520962852 : if (!HONOR_SIGNED_ZEROS (mode) && !HONOR_SNANS (mode)
3245 520962840 : && trueop1 == CONST0_RTX (mode))
3246 : return op0;
3247 :
3248 : /* ((-a) + b) -> (b - a) and similarly for (a + (-b)). These
3249 : transformations are safe even for IEEE. */
3250 260893056 : if (GET_CODE (op0) == NEG)
3251 65270 : return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
3252 260827786 : else if (GET_CODE (op1) == NEG)
3253 8614 : return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
3254 :
3255 : /* (~a) + 1 -> -a */
3256 260819172 : if (INTEGRAL_MODE_P (mode)
3257 256020748 : && GET_CODE (op0) == NOT
3258 1382472 : && trueop1 == const1_rtx)
3259 3830 : return simplify_gen_unary (NEG, mode, XEXP (op0, 0), mode);
3260 :
3261 : /* Handle both-operands-constant cases. We can only add
3262 : CONST_INTs to constants since the sum of relocatable symbols
3263 : can't be handled by most assemblers. Don't add CONST_INT
3264 : to CONST_INT since overflow won't be computed properly if wider
3265 : than HOST_BITS_PER_WIDE_INT. */
3266 :
3267 260815342 : if ((GET_CODE (op0) == CONST
3268 260815342 : || GET_CODE (op0) == SYMBOL_REF
3269 258206773 : || GET_CODE (op0) == LABEL_REF)
3270 260815342 : && poly_int_rtx_p (op1, &offset))
3271 2607601 : return plus_constant (mode, op0, offset);
3272 258207741 : else if ((GET_CODE (op1) == CONST
3273 258207741 : || GET_CODE (op1) == SYMBOL_REF
3274 254008705 : || GET_CODE (op1) == LABEL_REF)
3275 258207741 : && poly_int_rtx_p (op0, &offset))
3276 0 : return plus_constant (mode, op1, offset);
3277 :
3278 : /* See if this is something like X * C - X or vice versa or
3279 : if the multiplication is written as a shift. If so, we can
3280 : distribute and make a new multiply, shift, or maybe just
3281 : have X (if C is 2 in the example above). But don't make
3282 : something more expensive than we had before. */
3283 :
3284 258207741 : if (is_a <scalar_int_mode> (mode, &int_mode))
3285 : {
3286 251228269 : rtx lhs = op0, rhs = op1;
3287 :
3288 251228269 : wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
3289 251228269 : wide_int coeff1 = wi::one (GET_MODE_PRECISION (int_mode));
3290 :
3291 251228269 : if (GET_CODE (lhs) == NEG)
3292 : {
3293 0 : coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3294 0 : lhs = XEXP (lhs, 0);
3295 : }
3296 251228269 : else if (GET_CODE (lhs) == MULT
3297 9868676 : && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
3298 : {
3299 8562306 : coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
3300 8562306 : lhs = XEXP (lhs, 0);
3301 : }
3302 242665963 : else if (GET_CODE (lhs) == ASHIFT
3303 11047445 : && CONST_INT_P (XEXP (lhs, 1))
3304 10974843 : && INTVAL (XEXP (lhs, 1)) >= 0
3305 253640794 : && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
3306 : {
3307 10974831 : coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
3308 21949662 : GET_MODE_PRECISION (int_mode));
3309 10974831 : lhs = XEXP (lhs, 0);
3310 : }
3311 :
3312 251228269 : if (GET_CODE (rhs) == NEG)
3313 : {
3314 0 : coeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3315 0 : rhs = XEXP (rhs, 0);
3316 : }
3317 251228269 : else if (GET_CODE (rhs) == MULT
3318 353785 : && CONST_INT_P (XEXP (rhs, 1)))
3319 : {
3320 197313 : coeff1 = rtx_mode_t (XEXP (rhs, 1), int_mode);
3321 197313 : rhs = XEXP (rhs, 0);
3322 : }
3323 251030956 : else if (GET_CODE (rhs) == ASHIFT
3324 575781 : && CONST_INT_P (XEXP (rhs, 1))
3325 566010 : && INTVAL (XEXP (rhs, 1)) >= 0
3326 251596966 : && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
3327 : {
3328 566010 : coeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
3329 1132020 : GET_MODE_PRECISION (int_mode));
3330 566010 : rhs = XEXP (rhs, 0);
3331 : }
3332 :
3333 : /* Keep PLUS of 2 volatile memory references. */
3334 251228269 : if (rtx_equal_p (lhs, rhs)
3335 251228269 : && (!MEM_P (lhs) || !MEM_VOLATILE_P (lhs)))
3336 : {
3337 827647 : rtx orig = gen_rtx_PLUS (int_mode, op0, op1);
3338 827647 : rtx coeff;
3339 827647 : bool speed = optimize_function_for_speed_p (cfun);
3340 :
3341 827647 : coeff = immed_wide_int_const (coeff0 + coeff1, int_mode);
3342 :
3343 827647 : tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
3344 827647 : return (set_src_cost (tem, int_mode, speed)
3345 827647 : <= set_src_cost (orig, int_mode, speed) ? tem : 0);
3346 : }
3347 :
3348 : /* Optimize (X - 1) * Y + Y to X * Y. */
3349 250400622 : lhs = op0;
3350 250400622 : rhs = op1;
3351 250400622 : if (GET_CODE (op0) == MULT)
3352 : {
3353 9816510 : if (((GET_CODE (XEXP (op0, 0)) == PLUS
3354 635355 : && XEXP (XEXP (op0, 0), 1) == constm1_rtx)
3355 9767576 : || (GET_CODE (XEXP (op0, 0)) == MINUS
3356 51973 : && XEXP (XEXP (op0, 0), 1) == const1_rtx))
3357 9865444 : && rtx_equal_p (XEXP (op0, 1), op1))
3358 88 : lhs = XEXP (XEXP (op0, 0), 0);
3359 9816422 : else if (((GET_CODE (XEXP (op0, 1)) == PLUS
3360 1769 : && XEXP (XEXP (op0, 1), 1) == constm1_rtx)
3361 9816364 : || (GET_CODE (XEXP (op0, 1)) == MINUS
3362 368 : && XEXP (XEXP (op0, 1), 1) == const1_rtx))
3363 9816480 : && rtx_equal_p (XEXP (op0, 0), op1))
3364 0 : lhs = XEXP (XEXP (op0, 1), 0);
3365 : }
3366 240584112 : else if (GET_CODE (op1) == MULT)
3367 : {
3368 128171 : if (((GET_CODE (XEXP (op1, 0)) == PLUS
3369 93 : && XEXP (XEXP (op1, 0), 1) == constm1_rtx)
3370 128165 : || (GET_CODE (XEXP (op1, 0)) == MINUS
3371 23 : && XEXP (XEXP (op1, 0), 1) == const1_rtx))
3372 128177 : && rtx_equal_p (XEXP (op1, 1), op0))
3373 0 : rhs = XEXP (XEXP (op1, 0), 0);
3374 128171 : else if (((GET_CODE (XEXP (op1, 1)) == PLUS
3375 45 : && XEXP (XEXP (op1, 1), 1) == constm1_rtx)
3376 128171 : || (GET_CODE (XEXP (op1, 1)) == MINUS
3377 0 : && XEXP (XEXP (op1, 1), 1) == const1_rtx))
3378 128171 : && rtx_equal_p (XEXP (op1, 0), op0))
3379 0 : rhs = XEXP (XEXP (op1, 1), 0);
3380 : }
3381 250400622 : if (lhs != op0 || rhs != op1)
3382 88 : return simplify_gen_binary (MULT, int_mode, lhs, rhs);
3383 251228269 : }
3384 :
3385 : /* (plus (xor X C1) C2) is (xor X (C1^C2)) if C2 is signbit. */
3386 257380006 : if (CONST_SCALAR_INT_P (op1)
3387 196563910 : && GET_CODE (op0) == XOR
3388 18419 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
3389 257389669 : && mode_signbit_p (mode, op1))
3390 121 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3391 : simplify_gen_binary (XOR, mode, op1,
3392 121 : XEXP (op0, 1)));
3393 :
3394 : /* (plus (xor X C1) C2) is (xor X (C1^C2)) if X is either 0 or 1 and
3395 : 2 * ((X ^ C1) & C2) == 0; based on A + B == A ^ B + 2 * (A & B). */
3396 257379885 : if (CONST_SCALAR_INT_P (op1)
3397 196563789 : && GET_CODE (op0) == XOR
3398 18298 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
3399 9542 : && nonzero_bits (XEXP (op0, 0), mode) == 1
3400 349 : && 2 * (INTVAL (XEXP (op0, 1)) & INTVAL (op1)) == 0
3401 257379885 : && 2 * ((1 ^ INTVAL (XEXP (op0, 1))) & INTVAL (op1)) == 0)
3402 0 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3403 : simplify_gen_binary (XOR, mode, op1,
3404 0 : XEXP (op0, 1)));
3405 :
3406 : /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)). */
3407 257379885 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3408 257377357 : && GET_CODE (op0) == MULT
3409 267565271 : && GET_CODE (XEXP (op0, 0)) == NEG)
3410 : {
3411 5130 : rtx in1, in2;
3412 :
3413 5130 : in1 = XEXP (XEXP (op0, 0), 0);
3414 5130 : in2 = XEXP (op0, 1);
3415 5130 : return simplify_gen_binary (MINUS, mode, op1,
3416 : simplify_gen_binary (MULT, mode,
3417 5130 : in1, in2));
3418 : }
3419 :
3420 : /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
3421 : C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
3422 : is 1. */
3423 257374755 : if (COMPARISON_P (op0)
3424 1279700 : && ((STORE_FLAG_VALUE == -1 && trueop1 == const1_rtx)
3425 1279700 : || (STORE_FLAG_VALUE == 1 && trueop1 == constm1_rtx))
3426 257432258 : && (reversed = reversed_comparison (op0, mode)))
3427 57146 : return
3428 57146 : simplify_gen_unary (NEG, mode, reversed, mode);
3429 :
3430 : /* Convert (plus (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3431 : mode size to (rotate A CX). */
3432 257317609 : if ((tem = simplify_rotate_op (op0, op1, mode)))
3433 : return tem;
3434 :
3435 : /* If one of the operands is a PLUS or a MINUS, see if we can
3436 : simplify this by the associative law.
3437 : Don't use the associative law for floating point.
3438 : The inaccuracy makes it nonassociative,
3439 : and subtle programs can break if operations are associated. */
3440 :
3441 257316145 : if (INTEGRAL_MODE_P (mode)
3442 252517770 : && (plus_minus_operand_p (op0)
3443 218181030 : || plus_minus_operand_p (op1))
3444 35402567 : && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
3445 : return tem;
3446 :
3447 : /* Reassociate floating point addition only when the user
3448 : specifies associative math operations. */
3449 222611515 : if (FLOAT_MODE_P (mode)
3450 4798375 : && flag_associative_math)
3451 : {
3452 909676 : tem = simplify_associative_operation (code, mode, op0, op1);
3453 909676 : if (tem)
3454 : return tem;
3455 : }
3456 :
3457 : /* Handle vector series. */
3458 222597772 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3459 : {
3460 2015022 : tem = simplify_binary_operation_series (code, mode, op0, op1);
3461 2015022 : if (tem)
3462 : return tem;
3463 : }
3464 : break;
3465 :
3466 : case COMPARE:
3467 : break;
3468 :
3469 45469057 : case MINUS:
3470 : /* We can't assume x-x is 0 even with non-IEEE floating point,
3471 : but since it is zero except in very strange circumstances, we
3472 : will treat it as zero with -ffinite-math-only. */
3473 45469057 : if (rtx_equal_p (trueop0, trueop1)
3474 209134 : && ! side_effects_p (op0)
3475 45677778 : && (!FLOAT_MODE_P (mode) || !HONOR_NANS (mode)))
3476 206008 : return CONST0_RTX (mode);
3477 :
3478 : /* Change subtraction from zero into negation. (0 - x) is the
3479 : same as -x when x is NaN, infinite, or finite and nonzero.
3480 : But if the mode has signed zeros, and does not round towards
3481 : -infinity, then 0 - 0 is 0, not -0. */
3482 45263049 : if (!HONOR_SIGNED_ZEROS (mode) && trueop0 == CONST0_RTX (mode))
3483 354262 : return simplify_gen_unary (NEG, mode, op1, mode);
3484 :
3485 : /* (-1 - a) is ~a, unless the expression contains symbolic
3486 : constants, in which case not retaining additions and
3487 : subtractions could cause invalid assembly to be produced. */
3488 44908787 : if (trueop0 == CONSTM1_RTX (mode)
3489 44908787 : && !contains_symbolic_reference_p (op1))
3490 616488 : return simplify_gen_unary (NOT, mode, op1, mode);
3491 :
3492 : /* Subtracting 0 has no effect unless the mode has signalling NaNs,
3493 : or has signed zeros and supports rounding towards -infinity.
3494 : In such a case, 0 - 0 is -0. */
3495 45026065 : if (!(HONOR_SIGNED_ZEROS (mode)
3496 733766 : && HONOR_SIGN_DEPENDENT_ROUNDING (mode))
3497 44291149 : && !HONOR_SNANS (mode)
3498 88583412 : && trueop1 == CONST0_RTX (mode))
3499 : return op0;
3500 :
3501 : /* See if this is something like X * C - X or vice versa or
3502 : if the multiplication is written as a shift. If so, we can
3503 : distribute and make a new multiply, shift, or maybe just
3504 : have X (if C is 2 in the example above). But don't make
3505 : something more expensive than we had before. */
3506 :
3507 43356785 : if (is_a <scalar_int_mode> (mode, &int_mode))
3508 : {
3509 41969702 : rtx lhs = op0, rhs = op1;
3510 :
3511 41969702 : wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
3512 41969702 : wide_int negcoeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3513 :
3514 41969702 : if (GET_CODE (lhs) == NEG)
3515 : {
3516 72990 : coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3517 72990 : lhs = XEXP (lhs, 0);
3518 : }
3519 41896712 : else if (GET_CODE (lhs) == MULT
3520 195022 : && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
3521 : {
3522 70121 : coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
3523 70121 : lhs = XEXP (lhs, 0);
3524 : }
3525 41826591 : else if (GET_CODE (lhs) == ASHIFT
3526 315005 : && CONST_INT_P (XEXP (lhs, 1))
3527 311684 : && INTVAL (XEXP (lhs, 1)) >= 0
3528 42138254 : && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
3529 : {
3530 311663 : coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
3531 623326 : GET_MODE_PRECISION (int_mode));
3532 311663 : lhs = XEXP (lhs, 0);
3533 : }
3534 :
3535 41969702 : if (GET_CODE (rhs) == NEG)
3536 : {
3537 13037 : negcoeff1 = wi::one (GET_MODE_PRECISION (int_mode));
3538 13037 : rhs = XEXP (rhs, 0);
3539 : }
3540 41956665 : else if (GET_CODE (rhs) == MULT
3541 155755 : && CONST_INT_P (XEXP (rhs, 1)))
3542 : {
3543 101468 : negcoeff1 = wi::neg (rtx_mode_t (XEXP (rhs, 1), int_mode));
3544 101468 : rhs = XEXP (rhs, 0);
3545 : }
3546 41855197 : else if (GET_CODE (rhs) == ASHIFT
3547 413899 : && CONST_INT_P (XEXP (rhs, 1))
3548 413367 : && INTVAL (XEXP (rhs, 1)) >= 0
3549 42268564 : && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
3550 : {
3551 413367 : negcoeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
3552 826734 : GET_MODE_PRECISION (int_mode));
3553 413367 : negcoeff1 = -negcoeff1;
3554 413367 : rhs = XEXP (rhs, 0);
3555 : }
3556 :
3557 41969702 : if (rtx_equal_p (lhs, rhs))
3558 : {
3559 92639 : rtx orig = gen_rtx_MINUS (int_mode, op0, op1);
3560 92639 : rtx coeff;
3561 92639 : bool speed = optimize_function_for_speed_p (cfun);
3562 :
3563 92639 : coeff = immed_wide_int_const (coeff0 + negcoeff1, int_mode);
3564 :
3565 92639 : tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
3566 92639 : return (set_src_cost (tem, int_mode, speed)
3567 92639 : <= set_src_cost (orig, int_mode, speed) ? tem : 0);
3568 : }
3569 :
3570 : /* Optimize (X + 1) * Y - Y to X * Y. */
3571 41877063 : lhs = op0;
3572 41877063 : if (GET_CODE (op0) == MULT)
3573 : {
3574 194543 : if (((GET_CODE (XEXP (op0, 0)) == PLUS
3575 4960 : && XEXP (XEXP (op0, 0), 1) == const1_rtx)
3576 192865 : || (GET_CODE (XEXP (op0, 0)) == MINUS
3577 1643 : && XEXP (XEXP (op0, 0), 1) == constm1_rtx))
3578 196221 : && rtx_equal_p (XEXP (op0, 1), op1))
3579 2 : lhs = XEXP (XEXP (op0, 0), 0);
3580 194541 : else if (((GET_CODE (XEXP (op0, 1)) == PLUS
3581 30 : && XEXP (XEXP (op0, 1), 1) == const1_rtx)
3582 194529 : || (GET_CODE (XEXP (op0, 1)) == MINUS
3583 84 : && XEXP (XEXP (op0, 1), 1) == constm1_rtx))
3584 194553 : && rtx_equal_p (XEXP (op0, 0), op1))
3585 0 : lhs = XEXP (XEXP (op0, 1), 0);
3586 : }
3587 41877063 : if (lhs != op0)
3588 2 : return simplify_gen_binary (MULT, int_mode, lhs, op1);
3589 41969702 : }
3590 :
3591 : /* (a - (-b)) -> (a + b). True even for IEEE. */
3592 43264144 : if (GET_CODE (op1) == NEG)
3593 12959 : return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
3594 :
3595 : /* (-x - c) may be simplified as (-c - x). */
3596 43251185 : if (GET_CODE (op0) == NEG
3597 77132 : && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1)))
3598 : {
3599 725 : tem = simplify_unary_operation (NEG, mode, op1, mode);
3600 725 : if (tem)
3601 725 : return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
3602 : }
3603 :
3604 43250460 : if ((GET_CODE (op0) == CONST
3605 43250460 : || GET_CODE (op0) == SYMBOL_REF
3606 37728812 : || GET_CODE (op0) == LABEL_REF)
3607 43250460 : && poly_int_rtx_p (op1, &offset))
3608 54145 : return plus_constant (mode, op0, trunc_int_for_mode (-offset, mode));
3609 :
3610 : /* Don't let a relocatable value get a negative coeff. */
3611 43196315 : if (is_a <scalar_int_mode> (mode)
3612 41809263 : && poly_int_rtx_p (op1)
3613 50396655 : && GET_MODE (op0) != VOIDmode)
3614 7200340 : return simplify_gen_binary (PLUS, mode,
3615 : op0,
3616 7200340 : neg_poly_int_rtx (mode, op1));
3617 :
3618 : /* (x - (x & y)) -> (x & ~y) */
3619 35995975 : if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND)
3620 : {
3621 248467 : if (rtx_equal_p (op0, XEXP (op1, 0)))
3622 : {
3623 480 : tem = simplify_gen_unary (NOT, mode, XEXP (op1, 1),
3624 240 : GET_MODE (XEXP (op1, 1)));
3625 240 : return simplify_gen_binary (AND, mode, op0, tem);
3626 : }
3627 248227 : if (rtx_equal_p (op0, XEXP (op1, 1)))
3628 : {
3629 2364 : tem = simplify_gen_unary (NOT, mode, XEXP (op1, 0),
3630 1182 : GET_MODE (XEXP (op1, 0)));
3631 1182 : return simplify_gen_binary (AND, mode, op0, tem);
3632 : }
3633 : }
3634 :
3635 : /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
3636 : by reversing the comparison code if valid. */
3637 35994553 : if (STORE_FLAG_VALUE == 1
3638 35994553 : && trueop0 == const1_rtx
3639 1183506 : && COMPARISON_P (op1)
3640 36098558 : && (reversed = reversed_comparison (op1, mode)))
3641 : return reversed;
3642 :
3643 : /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A). */
3644 35890553 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3645 35889202 : && GET_CODE (op1) == MULT
3646 36146753 : && GET_CODE (XEXP (op1, 0)) == NEG)
3647 : {
3648 173 : rtx in1, in2;
3649 :
3650 173 : in1 = XEXP (XEXP (op1, 0), 0);
3651 173 : in2 = XEXP (op1, 1);
3652 173 : return simplify_gen_binary (PLUS, mode,
3653 : simplify_gen_binary (MULT, mode,
3654 : in1, in2),
3655 173 : op0);
3656 : }
3657 :
3658 : /* Canonicalize (minus (neg A) (mult B C)) to
3659 : (minus (mult (neg B) C) A). */
3660 35890380 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3661 35889029 : && GET_CODE (op1) == MULT
3662 36146407 : && GET_CODE (op0) == NEG)
3663 : {
3664 675 : rtx in1, in2;
3665 :
3666 675 : in1 = simplify_gen_unary (NEG, mode, XEXP (op1, 0), mode);
3667 675 : in2 = XEXP (op1, 1);
3668 675 : return simplify_gen_binary (MINUS, mode,
3669 : simplify_gen_binary (MULT, mode,
3670 : in1, in2),
3671 675 : XEXP (op0, 0));
3672 : }
3673 :
3674 : /* If one of the operands is a PLUS or a MINUS, see if we can
3675 : simplify this by the associative law. This will, for example,
3676 : canonicalize (minus A (plus B C)) to (minus (minus A B) C).
3677 : Don't use the associative law for floating point.
3678 : The inaccuracy makes it nonassociative,
3679 : and subtle programs can break if operations are associated. */
3680 :
3681 35889705 : if (INTEGRAL_MODE_P (mode)
3682 35034686 : && (plus_minus_operand_p (op0)
3683 32125746 : || plus_minus_operand_p (op1))
3684 4150082 : && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
3685 : return tem;
3686 :
3687 : /* Handle vector series. */
3688 31889269 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3689 : {
3690 508196 : tem = simplify_binary_operation_series (code, mode, op0, op1);
3691 508196 : if (tem)
3692 : return tem;
3693 : }
3694 : break;
3695 :
3696 12795396 : case MULT:
3697 12795396 : if (trueop1 == constm1_rtx)
3698 34968 : return simplify_gen_unary (NEG, mode, op0, mode);
3699 :
3700 12760428 : if (GET_CODE (op0) == NEG)
3701 : {
3702 40694 : rtx temp = simplify_unary_operation (NEG, mode, op1, mode);
3703 : /* If op1 is a MULT as well and simplify_unary_operation
3704 : just moved the NEG to the second operand, simplify_gen_binary
3705 : below could through simplify_associative_operation move
3706 : the NEG around again and recurse endlessly. */
3707 40694 : if (temp
3708 1977 : && GET_CODE (op1) == MULT
3709 0 : && GET_CODE (temp) == MULT
3710 0 : && XEXP (op1, 0) == XEXP (temp, 0)
3711 0 : && GET_CODE (XEXP (temp, 1)) == NEG
3712 0 : && XEXP (op1, 1) == XEXP (XEXP (temp, 1), 0))
3713 : temp = NULL_RTX;
3714 : if (temp)
3715 1977 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp);
3716 : }
3717 12758451 : if (GET_CODE (op1) == NEG)
3718 : {
3719 906 : rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
3720 : /* If op0 is a MULT as well and simplify_unary_operation
3721 : just moved the NEG to the second operand, simplify_gen_binary
3722 : below could through simplify_associative_operation move
3723 : the NEG around again and recurse endlessly. */
3724 906 : if (temp
3725 413 : && GET_CODE (op0) == MULT
3726 302 : && GET_CODE (temp) == MULT
3727 302 : && XEXP (op0, 0) == XEXP (temp, 0)
3728 6 : && GET_CODE (XEXP (temp, 1)) == NEG
3729 5 : && XEXP (op0, 1) == XEXP (XEXP (temp, 1), 0))
3730 : temp = NULL_RTX;
3731 : if (temp)
3732 408 : return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
3733 : }
3734 :
3735 : /* Maybe simplify x * 0 to 0. The reduction is not valid if
3736 : x is NaN, since x * 0 is then also NaN. Nor is it valid
3737 : when the mode has signed zeros, since multiplying a negative
3738 : number by 0 will give -0, not 0. */
3739 12758043 : if (!HONOR_NANS (mode)
3740 11775390 : && !HONOR_SIGNED_ZEROS (mode)
3741 11774974 : && trueop1 == CONST0_RTX (mode)
3742 12802194 : && ! side_effects_p (op0))
3743 : return op1;
3744 :
3745 : /* In IEEE floating point, x*1 is not equivalent to x for
3746 : signalling NaNs. */
3747 12714307 : if (!HONOR_SNANS (mode)
3748 12714307 : && trueop1 == CONST1_RTX (mode))
3749 : return op0;
3750 :
3751 : /* Convert multiply by constant power of two into shift. */
3752 12186455 : if (mem_depth == 0 && CONST_SCALAR_INT_P (trueop1))
3753 : {
3754 6233236 : val = wi::exact_log2 (rtx_mode_t (trueop1, mode));
3755 6233236 : if (val >= 0)
3756 2938998 : return simplify_gen_binary (ASHIFT, mode, op0,
3757 2938998 : gen_int_shift_amount (mode, val));
3758 : }
3759 :
3760 : /* x*2 is x+x and x*(-1) is -x */
3761 9247457 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
3762 171735 : && SCALAR_FLOAT_MODE_P (GET_MODE (trueop1))
3763 171735 : && !DECIMAL_FLOAT_MODE_P (GET_MODE (trueop1))
3764 171451 : && GET_MODE (op0) == mode)
3765 : {
3766 171451 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
3767 :
3768 171451 : if (real_equal (d1, &dconst2))
3769 682 : return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
3770 :
3771 170769 : if (!HONOR_SNANS (mode)
3772 170769 : && real_equal (d1, &dconstm1))
3773 25 : return simplify_gen_unary (NEG, mode, op0, mode);
3774 : }
3775 :
3776 : /* Optimize -x * -x as x * x. */
3777 9246750 : if (FLOAT_MODE_P (mode)
3778 1407474 : && GET_CODE (op0) == NEG
3779 8307 : && GET_CODE (op1) == NEG
3780 0 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3781 0 : && !side_effects_p (XEXP (op0, 0)))
3782 0 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3783 :
3784 : /* Likewise, optimize abs(x) * abs(x) as x * x. */
3785 9246750 : if (SCALAR_FLOAT_MODE_P (mode)
3786 1101618 : && GET_CODE (op0) == ABS
3787 1468 : && GET_CODE (op1) == ABS
3788 1 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3789 9246750 : && !side_effects_p (XEXP (op0, 0)))
3790 0 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3791 :
3792 : /* Reassociate multiplication, but for floating point MULTs
3793 : only when the user specifies unsafe math optimizations. */
3794 9246750 : if (! FLOAT_MODE_P (mode)
3795 1407474 : || flag_unsafe_math_optimizations)
3796 : {
3797 8265210 : tem = simplify_associative_operation (code, mode, op0, op1);
3798 8265210 : if (tem)
3799 : return tem;
3800 : }
3801 : break;
3802 :
3803 15349891 : case IOR:
3804 15349891 : if (trueop1 == CONST0_RTX (mode))
3805 : return op0;
3806 14518178 : if (INTEGRAL_MODE_P (mode)
3807 14242636 : && trueop1 == CONSTM1_RTX (mode)
3808 10156 : && !side_effects_p (op0))
3809 : return op1;
3810 14508022 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
3811 : return op0;
3812 : /* A | (~A) -> -1 */
3813 71131 : if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
3814 14487955 : || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
3815 2 : && ! side_effects_p (op0)
3816 14487959 : && GET_MODE_CLASS (mode) != MODE_CC)
3817 2 : return CONSTM1_RTX (mode);
3818 :
3819 : /* IOR of two single bit bitfields extracted from the same object.
3820 : Bitfields are represented as an AND based extraction */
3821 14487955 : if (GET_CODE (op0) == AND
3822 4034293 : && GET_CODE (op1) == AND
3823 : /* Verify both AND operands are logical right shifts. */
3824 279036 : && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
3825 1737 : && GET_CODE (XEXP (op1, 0)) == LSHIFTRT
3826 : /* Verify both bitfields are extracted from the same object. */
3827 90 : && XEXP (XEXP (op0, 0), 0) == XEXP (XEXP (op1, 0), 0)
3828 : /* Verify both fields are a single bit (could be generalized). */
3829 86 : && XEXP (op0, 1) == CONST1_RTX (mode)
3830 0 : && XEXP (op1, 1) == CONST1_RTX (mode)
3831 : /* Verify bit positions (for cases with variable bit position). */
3832 0 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
3833 0 : && CONST_INT_P (XEXP (XEXP (op1, 0), 1)))
3834 : {
3835 0 : unsigned HOST_WIDE_INT bitpos1 = INTVAL (XEXP (XEXP (op0, 0), 1));
3836 0 : unsigned HOST_WIDE_INT bitpos2 = INTVAL (XEXP (XEXP (op1, 0), 1));
3837 0 : unsigned HOST_WIDE_INT mask
3838 0 : = (HOST_WIDE_INT_1U << bitpos1) | (HOST_WIDE_INT_1U << bitpos2);
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 : /* IOR of multiple single bit bitfields extracted from the same object
3847 : (building on previous case).
3848 : First bitfield is represented as an AND based extraction, as done
3849 : above. Second represented as NE based extraction, from
3850 : output above. */
3851 14487955 : if (GET_CODE (op0) == AND
3852 4034293 : && GET_CODE (op1) == NE
3853 : /* Verify AND operand is logical right shift. */
3854 3321 : && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
3855 : /* Verify NE operand is an AND (based on output above). */
3856 86 : && GET_CODE (XEXP (op1, 0)) == AND
3857 : /* Verify both bitfields are extracted from the same object. */
3858 0 : && XEXP (XEXP (op0, 0), 0) == XEXP (XEXP (op1, 0), 0)
3859 : /* Verify masking is with a single bit and that we have a NE 0
3860 : comparison for the other operand. */
3861 0 : && XEXP (op0, 1) == CONST1_RTX (mode)
3862 0 : && XEXP (op1, 1) == CONST0_RTX (mode)
3863 : /* Verify bit position. */
3864 0 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
3865 : {
3866 0 : unsigned HOST_WIDE_INT bitpos1 = INTVAL (XEXP (XEXP (op0, 0), 1));
3867 0 : unsigned HOST_WIDE_INT mask
3868 0 : = (HOST_WIDE_INT_1U << bitpos1) | INTVAL (XEXP (XEXP (op1, 0), 1));
3869 :
3870 0 : rtx m = GEN_INT (mask);
3871 0 : rtx t = gen_rtx_AND (mode, XEXP (XEXP (op0, 0), 0), m);
3872 0 : t = gen_rtx_NE (mode, t, CONST0_RTX (mode));
3873 0 : return t;
3874 : }
3875 :
3876 : /* Convert (ior (plus (A - 1)) (neg A)) to -1. */
3877 14487955 : if (match_plus_neg_pattern (op0, op1, mode))
3878 0 : return CONSTM1_RTX (mode);
3879 :
3880 : /* (ior A C) is C if all bits of A that might be nonzero are on in C. */
3881 14487955 : if (CONST_INT_P (op1)
3882 3613361 : && HWI_COMPUTABLE_MODE_P (mode)
3883 3558267 : && (nonzero_bits (op0, mode) & ~UINTVAL (op1)) == 0
3884 14895705 : && !side_effects_p (op0))
3885 : return op1;
3886 :
3887 : /* Canonicalize (X & C1) | C2. */
3888 14080205 : if (GET_CODE (op0) == AND
3889 4025324 : && CONST_INT_P (trueop1)
3890 653999 : && CONST_INT_P (XEXP (op0, 1)))
3891 : {
3892 486825 : HOST_WIDE_INT mask = GET_MODE_MASK (mode);
3893 486825 : HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
3894 486825 : HOST_WIDE_INT c2 = INTVAL (trueop1);
3895 :
3896 : /* If (C1&C2) == C1, then (X&C1)|C2 becomes C2. */
3897 486825 : if ((c1 & c2) == c1
3898 486825 : && !side_effects_p (XEXP (op0, 0)))
3899 : return trueop1;
3900 :
3901 : /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2. */
3902 486805 : if (((c1|c2) & mask) == mask)
3903 70852 : return simplify_gen_binary (IOR, mode, XEXP (op0, 0), op1);
3904 :
3905 : /* If (C1|C2) has a single bit clear, then adjust C1 so that
3906 : when split it'll match a single bit clear style insn.
3907 :
3908 : This could have been done with a target dependent splitter, but
3909 : then every target with single bit manipulation insns would need
3910 : to implement such splitters. */
3911 415953 : if (exact_log2 (~(c1 | c2)) >= 0)
3912 : {
3913 61161 : rtx temp = gen_rtx_AND (mode, XEXP (op0, 0), GEN_INT (c1 | c2));
3914 61161 : temp = gen_rtx_IOR (mode, temp, trueop1);
3915 61161 : return temp;
3916 : }
3917 : }
3918 :
3919 : /* Convert (A & B) | A to A. */
3920 13948172 : if (GET_CODE (op0) == AND
3921 3893291 : && (rtx_equal_p (XEXP (op0, 0), op1)
3922 3892804 : || rtx_equal_p (XEXP (op0, 1), op1))
3923 3690 : && ! side_effects_p (XEXP (op0, 0))
3924 13951862 : && ! side_effects_p (XEXP (op0, 1)))
3925 : return op1;
3926 :
3927 : /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3928 : mode size to (rotate A CX). */
3929 13944482 : tem = simplify_rotate_op (op0, op1, mode);
3930 13944482 : if (tem)
3931 : return tem;
3932 :
3933 : /* If OP0 is (ashiftrt (plus ...) C), it might actually be
3934 : a (sign_extend (plus ...)). Then check if OP1 is a CONST_INT and
3935 : the PLUS does not affect any of the bits in OP1: then we can do
3936 : the IOR as a PLUS and we can associate. This is valid if OP1
3937 : can be safely shifted left C bits. */
3938 13942236 : if (CONST_INT_P (trueop1) && GET_CODE (op0) == ASHIFTRT
3939 6616 : && GET_CODE (XEXP (op0, 0)) == PLUS
3940 141 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
3941 87 : && CONST_INT_P (XEXP (op0, 1))
3942 87 : && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
3943 : {
3944 87 : int count = INTVAL (XEXP (op0, 1));
3945 87 : HOST_WIDE_INT mask = UINTVAL (trueop1) << count;
3946 :
3947 87 : if (mask >> count == INTVAL (trueop1)
3948 80 : && trunc_int_for_mode (mask, mode) == mask
3949 154 : && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
3950 0 : return simplify_gen_binary (ASHIFTRT, mode,
3951 : plus_constant (mode, XEXP (op0, 0),
3952 0 : mask),
3953 : XEXP (op0, 1));
3954 : }
3955 :
3956 : /* The following happens with bitfield merging.
3957 : (X & C) | ((X | Y) & ~C) -> X | (Y & ~C) */
3958 13942236 : if (GET_CODE (op0) == AND
3959 3889601 : && GET_CODE (op1) == AND
3960 279036 : && CONST_INT_P (XEXP (op0, 1))
3961 121570 : && CONST_INT_P (XEXP (op1, 1))
3962 117150 : && (INTVAL (XEXP (op0, 1))
3963 117150 : == ~INTVAL (XEXP (op1, 1))))
3964 : {
3965 : /* The IOR/XOR may be on both sides. */
3966 33479 : rtx top0 = NULL_RTX, top1 = NULL_RTX;
3967 33479 : if (GET_CODE (XEXP (op1, 0)) == IOR
3968 33479 : || GET_CODE (XEXP (op1, 0)) == XOR)
3969 : top0 = op0, top1 = op1;
3970 33360 : else if (GET_CODE (XEXP (op0, 0)) == IOR
3971 33360 : || GET_CODE (XEXP (op0, 0)) == XOR)
3972 3 : top0 = op1, top1 = op0;
3973 33479 : if (top0 && top1)
3974 : {
3975 : /* X may be on either side of the inner IOR/XOR. */
3976 122 : rtx tem = NULL_RTX;
3977 122 : if (rtx_equal_p (XEXP (top0, 0),
3978 122 : XEXP (XEXP (top1, 0), 0)))
3979 76 : tem = XEXP (XEXP (top1, 0), 1);
3980 46 : else if (rtx_equal_p (XEXP (top0, 0),
3981 46 : XEXP (XEXP (top1, 0), 1)))
3982 13 : tem = XEXP (XEXP (top1, 0), 0);
3983 89 : if (tem)
3984 89 : return simplify_gen_binary (GET_CODE (XEXP (top1, 0)),
3985 : mode, XEXP (top0, 0),
3986 : simplify_gen_binary
3987 89 : (AND, mode, tem, XEXP (top1, 1)));
3988 : }
3989 : }
3990 :
3991 : /* Convert (ior (and A C) (and B C)) into (and (ior A B) C). */
3992 13942147 : if (GET_CODE (op0) == GET_CODE (op1)
3993 3442863 : && (GET_CODE (op0) == AND
3994 : || GET_CODE (op0) == IOR
3995 3442863 : || GET_CODE (op0) == LSHIFTRT
3996 3162962 : || GET_CODE (op0) == ASHIFTRT
3997 3162827 : || GET_CODE (op0) == ASHIFT
3998 3146749 : || GET_CODE (op0) == ROTATE
3999 3146749 : || GET_CODE (op0) == ROTATERT))
4000 : {
4001 296114 : tem = simplify_distributive_operation (code, mode, op0, op1);
4002 296114 : if (tem)
4003 : return tem;
4004 : }
4005 :
4006 : /* Convert (ior (and (not A) B) A) into A | B. */
4007 13859335 : if (GET_CODE (op0) == AND
4008 13859335 : && negated_ops_p (XEXP (op0, 0), op1))
4009 6294 : return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
4010 :
4011 : /* op0/op1 may have a common term which in turn may allow simplification
4012 : of the the outer IOR. There are likely other cases we should
4013 : handle for the outer code as well as the form of the operands. */
4014 13853041 : tem = simplify_ior_with_common_term (mode, op0, op1);
4015 13853041 : if (tem)
4016 : return tem;
4017 :
4018 : /* IOR is commutative and we can't rely on canonicalization at this point,
4019 : so try again to simplify with the operands reversed. */
4020 13852950 : tem = simplify_ior_with_common_term (mode, op1, op0);
4021 13852950 : if (tem)
4022 : return tem;
4023 :
4024 13852950 : tem = simplify_with_subreg_not (code, mode, op0, op1);
4025 13852950 : if (tem)
4026 : return tem;
4027 :
4028 13852945 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
4029 13852945 : if (tem)
4030 : return tem;
4031 :
4032 13852912 : tem = simplify_associative_operation (code, mode, op0, op1);
4033 13852912 : if (tem)
4034 : return tem;
4035 :
4036 13574845 : tem = simplify_logical_relational_operation (code, mode, op0, op1);
4037 13574845 : if (tem)
4038 : return tem;
4039 : break;
4040 :
4041 1845959 : case XOR:
4042 1845959 : if (trueop1 == CONST0_RTX (mode))
4043 : return op0;
4044 1787066 : if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
4045 30956 : return simplify_gen_unary (NOT, mode, op0, mode);
4046 1756110 : if (rtx_equal_p (trueop0, trueop1)
4047 2641 : && ! side_effects_p (op0)
4048 1758747 : && GET_MODE_CLASS (mode) != MODE_CC)
4049 2637 : return CONST0_RTX (mode);
4050 :
4051 : /* Canonicalize XOR of the most significant bit to PLUS. */
4052 1753473 : if (CONST_SCALAR_INT_P (op1)
4053 1753473 : && mode_signbit_p (mode, op1))
4054 40293 : return simplify_gen_binary (PLUS, mode, op0, op1);
4055 : /* (xor (plus X C1) C2) is (xor X (C1^C2)) if C1 is signbit. */
4056 1713180 : if (CONST_SCALAR_INT_P (op1)
4057 492833 : && GET_CODE (op0) == PLUS
4058 2583 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
4059 1714700 : && mode_signbit_p (mode, XEXP (op0, 1)))
4060 189 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
4061 : simplify_gen_binary (XOR, mode, op1,
4062 189 : XEXP (op0, 1)));
4063 :
4064 : /* If we are XORing two things that have no bits in common,
4065 : convert them into an IOR. This helps to detect rotation encoded
4066 : using those methods and possibly other simplifications. */
4067 :
4068 1712991 : if (HWI_COMPUTABLE_MODE_P (mode)
4069 1388905 : && (nonzero_bits (op0, mode)
4070 1388905 : & nonzero_bits (op1, mode)) == 0)
4071 11888 : return (simplify_gen_binary (IOR, mode, op0, op1));
4072 :
4073 : /* Convert (xor (plus (A - 1)) (neg A)) to -1. */
4074 1701103 : if (match_plus_neg_pattern (op0, op1, mode))
4075 0 : return CONSTM1_RTX (mode);
4076 :
4077 : /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
4078 : Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
4079 : (NOT y). */
4080 1701103 : {
4081 1701103 : int num_negated = 0;
4082 :
4083 1701103 : if (GET_CODE (op0) == NOT)
4084 720 : num_negated++, op0 = XEXP (op0, 0);
4085 1701103 : if (GET_CODE (op1) == NOT)
4086 65 : num_negated++, op1 = XEXP (op1, 0);
4087 :
4088 65 : if (num_negated == 2)
4089 0 : return simplify_gen_binary (XOR, mode, op0, op1);
4090 1701103 : else if (num_negated == 1)
4091 785 : return simplify_gen_unary (NOT, mode,
4092 : simplify_gen_binary (XOR, mode, op0, op1),
4093 785 : mode);
4094 : }
4095 :
4096 : /* Convert (xor (and A B) B) to (and (not A) B). The latter may
4097 : correspond to a machine insn or result in further simplifications
4098 : if B is a constant. */
4099 :
4100 1700318 : if (GET_CODE (op0) == AND
4101 192368 : && rtx_equal_p (XEXP (op0, 1), op1)
4102 1723150 : && ! side_effects_p (op1))
4103 22832 : return simplify_gen_binary (AND, mode,
4104 : simplify_gen_unary (NOT, mode,
4105 : XEXP (op0, 0), mode),
4106 22832 : op1);
4107 :
4108 1677486 : else if (GET_CODE (op0) == AND
4109 169536 : && rtx_equal_p (XEXP (op0, 0), op1)
4110 1679577 : && ! side_effects_p (op1))
4111 2091 : return simplify_gen_binary (AND, mode,
4112 : simplify_gen_unary (NOT, mode,
4113 : XEXP (op0, 1), mode),
4114 2091 : op1);
4115 :
4116 : /* Given (xor (ior (xor A B) C) D), where B, C and D are
4117 : constants, simplify to (xor (ior A C) (B&~C)^D), canceling
4118 : out bits inverted twice and not set by C. Similarly, given
4119 : (xor (and (xor A B) C) D), simplify without inverting C in
4120 : the xor operand: (xor (and A C) (B&C)^D).
4121 : */
4122 1675395 : else if ((GET_CODE (op0) == IOR || GET_CODE (op0) == AND)
4123 191401 : && GET_CODE (XEXP (op0, 0)) == XOR
4124 7607 : && CONST_INT_P (op1)
4125 210 : && CONST_INT_P (XEXP (op0, 1))
4126 179 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
4127 : {
4128 38 : enum rtx_code op = GET_CODE (op0);
4129 38 : rtx a = XEXP (XEXP (op0, 0), 0);
4130 38 : rtx b = XEXP (XEXP (op0, 0), 1);
4131 38 : rtx c = XEXP (op0, 1);
4132 38 : rtx d = op1;
4133 38 : HOST_WIDE_INT bval = INTVAL (b);
4134 38 : HOST_WIDE_INT cval = INTVAL (c);
4135 38 : HOST_WIDE_INT dval = INTVAL (d);
4136 38 : HOST_WIDE_INT xcval;
4137 :
4138 38 : if (op == IOR)
4139 8 : xcval = ~cval;
4140 : else
4141 : xcval = cval;
4142 :
4143 38 : return simplify_gen_binary (XOR, mode,
4144 : simplify_gen_binary (op, mode, a, c),
4145 38 : gen_int_mode ((bval & xcval) ^ dval,
4146 : mode));
4147 : }
4148 :
4149 : /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P),
4150 : we can transform like this:
4151 : (A&B)^C == ~(A&B)&C | ~C&(A&B)
4152 : == (~A|~B)&C | ~C&(A&B) * DeMorgan's Law
4153 : == ~A&C | ~B&C | A&(~C&B) * Distribute and re-order
4154 : Attempt a few simplifications when B and C are both constants. */
4155 1675357 : if (GET_CODE (op0) == AND
4156 167415 : && CONST_INT_P (op1)
4157 13988 : && CONST_INT_P (XEXP (op0, 1)))
4158 : {
4159 11474 : rtx a = XEXP (op0, 0);
4160 11474 : rtx b = XEXP (op0, 1);
4161 11474 : rtx c = op1;
4162 11474 : HOST_WIDE_INT bval = INTVAL (b);
4163 11474 : HOST_WIDE_INT cval = INTVAL (c);
4164 :
4165 : /* Instead of computing ~A&C, we compute its negated value,
4166 : ~(A|~C). If it yields -1, ~A&C is zero, so we can
4167 : optimize for sure. If it does not simplify, we still try
4168 : to compute ~A&C below, but since that always allocates
4169 : RTL, we don't try that before committing to returning a
4170 : simplified expression. */
4171 11474 : rtx n_na_c = simplify_binary_operation (IOR, mode, a,
4172 : GEN_INT (~cval));
4173 :
4174 11474 : if ((~cval & bval) == 0)
4175 : {
4176 828 : rtx na_c = NULL_RTX;
4177 828 : if (n_na_c)
4178 0 : na_c = simplify_gen_unary (NOT, mode, n_na_c, mode);
4179 : else
4180 : {
4181 : /* If ~A does not simplify, don't bother: we don't
4182 : want to simplify 2 operations into 3, and if na_c
4183 : were to simplify with na, n_na_c would have
4184 : simplified as well. */
4185 828 : rtx na = simplify_unary_operation (NOT, mode, a, mode);
4186 828 : if (na)
4187 0 : na_c = simplify_gen_binary (AND, mode, na, c);
4188 : }
4189 :
4190 : /* Try to simplify ~A&C | ~B&C. */
4191 0 : if (na_c != NULL_RTX)
4192 0 : return simplify_gen_binary (IOR, mode, na_c,
4193 0 : gen_int_mode (~bval & cval, mode));
4194 : }
4195 : else
4196 : {
4197 : /* If ~A&C is zero, simplify A&(~C&B) | ~B&C. */
4198 10646 : if (n_na_c == CONSTM1_RTX (mode))
4199 : {
4200 0 : rtx a_nc_b = simplify_gen_binary (AND, mode, a,
4201 0 : gen_int_mode (~cval & bval,
4202 : mode));
4203 0 : return simplify_gen_binary (IOR, mode, a_nc_b,
4204 0 : gen_int_mode (~bval & cval,
4205 : mode));
4206 : }
4207 : }
4208 : }
4209 :
4210 : /* If we have (xor (and (xor A B) C) A) with C a constant we can instead
4211 : do (ior (and A ~C) (and B C)) which is a machine instruction on some
4212 : machines, and also has shorter instruction path length. */
4213 1675357 : if (GET_CODE (op0) == AND
4214 167415 : && GET_CODE (XEXP (op0, 0)) == XOR
4215 7119 : && CONST_INT_P (XEXP (op0, 1))
4216 1679191 : && rtx_equal_p (XEXP (XEXP (op0, 0), 0), trueop1))
4217 : {
4218 7 : rtx a = trueop1;
4219 7 : rtx b = XEXP (XEXP (op0, 0), 1);
4220 7 : rtx c = XEXP (op0, 1);
4221 7 : rtx nc = simplify_gen_unary (NOT, mode, c, mode);
4222 7 : rtx a_nc = simplify_gen_binary (AND, mode, a, nc);
4223 7 : rtx bc = simplify_gen_binary (AND, mode, b, c);
4224 7 : return simplify_gen_binary (IOR, mode, a_nc, bc);
4225 : }
4226 : /* Similarly, (xor (and (xor A B) C) B) as (ior (and A C) (and B ~C)) */
4227 1675350 : else if (GET_CODE (op0) == AND
4228 167408 : && GET_CODE (XEXP (op0, 0)) == XOR
4229 7112 : && CONST_INT_P (XEXP (op0, 1))
4230 1679177 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), trueop1))
4231 : {
4232 8 : rtx a = XEXP (XEXP (op0, 0), 0);
4233 8 : rtx b = trueop1;
4234 8 : rtx c = XEXP (op0, 1);
4235 8 : rtx nc = simplify_gen_unary (NOT, mode, c, mode);
4236 8 : rtx b_nc = simplify_gen_binary (AND, mode, b, nc);
4237 8 : rtx ac = simplify_gen_binary (AND, mode, a, c);
4238 8 : return simplify_gen_binary (IOR, mode, ac, b_nc);
4239 : }
4240 :
4241 : /* (xor (comparison foo bar) (const_int 1)) can become the reversed
4242 : comparison if STORE_FLAG_VALUE is 1. */
4243 1675342 : if (STORE_FLAG_VALUE == 1
4244 1675342 : && trueop1 == const1_rtx
4245 208392 : && COMPARISON_P (op0)
4246 1681959 : && (reversed = reversed_comparison (op0, mode)))
4247 : return reversed;
4248 :
4249 : /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
4250 : is (lt foo (const_int 0)), so we can perform the above
4251 : simplification if STORE_FLAG_VALUE is 1. */
4252 :
4253 1668733 : if (is_a <scalar_int_mode> (mode, &int_mode)
4254 : && STORE_FLAG_VALUE == 1
4255 1349216 : && trueop1 == const1_rtx
4256 201783 : && GET_CODE (op0) == LSHIFTRT
4257 36074 : && CONST_INT_P (XEXP (op0, 1))
4258 36074 : && INTVAL (XEXP (op0, 1)) == GET_MODE_PRECISION (int_mode) - 1)
4259 34949 : return gen_rtx_GE (int_mode, XEXP (op0, 0), const0_rtx);
4260 :
4261 : /* (xor (comparison foo bar) (const_int sign-bit))
4262 : when STORE_FLAG_VALUE is the sign bit. */
4263 1633784 : if (is_a <scalar_int_mode> (mode, &int_mode)
4264 1314267 : && val_signbit_p (int_mode, STORE_FLAG_VALUE)
4265 0 : && trueop1 == const_true_rtx
4266 0 : && COMPARISON_P (op0)
4267 0 : && (reversed = reversed_comparison (op0, int_mode)))
4268 : return reversed;
4269 :
4270 : /* Convert (xor (and A C) (and B C)) into (and (xor A B) C). */
4271 1633784 : if (GET_CODE (op0) == GET_CODE (op1)
4272 568920 : && (GET_CODE (op0) == AND
4273 568920 : || GET_CODE (op0) == LSHIFTRT
4274 491573 : || GET_CODE (op0) == ASHIFTRT
4275 491473 : || GET_CODE (op0) == ASHIFT
4276 491345 : || GET_CODE (op0) == ROTATE
4277 491203 : || GET_CODE (op0) == ROTATERT))
4278 : {
4279 78251 : tem = simplify_distributive_operation (code, mode, op0, op1);
4280 78251 : if (tem)
4281 : return tem;
4282 : }
4283 :
4284 : /* Convert (xor (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
4285 : mode size to (rotate A CX). */
4286 1559286 : tem = simplify_rotate_op (op0, op1, mode);
4287 1559286 : if (tem)
4288 : return tem;
4289 :
4290 : /* Convert (xor (and (not A) B) A) into A | B. */
4291 1557906 : if (GET_CODE (op0) == AND
4292 1557906 : && negated_ops_p (XEXP (op0, 0), op1))
4293 0 : return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
4294 :
4295 : /* Convert (xor (and (rotate (~1) A) B) (ashift 1 A))
4296 : into B | (1 << A). */
4297 1557906 : if (SHIFT_COUNT_TRUNCATED
4298 : && GET_CODE (op0) == AND
4299 : && GET_CODE (XEXP (op0, 0)) == ROTATE
4300 : && CONST_INT_P (XEXP (XEXP (op0, 0), 0))
4301 : && INTVAL (XEXP (XEXP (op0, 0), 0)) == -2
4302 : && GET_CODE (op1) == ASHIFT
4303 : && CONST_INT_P (XEXP (op1, 0))
4304 : && INTVAL (XEXP (op1, 0)) == 1
4305 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), XEXP (op1, 1))
4306 : && !side_effects_p (XEXP (op1, 1)))
4307 : return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
4308 :
4309 1557906 : tem = simplify_with_subreg_not (code, mode, op0, op1);
4310 1557906 : if (tem)
4311 : return tem;
4312 :
4313 1557905 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
4314 1557905 : if (tem)
4315 : return tem;
4316 :
4317 1557905 : tem = simplify_associative_operation (code, mode, op0, op1);
4318 1557905 : if (tem)
4319 : return tem;
4320 : break;
4321 :
4322 24535039 : case AND:
4323 24535039 : if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
4324 : return trueop1;
4325 24252750 : if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
4326 : return op0;
4327 23865795 : if (HWI_COMPUTABLE_MODE_P (mode))
4328 : {
4329 : /* When WORD_REGISTER_OPERATIONS is true, we need to know the
4330 : nonzero bits in WORD_MODE rather than MODE. */
4331 20908385 : scalar_int_mode tmode = as_a <scalar_int_mode> (mode);
4332 20908385 : if (WORD_REGISTER_OPERATIONS
4333 : && GET_MODE_BITSIZE (tmode) < BITS_PER_WORD)
4334 : tmode = word_mode;
4335 20908385 : HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, tmode);
4336 20908385 : HOST_WIDE_INT nzop1;
4337 20908385 : if (CONST_INT_P (trueop1))
4338 : {
4339 17847448 : HOST_WIDE_INT val1 = INTVAL (trueop1);
4340 : /* If we are turning off bits already known off in OP0, we need
4341 : not do an AND. */
4342 17847448 : if ((nzop0 & ~val1) == 0)
4343 432424 : return op0;
4344 :
4345 : /* Canonicalize (and (subreg (lshiftrt X shift)) mask) into
4346 : (and (lshiftrt (subreg X) shift) mask).
4347 :
4348 : Keeps shift and AND in the same mode, improving recognition.
4349 : Only applied when subreg is a lowpart, shift is valid,
4350 : and no precision is lost. */
4351 17502000 : if (SUBREG_P (op0)
4352 6231713 : && subreg_lowpart_p (op0)
4353 6214743 : && !paradoxical_subreg_p (op0)
4354 790293 : && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
4355 : /* simplify_subreg asserts the object being accessed is not
4356 : VOIDmode or BLKmode. We may have a REG_EQUAL note which
4357 : is not simplified and the source operand is a constant,
4358 : and thus VOIDmode. Guard against that. */
4359 117236 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) != VOIDmode
4360 117186 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) != BLKmode
4361 117186 : && !CONST_INT_P (XEXP (XEXP (op0, 0), 0))
4362 117186 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
4363 96107 : && INTVAL (XEXP (XEXP (op0, 0), 1)) >= 0
4364 96107 : && INTVAL (XEXP (XEXP (op0, 0), 1)) < HOST_BITS_PER_WIDE_INT
4365 17598106 : && ((INTVAL (XEXP (XEXP (op0, 0), 1))
4366 96106 : + floor_log2 (val1))
4367 17502000 : < GET_MODE_PRECISION (as_a <scalar_int_mode> (mode))))
4368 : {
4369 13372 : tem = XEXP (XEXP (op0, 0), 0);
4370 13372 : if (SUBREG_P (tem))
4371 : {
4372 288 : if (subreg_lowpart_p (tem))
4373 288 : tem = SUBREG_REG (tem);
4374 : else
4375 : tem = NULL_RTX;
4376 : }
4377 288 : if (tem != NULL_RTX)
4378 : {
4379 13372 : offset = subreg_lowpart_offset (mode, GET_MODE (tem));
4380 13372 : tem = simplify_gen_subreg (mode, tem, GET_MODE (tem),
4381 13372 : offset);
4382 13372 : if (tem)
4383 : {
4384 13372 : unsigned shiftamt = INTVAL (XEXP (XEXP (op0, 0), 1));
4385 13372 : rtx shiftamtrtx = gen_int_shift_amount (mode,
4386 13372 : shiftamt);
4387 13372 : op0 = simplify_gen_binary (LSHIFTRT, mode, tem,
4388 : shiftamtrtx);
4389 13372 : return simplify_gen_binary (AND, mode, op0, op1);
4390 : }
4391 : }
4392 : }
4393 : }
4394 20549565 : nzop1 = nonzero_bits (trueop1, mode);
4395 : /* If we are clearing all the nonzero bits, the result is zero. */
4396 20549565 : if ((nzop1 & nzop0) == 0
4397 20549565 : && !side_effects_p (op0) && !side_effects_p (op1))
4398 73604 : return CONST0_RTX (mode);
4399 : }
4400 23437859 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
4401 23437855 : && GET_MODE_CLASS (mode) != MODE_CC)
4402 : return op0;
4403 : /* A & (~A) -> 0 */
4404 591010 : if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
4405 23425778 : || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
4406 3155 : && ! side_effects_p (op0)
4407 23432041 : && GET_MODE_CLASS (mode) != MODE_CC)
4408 3154 : return CONST0_RTX (mode);
4409 :
4410 : /* Convert (and (plus (A - 1)) (neg A)) to 0. */
4411 23425733 : if (match_plus_neg_pattern (op0, op1, mode))
4412 2 : return CONST0_RTX (mode);
4413 :
4414 : /* Transform (and (extend X) C) into (zero_extend (and X C)) if
4415 : there are no nonzero bits of C outside of X's mode. */
4416 46851462 : if ((GET_CODE (op0) == SIGN_EXTEND
4417 23425731 : || GET_CODE (op0) == ZERO_EXTEND)
4418 94404 : && CONST_SCALAR_INT_P (trueop1)
4419 81202 : && is_a <scalar_int_mode> (mode, &int_mode)
4420 81202 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
4421 23506933 : && (wi::mask (GET_MODE_PRECISION (inner_mode), true,
4422 81202 : GET_MODE_PRECISION (int_mode))
4423 23506933 : & rtx_mode_t (trueop1, mode)) == 0)
4424 : {
4425 79229 : machine_mode imode = GET_MODE (XEXP (op0, 0));
4426 79229 : tem = immed_wide_int_const (rtx_mode_t (trueop1, mode), imode);
4427 79229 : tem = simplify_gen_binary (AND, imode, XEXP (op0, 0), tem);
4428 79229 : return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
4429 : }
4430 :
4431 : /* Transform (and (truncate X) C) into (truncate (and X C)). This way
4432 : we might be able to further simplify the AND with X and potentially
4433 : remove the truncation altogether. */
4434 23346502 : if (GET_CODE (op0) == TRUNCATE && CONST_INT_P (trueop1))
4435 : {
4436 6 : rtx x = XEXP (op0, 0);
4437 6 : machine_mode xmode = GET_MODE (x);
4438 6 : tem = simplify_gen_binary (AND, xmode, x,
4439 6 : gen_int_mode (INTVAL (trueop1), xmode));
4440 6 : return simplify_gen_unary (TRUNCATE, mode, tem, xmode);
4441 : }
4442 :
4443 : /* Canonicalize (A | C1) & C2 as (A & C2) | (C1 & C2). */
4444 23346496 : if (GET_CODE (op0) == IOR
4445 1390932 : && CONST_INT_P (trueop1)
4446 216235 : && CONST_INT_P (XEXP (op0, 1)))
4447 : {
4448 132409 : HOST_WIDE_INT tmp = INTVAL (trueop1) & INTVAL (XEXP (op0, 1));
4449 132409 : return simplify_gen_binary (IOR, mode,
4450 : simplify_gen_binary (AND, mode,
4451 : XEXP (op0, 0), op1),
4452 132409 : gen_int_mode (tmp, mode));
4453 : }
4454 :
4455 : /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
4456 : insn (and may simplify more). */
4457 23214087 : if (GET_CODE (op0) == XOR
4458 151693 : && rtx_equal_p (XEXP (op0, 0), op1)
4459 23215528 : && ! side_effects_p (op1))
4460 1441 : return simplify_gen_binary (AND, mode,
4461 : simplify_gen_unary (NOT, mode,
4462 : XEXP (op0, 1), mode),
4463 1441 : op1);
4464 :
4465 23212646 : if (GET_CODE (op0) == XOR
4466 150252 : && rtx_equal_p (XEXP (op0, 1), op1)
4467 23217424 : && ! side_effects_p (op1))
4468 4778 : return simplify_gen_binary (AND, mode,
4469 : simplify_gen_unary (NOT, mode,
4470 : XEXP (op0, 0), mode),
4471 4778 : op1);
4472 :
4473 : /* Similarly for (~(A ^ B)) & A. */
4474 23207868 : if (GET_CODE (op0) == NOT
4475 587902 : && GET_CODE (XEXP (op0, 0)) == XOR
4476 3893 : && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
4477 23207922 : && ! side_effects_p (op1))
4478 54 : return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
4479 :
4480 23207814 : if (GET_CODE (op0) == NOT
4481 587848 : && GET_CODE (XEXP (op0, 0)) == XOR
4482 3839 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
4483 23207851 : && ! side_effects_p (op1))
4484 37 : return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
4485 :
4486 : /* Convert (A | B) & A to A. */
4487 23207777 : if (GET_CODE (op0) == IOR
4488 1258523 : && (rtx_equal_p (XEXP (op0, 0), op1)
4489 1257996 : || rtx_equal_p (XEXP (op0, 1), op1))
4490 764 : && ! side_effects_p (XEXP (op0, 0))
4491 23208541 : && ! side_effects_p (XEXP (op0, 1)))
4492 : return op1;
4493 :
4494 : /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
4495 : ((A & N) + B) & M -> (A + B) & M
4496 : Similarly if (N & M) == 0,
4497 : ((A | N) + B) & M -> (A + B) & M
4498 : and for - instead of + and/or ^ instead of |.
4499 : Also, if (N & M) == 0, then
4500 : (A +- N) & M -> A & M. */
4501 23207013 : if (CONST_INT_P (trueop1)
4502 17297260 : && HWI_COMPUTABLE_MODE_P (mode)
4503 17275614 : && ~UINTVAL (trueop1)
4504 17275614 : && (UINTVAL (trueop1) & (UINTVAL (trueop1) + 1)) == 0
4505 34570505 : && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS))
4506 : {
4507 971138 : rtx pmop[2];
4508 971138 : int which;
4509 :
4510 971138 : pmop[0] = XEXP (op0, 0);
4511 971138 : pmop[1] = XEXP (op0, 1);
4512 :
4513 971138 : if (CONST_INT_P (pmop[1])
4514 486280 : && (UINTVAL (pmop[1]) & UINTVAL (trueop1)) == 0)
4515 168264 : return simplify_gen_binary (AND, mode, pmop[0], op1);
4516 :
4517 2431596 : for (which = 0; which < 2; which++)
4518 : {
4519 1621064 : tem = pmop[which];
4520 1621064 : switch (GET_CODE (tem))
4521 : {
4522 12117 : case AND:
4523 12117 : if (CONST_INT_P (XEXP (tem, 1))
4524 10631 : && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1))
4525 : == UINTVAL (trueop1))
4526 7651 : pmop[which] = XEXP (tem, 0);
4527 : break;
4528 1194 : case IOR:
4529 1194 : case XOR:
4530 1194 : if (CONST_INT_P (XEXP (tem, 1))
4531 168 : && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1)) == 0)
4532 7 : pmop[which] = XEXP (tem, 0);
4533 : break;
4534 : default:
4535 : break;
4536 : }
4537 : }
4538 :
4539 810532 : if (pmop[0] != XEXP (op0, 0) || pmop[1] != XEXP (op0, 1))
4540 : {
4541 7658 : tem = simplify_gen_binary (GET_CODE (op0), mode,
4542 : pmop[0], pmop[1]);
4543 7658 : return simplify_gen_binary (code, mode, tem, op1);
4544 : }
4545 : }
4546 :
4547 : /* (and X (ior (not X) Y) -> (and X Y) */
4548 23038749 : if (GET_CODE (op1) == IOR
4549 955340 : && GET_CODE (XEXP (op1, 0)) == NOT
4550 23043717 : && rtx_equal_p (op0, XEXP (XEXP (op1, 0), 0)))
4551 0 : return simplify_gen_binary (AND, mode, op0, XEXP (op1, 1));
4552 :
4553 : /* (and (ior (not X) Y) X) -> (and X Y) */
4554 23038749 : if (GET_CODE (op0) == IOR
4555 1257759 : && GET_CODE (XEXP (op0, 0)) == NOT
4556 23085972 : && rtx_equal_p (op1, XEXP (XEXP (op0, 0), 0)))
4557 6 : return simplify_gen_binary (AND, mode, op1, XEXP (op0, 1));
4558 :
4559 : /* (and X (ior Y (not X)) -> (and X Y) */
4560 23038743 : if (GET_CODE (op1) == IOR
4561 955340 : && GET_CODE (XEXP (op1, 1)) == NOT
4562 23039325 : && rtx_equal_p (op0, XEXP (XEXP (op1, 1), 0)))
4563 0 : return simplify_gen_binary (AND, mode, op0, XEXP (op1, 0));
4564 :
4565 : /* (and (ior Y (not X)) X) -> (and X Y) */
4566 23038743 : if (GET_CODE (op0) == IOR
4567 1257753 : && GET_CODE (XEXP (op0, 1)) == NOT
4568 23045573 : && rtx_equal_p (op1, XEXP (XEXP (op0, 1), 0)))
4569 78 : return simplify_gen_binary (AND, mode, op1, XEXP (op0, 0));
4570 :
4571 : /* (and (ior/xor X Y) (not Y)) -> X & ~Y */
4572 23038665 : if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
4573 23038665 : && negated_ops_p (op1, XEXP (op0, 1)))
4574 101 : return simplify_gen_binary (AND, mode, XEXP (op0, 0),
4575 : simplify_gen_unary (NOT, mode,
4576 : XEXP (op0, 1),
4577 101 : mode));
4578 : /* (and (ior/xor Y X) (not Y)) -> X & ~Y */
4579 23038564 : if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
4580 23038564 : && negated_ops_p (op1, XEXP (op0, 0)))
4581 2 : return simplify_gen_binary (AND, mode, XEXP (op0, 1),
4582 : simplify_gen_unary (NOT, mode,
4583 : XEXP (op0, 0),
4584 2 : mode));
4585 :
4586 : /* Convert (and (ior A C) (ior B C)) into (ior (and A B) C). */
4587 23038562 : if (GET_CODE (op0) == GET_CODE (op1)
4588 2215890 : && (GET_CODE (op0) == AND
4589 : || GET_CODE (op0) == IOR
4590 2215890 : || GET_CODE (op0) == LSHIFTRT
4591 1261057 : || GET_CODE (op0) == ASHIFTRT
4592 1260905 : || GET_CODE (op0) == ASHIFT
4593 1260736 : || GET_CODE (op0) == ROTATE
4594 1260736 : || GET_CODE (op0) == ROTATERT))
4595 : {
4596 955154 : tem = simplify_distributive_operation (code, mode, op0, op1);
4597 955154 : if (tem)
4598 : return tem;
4599 : }
4600 :
4601 : /* (and:v4si
4602 : (ashiftrt:v4si A 16)
4603 : (const_vector: 0xffff x4))
4604 : is just (lshiftrt:v4si A 16). */
4605 22128430 : if (VECTOR_MODE_P (mode) && GET_CODE (op0) == ASHIFTRT
4606 4860 : && (CONST_INT_P (XEXP (op0, 1))
4607 2035 : || (GET_CODE (XEXP (op0, 1)) == CONST_VECTOR
4608 94 : && const_vec_duplicate_p (XEXP (op0, 1))
4609 0 : && CONST_INT_P (XVECEXP (XEXP (op0, 1), 0, 0))))
4610 2825 : && GET_CODE (op1) == CONST_VECTOR
4611 22128464 : && const_vec_duplicate_p (op1)
4612 22128506 : && CONST_INT_P (XVECEXP (op1, 0, 0)))
4613 : {
4614 148 : unsigned HOST_WIDE_INT shift_count
4615 : = (CONST_INT_P (XEXP (op0, 1))
4616 74 : ? UINTVAL (XEXP (op0, 1))
4617 0 : : UINTVAL (XVECEXP (XEXP (op0, 1), 0, 0)));
4618 74 : unsigned HOST_WIDE_INT inner_prec
4619 148 : = GET_MODE_PRECISION (GET_MODE_INNER (mode));
4620 :
4621 : /* Avoid UD shift count. */
4622 74 : if (shift_count < inner_prec
4623 62 : && (UINTVAL (XVECEXP (op1, 0, 0))
4624 62 : == (HOST_WIDE_INT_1U << (inner_prec - shift_count)) - 1))
4625 42 : return simplify_gen_binary (LSHIFTRT, mode, XEXP (op0, 0), XEXP (op0, 1));
4626 : }
4627 :
4628 22128388 : tem = simplify_with_subreg_not (code, mode, op0, op1);
4629 22128388 : if (tem)
4630 : return tem;
4631 :
4632 22125893 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
4633 22125893 : if (tem)
4634 : return tem;
4635 :
4636 22125672 : tem = simplify_associative_operation (code, mode, op0, op1);
4637 22125672 : if (tem)
4638 : return tem;
4639 : break;
4640 :
4641 898722 : case UDIV:
4642 : /* 0/x is 0 (or x&0 if x has side-effects). */
4643 898722 : if (trueop0 == CONST0_RTX (mode)
4644 377 : && !cfun->can_throw_non_call_exceptions)
4645 : {
4646 377 : if (side_effects_p (op1))
4647 0 : return simplify_gen_binary (AND, mode, op1, trueop0);
4648 : return trueop0;
4649 : }
4650 : /* x/1 is x. */
4651 898345 : if (trueop1 == CONST1_RTX (mode))
4652 : {
4653 242062 : tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4654 242062 : if (tem)
4655 : return tem;
4656 : }
4657 : /* Convert divide by power of two into shift. */
4658 656283 : if (CONST_INT_P (trueop1)
4659 979027 : && (val = exact_log2 (UINTVAL (trueop1))) > 0)
4660 322744 : return simplify_gen_binary (LSHIFTRT, mode, op0,
4661 322744 : gen_int_shift_amount (mode, val));
4662 : break;
4663 :
4664 1424562 : case DIV:
4665 : /* Handle floating point and integers separately. */
4666 1424562 : if (SCALAR_FLOAT_MODE_P (mode))
4667 : {
4668 : /* Maybe change 0.0 / x to 0.0. This transformation isn't
4669 : safe for modes with NaNs, since 0.0 / 0.0 will then be
4670 : NaN rather than 0.0. Nor is it safe for modes with signed
4671 : zeros, since dividing 0 by a negative number gives -0.0 */
4672 327568 : if (trueop0 == CONST0_RTX (mode)
4673 2818 : && !HONOR_NANS (mode)
4674 14 : && !HONOR_SIGNED_ZEROS (mode)
4675 327582 : && ! side_effects_p (op1))
4676 : return op0;
4677 : /* x/1.0 is x. */
4678 327554 : if (trueop1 == CONST1_RTX (mode)
4679 327554 : && !HONOR_SNANS (mode))
4680 : return op0;
4681 :
4682 327550 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
4683 28230 : && trueop1 != CONST0_RTX (mode))
4684 : {
4685 22114 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
4686 :
4687 : /* x/-1.0 is -x. */
4688 22114 : if (real_equal (d1, &dconstm1)
4689 22114 : && !HONOR_SNANS (mode))
4690 0 : return simplify_gen_unary (NEG, mode, op0, mode);
4691 :
4692 : /* Change FP division by a constant into multiplication.
4693 : Only do this with -freciprocal-math. */
4694 22114 : if (flag_reciprocal_math
4695 22114 : && !real_equal (d1, &dconst0))
4696 : {
4697 7 : REAL_VALUE_TYPE d;
4698 7 : real_arithmetic (&d, RDIV_EXPR, &dconst1, d1);
4699 7 : tem = const_double_from_real_value (d, mode);
4700 7 : return simplify_gen_binary (MULT, mode, op0, tem);
4701 : }
4702 : }
4703 : }
4704 1096994 : else if (SCALAR_INT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
4705 : {
4706 : /* 0/x is 0 (or x&0 if x has side-effects). */
4707 1065489 : if (trueop0 == CONST0_RTX (mode)
4708 985 : && !cfun->can_throw_non_call_exceptions)
4709 : {
4710 931 : if (side_effects_p (op1))
4711 8 : return simplify_gen_binary (AND, mode, op1, trueop0);
4712 : return trueop0;
4713 : }
4714 : /* x/1 is x. */
4715 1064558 : if (trueop1 == CONST1_RTX (mode))
4716 : {
4717 85 : tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4718 85 : if (tem)
4719 : return tem;
4720 : }
4721 : /* x/-1 is -x. */
4722 1064473 : if (trueop1 == CONSTM1_RTX (mode))
4723 : {
4724 554 : rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4725 554 : if (x)
4726 554 : return simplify_gen_unary (NEG, mode, x, mode);
4727 : }
4728 : }
4729 : break;
4730 :
4731 918415 : case UMOD:
4732 : /* 0%x is 0 (or x&0 if x has side-effects). */
4733 918415 : if (trueop0 == CONST0_RTX (mode))
4734 : {
4735 933 : if (side_effects_p (op1))
4736 0 : return simplify_gen_binary (AND, mode, op1, trueop0);
4737 : return trueop0;
4738 : }
4739 : /* x%1 is 0 (of x&0 if x has side-effects). */
4740 917482 : if (trueop1 == CONST1_RTX (mode))
4741 : {
4742 274669 : if (side_effects_p (op0))
4743 0 : return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
4744 274669 : return CONST0_RTX (mode);
4745 : }
4746 : /* Implement modulus by power of two as AND. */
4747 642813 : if (CONST_INT_P (trueop1)
4748 938993 : && exact_log2 (UINTVAL (trueop1)) > 0)
4749 296180 : return simplify_gen_binary (AND, mode, op0,
4750 296180 : gen_int_mode (UINTVAL (trueop1) - 1,
4751 : mode));
4752 : break;
4753 :
4754 576763 : case MOD:
4755 : /* 0%x is 0 (or x&0 if x has side-effects). */
4756 576763 : if (trueop0 == CONST0_RTX (mode))
4757 : {
4758 1219 : if (side_effects_p (op1))
4759 8 : return simplify_gen_binary (AND, mode, op1, trueop0);
4760 : return trueop0;
4761 : }
4762 : /* x%1 and x%-1 is 0 (or x&0 if x has side-effects). */
4763 575544 : if (trueop1 == CONST1_RTX (mode) || trueop1 == constm1_rtx)
4764 : {
4765 557 : if (side_effects_p (op0))
4766 0 : return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
4767 557 : return CONST0_RTX (mode);
4768 : }
4769 : break;
4770 :
4771 141141 : case ROTATERT:
4772 141141 : case ROTATE:
4773 141141 : if (trueop1 == CONST0_RTX (mode))
4774 : return op0;
4775 : /* Canonicalize rotates by constant amount. If the condition of
4776 : reversing direction is met, then reverse the direction. */
4777 : #if defined(HAVE_rotate) && defined(HAVE_rotatert)
4778 141051 : if (reverse_rotate_by_imm_p (mode, (code == ROTATE), trueop1))
4779 : {
4780 12256 : int new_amount = GET_MODE_UNIT_PRECISION (mode) - INTVAL (trueop1);
4781 12256 : rtx new_amount_rtx = gen_int_shift_amount (mode, new_amount);
4782 12990 : return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
4783 : mode, op0, new_amount_rtx);
4784 : }
4785 : #endif
4786 : /* ROTATE/ROTATERT:HI (X:HI, 8) is BSWAP:HI (X). Other combinations
4787 : such as SImode with a count of 16 do not correspond to RTL BSWAP
4788 : semantics. */
4789 128795 : tem = unwrap_const_vec_duplicate (trueop1);
4790 128795 : if (GET_MODE_UNIT_BITSIZE (mode) == (2 * BITS_PER_UNIT)
4791 128795 : && CONST_INT_P (tem) && INTVAL (tem) == BITS_PER_UNIT)
4792 674 : return simplify_gen_unary (BSWAP, mode, op0, mode);
4793 :
4794 : /* FALLTHRU */
4795 5457117 : case ASHIFTRT:
4796 5457117 : if (trueop1 == CONST0_RTX (mode))
4797 : return op0;
4798 5454852 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4799 : return op0;
4800 : /* Rotating ~0 always results in ~0. */
4801 5454679 : if (CONST_INT_P (trueop0)
4802 15469 : && HWI_COMPUTABLE_MODE_P (mode)
4803 15441 : && UINTVAL (trueop0) == GET_MODE_MASK (mode)
4804 5454679 : && ! side_effects_p (op1))
4805 : return op0;
4806 :
4807 32036817 : canonicalize_shift:
4808 : /* Given:
4809 : scalar modes M1, M2
4810 : scalar constants c1, c2
4811 : size (M2) > size (M1)
4812 : c1 == size (M2) - size (M1)
4813 : optimize:
4814 : ([a|l]shiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int <c1>))
4815 : <low_part>)
4816 : (const_int <c2>))
4817 : to:
4818 : (subreg:M1 ([a|l]shiftrt:M2 (reg:M2) (const_int <c1 + c2>))
4819 : <low_part>). */
4820 32036817 : if ((code == ASHIFTRT || code == LSHIFTRT)
4821 12213126 : && is_a <scalar_int_mode> (mode, &int_mode)
4822 11407472 : && SUBREG_P (op0)
4823 1240296 : && CONST_INT_P (op1)
4824 1236898 : && GET_CODE (SUBREG_REG (op0)) == LSHIFTRT
4825 18937 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op0)),
4826 : &inner_mode)
4827 18937 : && CONST_INT_P (XEXP (SUBREG_REG (op0), 1))
4828 37488 : && GET_MODE_BITSIZE (inner_mode) > GET_MODE_BITSIZE (int_mode)
4829 18744 : && (INTVAL (XEXP (SUBREG_REG (op0), 1))
4830 37488 : == GET_MODE_BITSIZE (inner_mode) - GET_MODE_BITSIZE (int_mode))
4831 32055331 : && subreg_lowpart_p (op0))
4832 : {
4833 18514 : rtx tmp = gen_int_shift_amount
4834 18514 : (inner_mode, INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (op1));
4835 :
4836 : /* Combine would usually zero out the value when combining two
4837 : local shifts and the range becomes larger or equal to the mode.
4838 : However since we fold away one of the shifts here combine won't
4839 : see it so we should immediately zero the result if it's out of
4840 : range. */
4841 18514 : if (code == LSHIFTRT
4842 33510 : && INTVAL (tmp) >= GET_MODE_BITSIZE (inner_mode))
4843 0 : tmp = const0_rtx;
4844 : else
4845 18514 : tmp = simplify_gen_binary (code,
4846 : inner_mode,
4847 18514 : XEXP (SUBREG_REG (op0), 0),
4848 : tmp);
4849 :
4850 18514 : return lowpart_subreg (int_mode, tmp, inner_mode);
4851 : }
4852 :
4853 32018303 : if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
4854 : {
4855 : val = INTVAL (op1) & (GET_MODE_UNIT_PRECISION (mode) - 1);
4856 : if (val != INTVAL (op1))
4857 : return simplify_gen_binary (code, mode, op0,
4858 : gen_int_shift_amount (mode, val));
4859 : }
4860 :
4861 : /* Simplify:
4862 :
4863 : (code:M1
4864 : (subreg:M1
4865 : ([al]shiftrt:M2
4866 : (subreg:M2
4867 : (ashift:M1 X C1))
4868 : C2))
4869 : C3)
4870 :
4871 : to:
4872 :
4873 : (code:M1
4874 : ([al]shiftrt:M1
4875 : (ashift:M1 X C1+N)
4876 : C2+N)
4877 : C3)
4878 :
4879 : where M1 is N bits wider than M2. Optimizing the (subreg:M1 ...)
4880 : directly would be arithmetically correct, but restricting the
4881 : simplification to shifts by constants is more conservative,
4882 : since it is more likely to lead to further simplifications. */
4883 32018303 : if (is_a<scalar_int_mode> (mode, &int_mode)
4884 5735421 : && paradoxical_subreg_p (op0)
4885 5215506 : && is_a<scalar_int_mode> (GET_MODE (SUBREG_REG (op0)), &inner_mode)
4886 5191462 : && (GET_CODE (SUBREG_REG (op0)) == ASHIFTRT
4887 5191462 : || GET_CODE (SUBREG_REG (op0)) == LSHIFTRT)
4888 157708 : && CONST_INT_P (op1))
4889 : {
4890 157708 : auto xcode = GET_CODE (SUBREG_REG (op0));
4891 157708 : rtx xop0 = XEXP (SUBREG_REG (op0), 0);
4892 157708 : rtx xop1 = XEXP (SUBREG_REG (op0), 1);
4893 157708 : if (SUBREG_P (xop0)
4894 11369 : && GET_MODE (SUBREG_REG (xop0)) == mode
4895 11224 : && GET_CODE (SUBREG_REG (xop0)) == ASHIFT
4896 596 : && CONST_INT_P (xop1)
4897 158304 : && UINTVAL (xop1) < GET_MODE_PRECISION (inner_mode))
4898 : {
4899 596 : rtx yop0 = XEXP (SUBREG_REG (xop0), 0);
4900 596 : rtx yop1 = XEXP (SUBREG_REG (xop0), 1);
4901 596 : if (CONST_INT_P (yop1)
4902 596 : && UINTVAL (yop1) < GET_MODE_PRECISION (inner_mode))
4903 : {
4904 1192 : auto bias = (GET_MODE_BITSIZE (int_mode)
4905 596 : - GET_MODE_BITSIZE (inner_mode));
4906 596 : tem = simplify_gen_binary (ASHIFT, mode, yop0,
4907 596 : GEN_INT (INTVAL (yop1) + bias));
4908 596 : tem = simplify_gen_binary (xcode, mode, tem,
4909 596 : GEN_INT (INTVAL (xop1) + bias));
4910 596 : return simplify_gen_binary (code, mode, tem, op1);
4911 : }
4912 : }
4913 : }
4914 : break;
4915 :
4916 0 : case SS_ASHIFT:
4917 0 : if (CONST_INT_P (trueop0)
4918 0 : && HWI_COMPUTABLE_MODE_P (mode)
4919 0 : && (UINTVAL (trueop0) == (GET_MODE_MASK (mode) >> 1)
4920 0 : || mode_signbit_p (mode, trueop0))
4921 0 : && ! side_effects_p (op1))
4922 : return op0;
4923 0 : goto simplify_ashift;
4924 :
4925 0 : case US_ASHIFT:
4926 0 : if (CONST_INT_P (trueop0)
4927 0 : && HWI_COMPUTABLE_MODE_P (mode)
4928 0 : && UINTVAL (trueop0) == GET_MODE_MASK (mode)
4929 0 : && ! side_effects_p (op1))
4930 : return op0;
4931 : /* FALLTHRU */
4932 :
4933 20132448 : case ASHIFT:
4934 20132448 : simplify_ashift:
4935 20132448 : if (trueop1 == CONST0_RTX (mode))
4936 : return op0;
4937 19962886 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4938 : return op0;
4939 19933147 : if (mem_depth
4940 237546 : && code == ASHIFT
4941 237546 : && CONST_INT_P (trueop1)
4942 237538 : && is_a <scalar_int_mode> (mode, &int_mode)
4943 20170673 : && IN_RANGE (UINTVAL (trueop1),
4944 : 1, GET_MODE_PRECISION (int_mode) - 1))
4945 : {
4946 237526 : auto c = (wi::one (GET_MODE_PRECISION (int_mode))
4947 237526 : << UINTVAL (trueop1));
4948 237526 : rtx new_op1 = immed_wide_int_const (c, int_mode);
4949 237526 : return simplify_gen_binary (MULT, int_mode, op0, new_op1);
4950 237526 : }
4951 :
4952 : /* If we're shifting left a signed bitfield extraction and the
4953 : shift count + bitfield size is a natural integral mode and
4954 : the field starts at offset 0 (counting from the LSB), then
4955 : this can be simplified to a sign extension of a left shift.
4956 :
4957 : Some ISAs (RISC-V 64-bit) have inherent support for such
4958 : instructions and it's better for various optimizations to
4959 : express as a SIGN_EXTEND rather than a shifted SIGN_EXTRACT. */
4960 19695621 : if (GET_CODE (op0) == SIGN_EXTRACT
4961 28 : && REG_P (XEXP (op0, 0))
4962 : /* The size of the bitfield, the location of the bitfield and
4963 : shift count must be CONST_INTs. */
4964 22 : && CONST_INT_P (op1)
4965 22 : && CONST_INT_P (XEXP (op0, 1))
4966 22 : && CONST_INT_P (XEXP (op0, 2)))
4967 : {
4968 22 : int size = INTVAL (op1) + INTVAL (XEXP (op0, 1));
4969 22 : machine_mode smaller_mode;
4970 : /* Now we need to verify the size of the bitfield plus the shift
4971 : count is an integral mode and smaller than MODE. This is
4972 : requirement for using SIGN_EXTEND. We also need to verify the
4973 : field starts at bit location 0 and that the subreg lowpart also
4974 : starts at zero. */
4975 22 : if (int_mode_for_size (size, size).exists (&smaller_mode)
4976 3 : && mode > smaller_mode
4977 22 : && (subreg_lowpart_offset (smaller_mode, mode).to_constant ()
4978 3 : == UINTVAL (XEXP (op0, 2)))
4979 1 : && XEXP (op0, 2) == CONST0_RTX (mode))
4980 : {
4981 : /* Everything passed. So we just need to get the subreg of the
4982 : original input, shift it and sign extend the result. */
4983 1 : rtx op = gen_lowpart (smaller_mode, XEXP (op0, 0));
4984 1 : rtx x = gen_rtx_ASHIFT (smaller_mode, op, op1);
4985 1 : return gen_rtx_SIGN_EXTEND (mode, x);
4986 : }
4987 : }
4988 19695620 : goto canonicalize_shift;
4989 :
4990 8731557 : case LSHIFTRT:
4991 8731557 : if (trueop1 == CONST0_RTX (mode))
4992 : return op0;
4993 6888113 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4994 : return op0;
4995 : /* Optimize (lshiftrt (clz X) C) as (eq X 0). */
4996 6886518 : if (GET_CODE (op0) == CLZ
4997 0 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
4998 0 : && CONST_INT_P (trueop1)
4999 : && STORE_FLAG_VALUE == 1
5000 6886518 : && INTVAL (trueop1) < GET_MODE_UNIT_PRECISION (mode))
5001 : {
5002 0 : unsigned HOST_WIDE_INT zero_val = 0;
5003 :
5004 0 : if (CLZ_DEFINED_VALUE_AT_ZERO (inner_mode, zero_val)
5005 0 : && zero_val == GET_MODE_PRECISION (inner_mode)
5006 0 : && INTVAL (trueop1) == exact_log2 (zero_val))
5007 0 : return simplify_gen_relational (EQ, mode, inner_mode,
5008 0 : XEXP (op0, 0), const0_rtx);
5009 : }
5010 6886518 : goto canonicalize_shift;
5011 :
5012 240502 : case SMIN:
5013 240502 : if (HWI_COMPUTABLE_MODE_P (mode)
5014 219609 : && mode_signbit_p (mode, trueop1)
5015 0 : && ! side_effects_p (op0))
5016 : return op1;
5017 240502 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5018 : return op0;
5019 240324 : tem = simplify_associative_operation (code, mode, op0, op1);
5020 240324 : if (tem)
5021 : return tem;
5022 : break;
5023 :
5024 709279 : case SMAX:
5025 709279 : if (HWI_COMPUTABLE_MODE_P (mode)
5026 681600 : && CONST_INT_P (trueop1)
5027 649382 : && (UINTVAL (trueop1) == GET_MODE_MASK (mode) >> 1)
5028 0 : && ! side_effects_p (op0))
5029 : return op1;
5030 709279 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5031 : return op0;
5032 709172 : tem = simplify_associative_operation (code, mode, op0, op1);
5033 709172 : if (tem)
5034 : return tem;
5035 : break;
5036 :
5037 352404 : case UMIN:
5038 352404 : if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
5039 : return op1;
5040 352392 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5041 : return op0;
5042 352274 : tem = simplify_associative_operation (code, mode, op0, op1);
5043 352274 : if (tem)
5044 : return tem;
5045 : break;
5046 :
5047 291998 : case UMAX:
5048 291998 : if (trueop1 == constm1_rtx && ! side_effects_p (op0))
5049 : return op1;
5050 291998 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5051 : return op0;
5052 291908 : tem = simplify_associative_operation (code, mode, op0, op1);
5053 291908 : if (tem)
5054 : return tem;
5055 : break;
5056 :
5057 12109 : case SS_PLUS:
5058 12109 : case US_PLUS:
5059 12109 : case SS_MINUS:
5060 12109 : case US_MINUS:
5061 : /* Simplify x +/- 0 to x, if possible. */
5062 12109 : if (trueop1 == CONST0_RTX (mode))
5063 0 : return op0;
5064 : return 0;
5065 :
5066 0 : case SS_MULT:
5067 0 : case US_MULT:
5068 : /* Simplify x * 0 to 0, if possible. */
5069 0 : if (trueop1 == CONST0_RTX (mode)
5070 0 : && !side_effects_p (op0))
5071 : return op1;
5072 :
5073 : /* Simplify x * 1 to x, if possible. */
5074 0 : if (trueop1 == CONST1_RTX (mode))
5075 0 : return op0;
5076 : return 0;
5077 :
5078 518436 : case SMUL_HIGHPART:
5079 518436 : case UMUL_HIGHPART:
5080 : /* Simplify x * 0 to 0, if possible. */
5081 518436 : if (trueop1 == CONST0_RTX (mode)
5082 518436 : && !side_effects_p (op0))
5083 78 : return op1;
5084 : return 0;
5085 :
5086 0 : case SS_DIV:
5087 0 : case US_DIV:
5088 : /* Simplify x / 1 to x, if possible. */
5089 0 : if (trueop1 == CONST1_RTX (mode))
5090 0 : return op0;
5091 : return 0;
5092 :
5093 0 : case COPYSIGN:
5094 0 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5095 : return op0;
5096 0 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1))
5097 : {
5098 0 : REAL_VALUE_TYPE f1;
5099 0 : real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (trueop1));
5100 0 : rtx tmp = simplify_gen_unary (ABS, mode, op0, mode);
5101 0 : if (REAL_VALUE_NEGATIVE (f1))
5102 0 : tmp = simplify_unary_operation (NEG, mode, tmp, mode);
5103 0 : return tmp;
5104 : }
5105 0 : if (GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
5106 0 : return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
5107 0 : if (GET_CODE (op1) == ABS
5108 0 : && ! side_effects_p (op1))
5109 0 : return simplify_gen_unary (ABS, mode, op0, mode);
5110 0 : if (GET_CODE (op0) == COPYSIGN
5111 0 : && ! side_effects_p (XEXP (op0, 1)))
5112 0 : return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
5113 0 : if (GET_CODE (op1) == COPYSIGN
5114 0 : && ! side_effects_p (XEXP (op1, 0)))
5115 0 : return simplify_gen_binary (COPYSIGN, mode, op0, XEXP (op1, 1));
5116 : return 0;
5117 :
5118 1112 : case VEC_SERIES:
5119 2224 : if (op1 == CONST0_RTX (GET_MODE_INNER (mode)))
5120 92 : return gen_vec_duplicate (mode, op0);
5121 1020 : if (valid_for_const_vector_p (mode, op0)
5122 1020 : && valid_for_const_vector_p (mode, op1))
5123 93 : return gen_const_vec_series (mode, op0, op1);
5124 : return 0;
5125 :
5126 3974018 : case VEC_SELECT:
5127 3974018 : if (!VECTOR_MODE_P (mode))
5128 : {
5129 1051497 : gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
5130 2102994 : gcc_assert (mode == GET_MODE_INNER (GET_MODE (trueop0)));
5131 1051497 : gcc_assert (GET_CODE (trueop1) == PARALLEL);
5132 1051497 : gcc_assert (XVECLEN (trueop1, 0) == 1);
5133 :
5134 : /* We can't reason about selections made at runtime. */
5135 1051497 : if (!CONST_INT_P (XVECEXP (trueop1, 0, 0)))
5136 459915835 : return 0;
5137 :
5138 1051497 : if (vec_duplicate_p (trueop0, &elt0))
5139 2132 : return elt0;
5140 :
5141 1049365 : if (GET_CODE (trueop0) == CONST_VECTOR)
5142 7255 : return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP
5143 : (trueop1, 0, 0)));
5144 :
5145 : /* Extract a scalar element from a nested VEC_SELECT expression
5146 : (with optional nested VEC_CONCAT expression). Some targets
5147 : (i386) extract scalar element from a vector using chain of
5148 : nested VEC_SELECT expressions. When input operand is a memory
5149 : operand, this operation can be simplified to a simple scalar
5150 : load from an offsetted memory address. */
5151 1042110 : int n_elts;
5152 1042110 : if (GET_CODE (trueop0) == VEC_SELECT
5153 1117079 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
5154 74969 : .is_constant (&n_elts)))
5155 : {
5156 74969 : rtx op0 = XEXP (trueop0, 0);
5157 74969 : rtx op1 = XEXP (trueop0, 1);
5158 :
5159 74969 : int i = INTVAL (XVECEXP (trueop1, 0, 0));
5160 74969 : int elem;
5161 :
5162 74969 : rtvec vec;
5163 74969 : rtx tmp_op, tmp;
5164 :
5165 74969 : gcc_assert (GET_CODE (op1) == PARALLEL);
5166 74969 : gcc_assert (i < XVECLEN (op1, 0));
5167 :
5168 : /* Select element, pointed by nested selector. */
5169 74969 : elem = INTVAL (XVECEXP (op1, 0, i));
5170 :
5171 74969 : gcc_assert (elem < n_elts);
5172 :
5173 : /* Handle the case when nested VEC_SELECT wraps VEC_CONCAT. */
5174 74969 : if (GET_CODE (op0) == VEC_CONCAT)
5175 : {
5176 30972 : rtx op00 = XEXP (op0, 0);
5177 30972 : rtx op01 = XEXP (op0, 1);
5178 :
5179 30972 : machine_mode mode00, mode01;
5180 30972 : int n_elts00, n_elts01;
5181 :
5182 30972 : mode00 = GET_MODE (op00);
5183 30972 : mode01 = GET_MODE (op01);
5184 :
5185 : /* Find out the number of elements of each operand.
5186 : Since the concatenated result has a constant number
5187 : of elements, the operands must too. */
5188 30972 : n_elts00 = GET_MODE_NUNITS (mode00).to_constant ();
5189 30972 : n_elts01 = GET_MODE_NUNITS (mode01).to_constant ();
5190 :
5191 30972 : gcc_assert (n_elts == n_elts00 + n_elts01);
5192 :
5193 : /* Select correct operand of VEC_CONCAT
5194 : and adjust selector. */
5195 30972 : if (elem < n_elts01)
5196 : tmp_op = op00;
5197 : else
5198 : {
5199 53 : tmp_op = op01;
5200 53 : elem -= n_elts00;
5201 : }
5202 : }
5203 : else
5204 : tmp_op = op0;
5205 :
5206 74969 : vec = rtvec_alloc (1);
5207 74969 : RTVEC_ELT (vec, 0) = GEN_INT (elem);
5208 :
5209 74969 : tmp = gen_rtx_fmt_ee (code, mode,
5210 : tmp_op, gen_rtx_PARALLEL (VOIDmode, vec));
5211 74969 : return tmp;
5212 : }
5213 : /* If we select one half of a vec_concat, return that. */
5214 967141 : else if (GET_CODE (trueop0) == VEC_CONCAT)
5215 : {
5216 1542 : rtx subop0 = XEXP (trueop0, 0);
5217 1542 : rtx subop1 = XEXP (trueop0, 1);
5218 1542 : machine_mode mode0 = GET_MODE (subop0);
5219 1542 : machine_mode mode1 = GET_MODE (subop1);
5220 1542 : int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5221 1542 : if (i0 == 0 && mode == mode0 && !side_effects_p (subop1))
5222 459915835 : return subop0;
5223 1132 : if (known_eq (i0, GET_MODE_NUNITS (mode0))
5224 566 : && mode == mode1 && !side_effects_p (subop0))
5225 : return subop1;
5226 : }
5227 : }
5228 : else
5229 : {
5230 2922521 : gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
5231 8767563 : gcc_assert (GET_MODE_INNER (mode)
5232 : == GET_MODE_INNER (GET_MODE (trueop0)));
5233 2922521 : gcc_assert (GET_CODE (trueop1) == PARALLEL);
5234 :
5235 2922521 : if (vec_duplicate_p (trueop0, &elt0))
5236 : /* It doesn't matter which elements are selected by trueop1,
5237 : because they are all the same. */
5238 17594 : return gen_vec_duplicate (mode, elt0);
5239 :
5240 2904927 : if (GET_CODE (trueop0) == CONST_VECTOR)
5241 : {
5242 18045 : unsigned n_elts = XVECLEN (trueop1, 0);
5243 18045 : rtvec v = rtvec_alloc (n_elts);
5244 18045 : unsigned int i;
5245 :
5246 36090 : gcc_assert (known_eq (n_elts, GET_MODE_NUNITS (mode)));
5247 83493 : for (i = 0; i < n_elts; i++)
5248 : {
5249 65448 : rtx x = XVECEXP (trueop1, 0, i);
5250 :
5251 65448 : if (!CONST_INT_P (x))
5252 : return 0;
5253 :
5254 65448 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0,
5255 : INTVAL (x));
5256 : }
5257 :
5258 18045 : return gen_rtx_CONST_VECTOR (mode, v);
5259 : }
5260 :
5261 : /* Recognize the identity. */
5262 2886882 : if (GET_MODE (trueop0) == mode)
5263 : {
5264 617758 : bool maybe_ident = true;
5265 617758 : for (int i = 0; i < XVECLEN (trueop1, 0); i++)
5266 : {
5267 617381 : rtx j = XVECEXP (trueop1, 0, i);
5268 617381 : if (!CONST_INT_P (j) || INTVAL (j) != i)
5269 : {
5270 : maybe_ident = false;
5271 : break;
5272 : }
5273 : }
5274 381776 : if (maybe_ident)
5275 : return trueop0;
5276 : }
5277 :
5278 : /* If we select a low-part subreg, return that. */
5279 2886505 : if (vec_series_lowpart_p (mode, GET_MODE (trueop0), trueop1))
5280 : {
5281 0 : rtx new_rtx = lowpart_subreg (mode, trueop0,
5282 0 : GET_MODE (trueop0));
5283 0 : if (new_rtx != NULL_RTX)
5284 : return new_rtx;
5285 : }
5286 :
5287 : /* If we build {a,b} then permute it, build the result directly. */
5288 2886505 : if (XVECLEN (trueop1, 0) == 2
5289 598183 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
5290 598183 : && CONST_INT_P (XVECEXP (trueop1, 0, 1))
5291 598183 : && GET_CODE (trueop0) == VEC_CONCAT
5292 177092 : && GET_CODE (XEXP (trueop0, 0)) == VEC_CONCAT
5293 75 : && GET_MODE (XEXP (trueop0, 0)) == mode
5294 75 : && GET_CODE (XEXP (trueop0, 1)) == VEC_CONCAT
5295 64 : && GET_MODE (XEXP (trueop0, 1)) == mode)
5296 : {
5297 64 : unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5298 64 : unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
5299 64 : rtx subop0, subop1;
5300 :
5301 64 : gcc_assert (i0 < 4 && i1 < 4);
5302 64 : subop0 = XEXP (XEXP (trueop0, i0 / 2), i0 % 2);
5303 64 : subop1 = XEXP (XEXP (trueop0, i1 / 2), i1 % 2);
5304 :
5305 64 : return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
5306 : }
5307 :
5308 2886441 : if (XVECLEN (trueop1, 0) == 2
5309 598119 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
5310 598119 : && CONST_INT_P (XVECEXP (trueop1, 0, 1))
5311 598119 : && GET_CODE (trueop0) == VEC_CONCAT
5312 177028 : && GET_MODE (trueop0) == mode)
5313 : {
5314 2 : unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5315 2 : unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
5316 2 : rtx subop0, subop1;
5317 :
5318 2 : gcc_assert (i0 < 2 && i1 < 2);
5319 2 : subop0 = XEXP (trueop0, i0);
5320 2 : subop1 = XEXP (trueop0, i1);
5321 :
5322 2 : return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
5323 : }
5324 :
5325 : /* If we select one half of a vec_concat, return that. */
5326 2886439 : int l0, l1;
5327 2886439 : if (GET_CODE (trueop0) == VEC_CONCAT
5328 3854506 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
5329 1927253 : .is_constant (&l0))
5330 3854506 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 1)))
5331 1927253 : .is_constant (&l1))
5332 4813692 : && CONST_INT_P (XVECEXP (trueop1, 0, 0)))
5333 : {
5334 1927253 : rtx subop0 = XEXP (trueop0, 0);
5335 1927253 : rtx subop1 = XEXP (trueop0, 1);
5336 1927253 : machine_mode mode0 = GET_MODE (subop0);
5337 1927253 : machine_mode mode1 = GET_MODE (subop1);
5338 1927253 : int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5339 1927253 : if (i0 == 0 && !side_effects_p (op1) && mode == mode0)
5340 : {
5341 1494580 : bool success = true;
5342 1494580 : for (int i = 1; i < l0; ++i)
5343 : {
5344 1494262 : rtx j = XVECEXP (trueop1, 0, i);
5345 1494262 : if (!CONST_INT_P (j) || INTVAL (j) != i)
5346 : {
5347 : success = false;
5348 : break;
5349 : }
5350 : }
5351 1262455 : if (success)
5352 : return subop0;
5353 : }
5354 1926935 : if (i0 == l0 && !side_effects_p (op0) && mode == mode1)
5355 : {
5356 590 : bool success = true;
5357 590 : for (int i = 1; i < l1; ++i)
5358 : {
5359 543 : rtx j = XVECEXP (trueop1, 0, i);
5360 543 : if (!CONST_INT_P (j) || INTVAL (j) != i0 + i)
5361 : {
5362 : success = false;
5363 : break;
5364 : }
5365 : }
5366 76 : if (success)
5367 : return subop1;
5368 : }
5369 : }
5370 :
5371 : /* Simplify vec_select of a subreg of X to just a vec_select of X
5372 : when X has same component mode as vec_select. */
5373 2886074 : unsigned HOST_WIDE_INT subreg_offset = 0;
5374 2886074 : if (GET_CODE (trueop0) == SUBREG
5375 370894 : && GET_MODE_INNER (mode)
5376 741788 : == GET_MODE_INNER (GET_MODE (SUBREG_REG (trueop0)))
5377 29990 : && GET_MODE_NUNITS (mode).is_constant (&l1)
5378 3256968 : && constant_multiple_p (subreg_memory_offset (trueop0),
5379 29990 : GET_MODE_UNIT_BITSIZE (mode),
5380 : &subreg_offset))
5381 : {
5382 14995 : poly_uint64 nunits
5383 29990 : = GET_MODE_NUNITS (GET_MODE (SUBREG_REG (trueop0)));
5384 14995 : bool success = true;
5385 92021 : for (int i = 0; i != l1; i++)
5386 : {
5387 87375 : rtx idx = XVECEXP (trueop1, 0, i);
5388 87375 : if (!CONST_INT_P (idx)
5389 87375 : || maybe_ge (UINTVAL (idx) + subreg_offset, nunits))
5390 : {
5391 : success = false;
5392 : break;
5393 : }
5394 : }
5395 :
5396 14995 : if (success)
5397 : {
5398 4646 : rtx par = trueop1;
5399 4646 : if (subreg_offset)
5400 : {
5401 0 : rtvec vec = rtvec_alloc (l1);
5402 0 : for (int i = 0; i < l1; i++)
5403 0 : RTVEC_ELT (vec, i)
5404 0 : = GEN_INT (INTVAL (XVECEXP (trueop1, 0, i))
5405 : + subreg_offset);
5406 0 : par = gen_rtx_PARALLEL (VOIDmode, vec);
5407 : }
5408 4646 : return gen_rtx_VEC_SELECT (mode, SUBREG_REG (trueop0), par);
5409 : }
5410 : }
5411 : }
5412 :
5413 3847212 : if (XVECLEN (trueop1, 0) == 1
5414 965868 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
5415 965868 : && GET_CODE (trueop0) == VEC_CONCAT)
5416 : {
5417 185 : rtx vec = trueop0;
5418 370 : offset = INTVAL (XVECEXP (trueop1, 0, 0)) * GET_MODE_SIZE (mode);
5419 :
5420 : /* Try to find the element in the VEC_CONCAT. */
5421 185 : while (GET_MODE (vec) != mode
5422 370 : && GET_CODE (vec) == VEC_CONCAT)
5423 : {
5424 185 : poly_int64 vec_size;
5425 :
5426 185 : if (CONST_INT_P (XEXP (vec, 0)))
5427 : {
5428 : /* vec_concat of two const_ints doesn't make sense with
5429 : respect to modes. */
5430 0 : if (CONST_INT_P (XEXP (vec, 1)))
5431 459915835 : return 0;
5432 :
5433 0 : vec_size = GET_MODE_SIZE (GET_MODE (trueop0))
5434 0 : - GET_MODE_SIZE (GET_MODE (XEXP (vec, 1)));
5435 : }
5436 : else
5437 370 : vec_size = GET_MODE_SIZE (GET_MODE (XEXP (vec, 0)));
5438 :
5439 185 : if (known_lt (offset, vec_size))
5440 : vec = XEXP (vec, 0);
5441 15 : else if (known_ge (offset, vec_size))
5442 : {
5443 15 : offset -= vec_size;
5444 15 : vec = XEXP (vec, 1);
5445 : }
5446 : else
5447 : break;
5448 185 : vec = avoid_constant_pool_reference (vec);
5449 : }
5450 :
5451 185 : if (GET_MODE (vec) == mode)
5452 : return vec;
5453 : }
5454 :
5455 : /* If we select elements in a vec_merge that all come from the same
5456 : operand, select from that operand directly. */
5457 3847212 : if (GET_CODE (op0) == VEC_MERGE)
5458 : {
5459 9370 : rtx trueop02 = avoid_constant_pool_reference (XEXP (op0, 2));
5460 9370 : if (CONST_INT_P (trueop02))
5461 : {
5462 2959 : unsigned HOST_WIDE_INT sel = UINTVAL (trueop02);
5463 2959 : bool all_operand0 = true;
5464 2959 : bool all_operand1 = true;
5465 10781 : for (int i = 0; i < XVECLEN (trueop1, 0); i++)
5466 : {
5467 7822 : rtx j = XVECEXP (trueop1, 0, i);
5468 7822 : if (sel & (HOST_WIDE_INT_1U << UINTVAL (j)))
5469 : all_operand1 = false;
5470 : else
5471 3420 : all_operand0 = false;
5472 : }
5473 2959 : if (all_operand0 && !side_effects_p (XEXP (op0, 1)))
5474 1440 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 0), op1);
5475 1519 : if (all_operand1 && !side_effects_p (XEXP (op0, 0)))
5476 55 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 1), op1);
5477 : }
5478 : }
5479 :
5480 : /* If we have two nested selects that are inverses of each
5481 : other, replace them with the source operand. */
5482 3845717 : if (GET_CODE (trueop0) == VEC_SELECT
5483 74083 : && GET_MODE (XEXP (trueop0, 0)) == mode)
5484 : {
5485 1042 : rtx op0_subop1 = XEXP (trueop0, 1);
5486 1042 : gcc_assert (GET_CODE (op0_subop1) == PARALLEL);
5487 2084 : gcc_assert (known_eq (XVECLEN (trueop1, 0), GET_MODE_NUNITS (mode)));
5488 : bool identical_p = true;
5489 :
5490 : /* Apply the outer ordering vector to the inner one. (The inner
5491 : ordering vector is expressly permitted to be of a different
5492 : length than the outer one.) If the result is { 0, 1, ..., n-1 }
5493 : then the two VEC_SELECTs cancel. */
5494 9014 : for (int i = 0; i < XVECLEN (trueop1, 0); ++i)
5495 : {
5496 7972 : rtx x = XVECEXP (trueop1, 0, i);
5497 7972 : if (!CONST_INT_P (x))
5498 : return 0;
5499 7972 : rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
5500 7972 : if (!CONST_INT_P (y))
5501 : return 0;
5502 7972 : if (i != INTVAL (y))
5503 5898 : identical_p = false;
5504 : }
5505 1042 : if (identical_p)
5506 : return XEXP (trueop0, 0);
5507 :
5508 : /* Otherwise a permutation of a permutation is a permutation. */
5509 1042 : int len = XVECLEN (trueop1, 0);
5510 1042 : rtvec vec = rtvec_alloc (len);
5511 10056 : for (int i = 0; i < len; ++i)
5512 : {
5513 7972 : rtx x = XVECEXP (trueop1, 0, i);
5514 7972 : rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
5515 7972 : RTVEC_ELT (vec, i) = y;
5516 : }
5517 1042 : return gen_rtx_fmt_ee (code, mode, XEXP (trueop0, 0),
5518 : gen_rtx_PARALLEL (VOIDmode, vec));
5519 : }
5520 :
5521 : return 0;
5522 4117504 : case VEC_CONCAT:
5523 4117504 : {
5524 4117504 : machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
5525 4117504 : ? GET_MODE (trueop0)
5526 4117504 : : GET_MODE_INNER (mode));
5527 4117504 : machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
5528 4117504 : ? GET_MODE (trueop1)
5529 4117504 : : GET_MODE_INNER (mode));
5530 :
5531 4117504 : gcc_assert (VECTOR_MODE_P (mode));
5532 16470016 : gcc_assert (known_eq (GET_MODE_SIZE (op0_mode)
5533 : + GET_MODE_SIZE (op1_mode),
5534 : GET_MODE_SIZE (mode)));
5535 :
5536 4117504 : if (VECTOR_MODE_P (op0_mode))
5537 6492294 : gcc_assert (GET_MODE_INNER (mode)
5538 : == GET_MODE_INNER (op0_mode));
5539 : else
5540 3906812 : gcc_assert (GET_MODE_INNER (mode) == op0_mode);
5541 :
5542 4117504 : if (VECTOR_MODE_P (op1_mode))
5543 6492294 : gcc_assert (GET_MODE_INNER (mode)
5544 : == GET_MODE_INNER (op1_mode));
5545 : else
5546 3906812 : gcc_assert (GET_MODE_INNER (mode) == op1_mode);
5547 :
5548 4117504 : unsigned int n_elts, in_n_elts;
5549 4117504 : if ((GET_CODE (trueop0) == CONST_VECTOR
5550 4117504 : || CONST_SCALAR_INT_P (trueop0)
5551 4087474 : || CONST_DOUBLE_AS_FLOAT_P (trueop0))
5552 31329 : && (GET_CODE (trueop1) == CONST_VECTOR
5553 31329 : || CONST_SCALAR_INT_P (trueop1)
5554 31329 : || CONST_DOUBLE_AS_FLOAT_P (trueop1))
5555 0 : && GET_MODE_NUNITS (mode).is_constant (&n_elts)
5556 4117504 : && GET_MODE_NUNITS (op0_mode).is_constant (&in_n_elts))
5557 : {
5558 0 : rtvec v = rtvec_alloc (n_elts);
5559 0 : unsigned int i;
5560 0 : for (i = 0; i < n_elts; i++)
5561 : {
5562 0 : if (i < in_n_elts)
5563 : {
5564 0 : if (!VECTOR_MODE_P (op0_mode))
5565 0 : RTVEC_ELT (v, i) = trueop0;
5566 : else
5567 0 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
5568 : }
5569 : else
5570 : {
5571 0 : if (!VECTOR_MODE_P (op1_mode))
5572 0 : RTVEC_ELT (v, i) = trueop1;
5573 : else
5574 0 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
5575 : i - in_n_elts);
5576 : }
5577 : }
5578 :
5579 0 : return gen_rtx_CONST_VECTOR (mode, v);
5580 : }
5581 :
5582 : /* Try to merge two VEC_SELECTs from the same vector into a single one.
5583 : Restrict the transformation to avoid generating a VEC_SELECT with a
5584 : mode unrelated to its operand. */
5585 4117504 : if (GET_CODE (trueop0) == VEC_SELECT
5586 187100 : && GET_CODE (trueop1) == VEC_SELECT
5587 38072 : && rtx_equal_p (XEXP (trueop0, 0), XEXP (trueop1, 0))
5588 4137409 : && GET_MODE_INNER (GET_MODE (XEXP (trueop0, 0)))
5589 39810 : == GET_MODE_INNER(mode))
5590 : {
5591 19905 : rtx par0 = XEXP (trueop0, 1);
5592 19905 : rtx par1 = XEXP (trueop1, 1);
5593 19905 : int len0 = XVECLEN (par0, 0);
5594 19905 : int len1 = XVECLEN (par1, 0);
5595 19905 : rtvec vec = rtvec_alloc (len0 + len1);
5596 138808 : for (int i = 0; i < len0; i++)
5597 98998 : RTVEC_ELT (vec, i) = XVECEXP (par0, 0, i);
5598 118903 : for (int i = 0; i < len1; i++)
5599 98998 : RTVEC_ELT (vec, len0 + i) = XVECEXP (par1, 0, i);
5600 19905 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (trueop0, 0),
5601 19905 : gen_rtx_PARALLEL (VOIDmode, vec));
5602 : }
5603 : /* (vec_concat:
5604 : (subreg_lowpart:N OP)
5605 : (vec_select:N OP P)) --> OP when P selects the high half
5606 : of the OP. */
5607 4097599 : if (GET_CODE (trueop0) == SUBREG
5608 482826 : && subreg_lowpart_p (trueop0)
5609 482581 : && GET_CODE (trueop1) == VEC_SELECT
5610 3 : && SUBREG_REG (trueop0) == XEXP (trueop1, 0)
5611 0 : && !side_effects_p (XEXP (trueop1, 0))
5612 4097599 : && vec_series_highpart_p (op1_mode, mode, XEXP (trueop1, 1)))
5613 0 : return XEXP (trueop1, 0);
5614 : }
5615 : return 0;
5616 :
5617 0 : default:
5618 0 : gcc_unreachable ();
5619 : }
5620 :
5621 386292403 : if (mode == GET_MODE (op0)
5622 331361042 : && mode == GET_MODE (op1)
5623 105169821 : && vec_duplicate_p (op0, &elt0)
5624 386417906 : && vec_duplicate_p (op1, &elt1))
5625 : {
5626 : /* Try applying the operator to ELT and see if that simplifies.
5627 : We can duplicate the result if so.
5628 :
5629 : The reason we don't use simplify_gen_binary is that it isn't
5630 : necessarily a win to convert things like:
5631 :
5632 : (plus:V (vec_duplicate:V (reg:S R1))
5633 : (vec_duplicate:V (reg:S R2)))
5634 :
5635 : to:
5636 :
5637 : (vec_duplicate:V (plus:S (reg:S R1) (reg:S R2)))
5638 :
5639 : The first might be done entirely in vector registers while the
5640 : second might need a move between register files. */
5641 158 : tem = simplify_binary_operation (code, GET_MODE_INNER (mode),
5642 : elt0, elt1);
5643 79 : if (tem)
5644 2 : return gen_vec_duplicate (mode, tem);
5645 : }
5646 :
5647 : return 0;
5648 : }
5649 :
5650 : /* Return true if binary operation OP distributes over addition in operand
5651 : OPNO, with the other operand being held constant. OPNO counts from 1. */
5652 :
5653 : static bool
5654 8223 : distributes_over_addition_p (rtx_code op, int opno)
5655 : {
5656 0 : switch (op)
5657 : {
5658 : case PLUS:
5659 : case MINUS:
5660 : case MULT:
5661 : return true;
5662 :
5663 0 : case ASHIFT:
5664 0 : return opno == 1;
5665 :
5666 0 : default:
5667 0 : return false;
5668 : }
5669 : }
5670 :
5671 : rtx
5672 494113088 : simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
5673 : rtx op0, rtx op1)
5674 : {
5675 494113088 : if (VECTOR_MODE_P (mode)
5676 15679999 : && code != VEC_CONCAT
5677 11547956 : && GET_CODE (op0) == CONST_VECTOR
5678 183483 : && GET_CODE (op1) == CONST_VECTOR)
5679 : {
5680 8932 : bool step_ok_p;
5681 8932 : if (CONST_VECTOR_STEPPED_P (op0)
5682 8932 : && CONST_VECTOR_STEPPED_P (op1))
5683 : /* We can operate directly on the encoding if:
5684 :
5685 : a3 - a2 == a2 - a1 && b3 - b2 == b2 - b1
5686 : implies
5687 : (a3 op b3) - (a2 op b2) == (a2 op b2) - (a1 op b1)
5688 :
5689 : Addition and subtraction are the supported operators
5690 : for which this is true. */
5691 709 : step_ok_p = (code == PLUS || code == MINUS);
5692 8223 : else if (CONST_VECTOR_STEPPED_P (op0))
5693 : /* We can operate directly on stepped encodings if:
5694 :
5695 : a3 - a2 == a2 - a1
5696 : implies:
5697 : (a3 op c) - (a2 op c) == (a2 op c) - (a1 op c)
5698 :
5699 : which is true if (x -> x op c) distributes over addition. */
5700 1300 : step_ok_p = distributes_over_addition_p (code, 1);
5701 : else
5702 : /* Similarly in reverse. */
5703 6923 : step_ok_p = distributes_over_addition_p (code, 2);
5704 8932 : rtx_vector_builder builder;
5705 8932 : if (!builder.new_binary_operation (mode, op0, op1, step_ok_p))
5706 : return 0;
5707 :
5708 8932 : unsigned int count = builder.encoded_nelts ();
5709 54484 : for (unsigned int i = 0; i < count; i++)
5710 : {
5711 91204 : rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
5712 : CONST_VECTOR_ELT (op0, i),
5713 45602 : CONST_VECTOR_ELT (op1, i));
5714 45602 : if (!x || !valid_for_const_vector_p (mode, x))
5715 50 : return 0;
5716 45552 : builder.quick_push (x);
5717 : }
5718 8882 : return builder.build ();
5719 8932 : }
5720 :
5721 494104156 : if (VECTOR_MODE_P (mode)
5722 15671067 : && code == VEC_CONCAT
5723 4132043 : && (CONST_SCALAR_INT_P (op0)
5724 4108436 : || CONST_FIXED_P (op0)
5725 4108436 : || CONST_DOUBLE_AS_FLOAT_P (op0)
5726 4104820 : || CONST_VECTOR_P (op0))
5727 45868 : && (CONST_SCALAR_INT_P (op1)
5728 42427 : || CONST_DOUBLE_AS_FLOAT_P (op1)
5729 40110 : || CONST_FIXED_P (op1)
5730 40110 : || CONST_VECTOR_P (op1)))
5731 : {
5732 : /* Both inputs have a constant number of elements, so the result
5733 : must too. */
5734 14539 : unsigned n_elts = GET_MODE_NUNITS (mode).to_constant ();
5735 14539 : rtvec v = rtvec_alloc (n_elts);
5736 :
5737 14539 : gcc_assert (n_elts >= 2);
5738 14539 : if (n_elts == 2)
5739 : {
5740 5758 : gcc_assert (GET_CODE (op0) != CONST_VECTOR);
5741 5758 : gcc_assert (GET_CODE (op1) != CONST_VECTOR);
5742 :
5743 5758 : RTVEC_ELT (v, 0) = op0;
5744 5758 : RTVEC_ELT (v, 1) = op1;
5745 : }
5746 : else
5747 : {
5748 8781 : unsigned op0_n_elts = GET_MODE_NUNITS (GET_MODE (op0)).to_constant ();
5749 8781 : unsigned op1_n_elts = GET_MODE_NUNITS (GET_MODE (op1)).to_constant ();
5750 8781 : unsigned i;
5751 :
5752 8781 : gcc_assert (GET_CODE (op0) == CONST_VECTOR);
5753 8781 : gcc_assert (GET_CODE (op1) == CONST_VECTOR);
5754 8781 : gcc_assert (op0_n_elts + op1_n_elts == n_elts);
5755 :
5756 53523 : for (i = 0; i < op0_n_elts; ++i)
5757 44742 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op0, i);
5758 53715 : for (i = 0; i < op1_n_elts; ++i)
5759 44934 : RTVEC_ELT (v, op0_n_elts+i) = CONST_VECTOR_ELT (op1, i);
5760 : }
5761 :
5762 14539 : return gen_rtx_CONST_VECTOR (mode, v);
5763 : }
5764 :
5765 481887269 : if (VECTOR_MODE_P (mode)
5766 15656528 : && GET_CODE (op0) == CONST_VECTOR
5767 184415 : && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1))
5768 494089617 : && (CONST_VECTOR_DUPLICATE_P (op0)
5769 120919 : || CONST_VECTOR_NUNITS (op0).is_constant ()))
5770 : {
5771 120919 : switch (code)
5772 : {
5773 120919 : case PLUS:
5774 120919 : case MINUS:
5775 120919 : case MULT:
5776 120919 : case DIV:
5777 120919 : case MOD:
5778 120919 : case UDIV:
5779 120919 : case UMOD:
5780 120919 : case AND:
5781 120919 : case IOR:
5782 120919 : case XOR:
5783 120919 : case SMIN:
5784 120919 : case SMAX:
5785 120919 : case UMIN:
5786 120919 : case UMAX:
5787 120919 : case LSHIFTRT:
5788 120919 : case ASHIFTRT:
5789 120919 : case ASHIFT:
5790 120919 : case ROTATE:
5791 120919 : case ROTATERT:
5792 120919 : case SS_PLUS:
5793 120919 : case US_PLUS:
5794 120919 : case SS_MINUS:
5795 120919 : case US_MINUS:
5796 120919 : case SS_ASHIFT:
5797 120919 : case US_ASHIFT:
5798 120919 : case COPYSIGN:
5799 120919 : break;
5800 : default:
5801 : return NULL_RTX;
5802 : }
5803 :
5804 120919 : unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op0)
5805 120919 : ? CONST_VECTOR_NPATTERNS (op0)
5806 128900 : : CONST_VECTOR_NUNITS (op0).to_constant ());
5807 120919 : rtx_vector_builder builder (mode, npatterns, 1);
5808 375910 : for (unsigned i = 0; i < npatterns; i++)
5809 : {
5810 268144 : rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
5811 134072 : CONST_VECTOR_ELT (op0, i), op1);
5812 134072 : if (!x || !valid_for_const_vector_p (mode, x))
5813 0 : return 0;
5814 134072 : builder.quick_push (x);
5815 : }
5816 120919 : return builder.build ();
5817 : }
5818 :
5819 493968698 : if (SCALAR_FLOAT_MODE_P (mode)
5820 6440513 : && CONST_DOUBLE_AS_FLOAT_P (op0)
5821 76369 : && CONST_DOUBLE_AS_FLOAT_P (op1)
5822 11609 : && mode == GET_MODE (op0) && mode == GET_MODE (op1))
5823 : {
5824 11609 : if (code == AND
5825 : || code == IOR
5826 11609 : || code == XOR)
5827 : {
5828 2537 : long tmp0[4];
5829 2537 : long tmp1[4];
5830 2537 : REAL_VALUE_TYPE r;
5831 2537 : int i;
5832 :
5833 2537 : real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0),
5834 2537 : GET_MODE (op0));
5835 2537 : real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1),
5836 2537 : GET_MODE (op1));
5837 12685 : for (i = 0; i < 4; i++)
5838 : {
5839 10148 : switch (code)
5840 : {
5841 5268 : case AND:
5842 5268 : tmp0[i] &= tmp1[i];
5843 5268 : break;
5844 2512 : case IOR:
5845 2512 : tmp0[i] |= tmp1[i];
5846 2512 : break;
5847 2368 : case XOR:
5848 2368 : tmp0[i] ^= tmp1[i];
5849 2368 : break;
5850 : default:
5851 : gcc_unreachable ();
5852 : }
5853 : }
5854 2537 : real_from_target (&r, tmp0, mode);
5855 2537 : return const_double_from_real_value (r, mode);
5856 : }
5857 9072 : else if (code == COPYSIGN)
5858 : {
5859 0 : REAL_VALUE_TYPE f0, f1;
5860 0 : real_convert (&f0, mode, CONST_DOUBLE_REAL_VALUE (op0));
5861 0 : real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (op1));
5862 0 : real_copysign (&f0, &f1);
5863 0 : return const_double_from_real_value (f0, mode);
5864 : }
5865 : else
5866 : {
5867 9072 : REAL_VALUE_TYPE f0, f1, value, result;
5868 9072 : const REAL_VALUE_TYPE *opr0, *opr1;
5869 9072 : bool inexact;
5870 :
5871 9072 : opr0 = CONST_DOUBLE_REAL_VALUE (op0);
5872 9072 : opr1 = CONST_DOUBLE_REAL_VALUE (op1);
5873 :
5874 9072 : if (HONOR_SNANS (mode)
5875 9072 : && (REAL_VALUE_ISSIGNALING_NAN (*opr0)
5876 803 : || REAL_VALUE_ISSIGNALING_NAN (*opr1)))
5877 : return 0;
5878 :
5879 9062 : real_convert (&f0, mode, opr0);
5880 9062 : real_convert (&f1, mode, opr1);
5881 :
5882 9062 : if (code == DIV
5883 4160 : && real_equal (&f1, &dconst0)
5884 12704 : && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
5885 : return 0;
5886 :
5887 27021 : if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
5888 5334 : && flag_trapping_math
5889 5256 : && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
5890 : {
5891 9 : int s0 = REAL_VALUE_NEGATIVE (f0);
5892 9 : int s1 = REAL_VALUE_NEGATIVE (f1);
5893 :
5894 9 : switch (code)
5895 : {
5896 0 : case PLUS:
5897 : /* Inf + -Inf = NaN plus exception. */
5898 0 : if (s0 != s1)
5899 : return 0;
5900 : break;
5901 0 : case MINUS:
5902 : /* Inf - Inf = NaN plus exception. */
5903 0 : if (s0 == s1)
5904 : return 0;
5905 : break;
5906 : case DIV:
5907 : /* Inf / Inf = NaN plus exception. */
5908 : return 0;
5909 : default:
5910 : break;
5911 : }
5912 : }
5913 :
5914 7922 : if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
5915 1945 : && flag_trapping_math
5916 7312 : && ((REAL_VALUE_ISINF (f0) && real_equal (&f1, &dconst0))
5917 1889 : || (REAL_VALUE_ISINF (f1)
5918 10 : && real_equal (&f0, &dconst0))))
5919 : /* Inf * 0 = NaN plus exception. */
5920 : return 0;
5921 :
5922 5397 : inexact = real_arithmetic (&value, rtx_to_tree_code (code),
5923 : &f0, &f1);
5924 5397 : real_convert (&result, mode, &value);
5925 :
5926 : /* Don't constant fold this floating point operation if
5927 : the result has overflowed and flag_trapping_math. */
5928 :
5929 5397 : if (flag_trapping_math
5930 20916 : && MODE_HAS_INFINITIES (mode)
5931 5229 : && REAL_VALUE_ISINF (result)
5932 1141 : && !REAL_VALUE_ISINF (f0)
5933 6524 : && !REAL_VALUE_ISINF (f1))
5934 : /* Overflow plus exception. */
5935 1127 : return 0;
5936 :
5937 : /* Don't constant fold this floating point operation if the
5938 : result may dependent upon the run-time rounding mode and
5939 : flag_rounding_math is set, or if GCC's software emulation
5940 : is unable to accurately represent the result. */
5941 :
5942 4270 : if ((flag_rounding_math
5943 27587 : || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
5944 4270 : && (inexact || !real_identical (&result, &value)))
5945 : return NULL_RTX;
5946 :
5947 3892 : return const_double_from_real_value (result, mode);
5948 : }
5949 : }
5950 :
5951 : /* We can fold some multi-word operations. */
5952 493957089 : scalar_int_mode int_mode;
5953 493957089 : if (is_a <scalar_int_mode> (mode, &int_mode)
5954 422867769 : && CONST_SCALAR_INT_P (op0)
5955 41177849 : && CONST_SCALAR_INT_P (op1)
5956 34048800 : && GET_MODE_PRECISION (int_mode) <= MAX_BITSIZE_MODE_ANY_INT)
5957 : {
5958 34048800 : wide_int result;
5959 34048800 : wi::overflow_type overflow;
5960 34048800 : rtx_mode_t pop0 = rtx_mode_t (op0, int_mode);
5961 34048800 : rtx_mode_t pop1 = rtx_mode_t (op1, int_mode);
5962 :
5963 : #if TARGET_SUPPORTS_WIDE_INT == 0
5964 : /* This assert keeps the simplification from producing a result
5965 : that cannot be represented in a CONST_DOUBLE but a lot of
5966 : upstream callers expect that this function never fails to
5967 : simplify something and so you if you added this to the test
5968 : above the code would die later anyway. If this assert
5969 : happens, you just need to make the port support wide int. */
5970 : gcc_assert (GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_DOUBLE_INT);
5971 : #endif
5972 34048800 : switch (code)
5973 : {
5974 1092954 : case MINUS:
5975 1092954 : result = wi::sub (pop0, pop1);
5976 1092954 : break;
5977 :
5978 26603637 : case PLUS:
5979 26603637 : result = wi::add (pop0, pop1);
5980 26603637 : break;
5981 :
5982 308294 : case MULT:
5983 308294 : result = wi::mul (pop0, pop1);
5984 308294 : break;
5985 :
5986 9138 : case DIV:
5987 9138 : result = wi::div_trunc (pop0, pop1, SIGNED, &overflow);
5988 9138 : if (overflow)
5989 : return NULL_RTX;
5990 : break;
5991 :
5992 1201 : case MOD:
5993 1201 : result = wi::mod_trunc (pop0, pop1, SIGNED, &overflow);
5994 1201 : if (overflow)
5995 : return NULL_RTX;
5996 : break;
5997 :
5998 6266 : case UDIV:
5999 6266 : result = wi::div_trunc (pop0, pop1, UNSIGNED, &overflow);
6000 6266 : if (overflow)
6001 : return NULL_RTX;
6002 : break;
6003 :
6004 16317 : case UMOD:
6005 16317 : result = wi::mod_trunc (pop0, pop1, UNSIGNED, &overflow);
6006 16317 : if (overflow)
6007 : return NULL_RTX;
6008 : break;
6009 :
6010 728634 : case AND:
6011 728634 : result = wi::bit_and (pop0, pop1);
6012 728634 : break;
6013 :
6014 284120 : case IOR:
6015 284120 : result = wi::bit_or (pop0, pop1);
6016 284120 : break;
6017 :
6018 44055 : case XOR:
6019 44055 : result = wi::bit_xor (pop0, pop1);
6020 44055 : break;
6021 :
6022 1763 : case SMIN:
6023 1763 : result = wi::smin (pop0, pop1);
6024 1763 : break;
6025 :
6026 1994 : case SMAX:
6027 1994 : result = wi::smax (pop0, pop1);
6028 1994 : break;
6029 :
6030 3205 : case UMIN:
6031 3205 : result = wi::umin (pop0, pop1);
6032 3205 : break;
6033 :
6034 2858 : case UMAX:
6035 2858 : result = wi::umax (pop0, pop1);
6036 2858 : break;
6037 :
6038 4904234 : case LSHIFTRT:
6039 4904234 : case ASHIFTRT:
6040 4904234 : case ASHIFT:
6041 4904234 : case SS_ASHIFT:
6042 4904234 : case US_ASHIFT:
6043 4904234 : {
6044 : /* The shift count might be in SImode while int_mode might
6045 : be narrower. On IA-64 it is even DImode. If the shift
6046 : count is too large and doesn't fit into int_mode, we'd
6047 : ICE. So, if int_mode is narrower than
6048 : HOST_BITS_PER_WIDE_INT, use DImode for the shift count. */
6049 4904234 : if (GET_MODE (op1) == VOIDmode
6050 4904234 : && GET_MODE_PRECISION (int_mode) < HOST_BITS_PER_WIDE_INT)
6051 1858522 : pop1 = rtx_mode_t (op1, DImode);
6052 :
6053 4904234 : wide_int wop1 = pop1;
6054 4904234 : if (SHIFT_COUNT_TRUNCATED)
6055 : wop1 = wi::umod_trunc (wop1, GET_MODE_PRECISION (int_mode));
6056 4904234 : else if (wi::geu_p (wop1, GET_MODE_PRECISION (int_mode)))
6057 64 : return NULL_RTX;
6058 :
6059 4904170 : switch (code)
6060 : {
6061 2797287 : case LSHIFTRT:
6062 2797287 : result = wi::lrshift (pop0, wop1);
6063 2797287 : break;
6064 :
6065 82024 : case ASHIFTRT:
6066 82024 : result = wi::arshift (pop0, wop1);
6067 82024 : break;
6068 :
6069 2024859 : case ASHIFT:
6070 2024859 : result = wi::lshift (pop0, wop1);
6071 2024859 : break;
6072 :
6073 0 : case SS_ASHIFT:
6074 0 : if (wi::leu_p (wop1, wi::clrsb (pop0)))
6075 0 : result = wi::lshift (pop0, wop1);
6076 0 : else if (wi::neg_p (pop0))
6077 0 : result = wi::min_value (int_mode, SIGNED);
6078 : else
6079 0 : result = wi::max_value (int_mode, SIGNED);
6080 : break;
6081 :
6082 0 : case US_ASHIFT:
6083 0 : if (wi::eq_p (pop0, 0))
6084 0 : result = pop0;
6085 0 : else if (wi::leu_p (wop1, wi::clz (pop0)))
6086 0 : result = wi::lshift (pop0, wop1);
6087 : else
6088 0 : result = wi::max_value (int_mode, UNSIGNED);
6089 : break;
6090 :
6091 : default:
6092 : gcc_unreachable ();
6093 : }
6094 4904170 : break;
6095 4904234 : }
6096 31568 : case ROTATE:
6097 31568 : case ROTATERT:
6098 31568 : {
6099 : /* The rotate count might be in SImode while int_mode might
6100 : be narrower. On IA-64 it is even DImode. If the shift
6101 : count is too large and doesn't fit into int_mode, we'd
6102 : ICE. So, if int_mode is narrower than
6103 : HOST_BITS_PER_WIDE_INT, use DImode for the shift count. */
6104 31568 : if (GET_MODE (op1) == VOIDmode
6105 31568 : && GET_MODE_PRECISION (int_mode) < HOST_BITS_PER_WIDE_INT)
6106 23782 : pop1 = rtx_mode_t (op1, DImode);
6107 :
6108 31568 : if (wi::neg_p (pop1))
6109 : return NULL_RTX;
6110 :
6111 31468 : switch (code)
6112 : {
6113 10480 : case ROTATE:
6114 10480 : result = wi::lrotate (pop0, pop1);
6115 10480 : break;
6116 :
6117 20988 : case ROTATERT:
6118 20988 : result = wi::rrotate (pop0, pop1);
6119 20988 : break;
6120 :
6121 : default:
6122 : gcc_unreachable ();
6123 : }
6124 : break;
6125 : }
6126 :
6127 2270 : case SS_PLUS:
6128 2270 : result = wi::add (pop0, pop1, SIGNED, &overflow);
6129 4484 : clamp_signed_saturation:
6130 4484 : if (overflow == wi::OVF_OVERFLOW)
6131 314 : result = wi::max_value (GET_MODE_PRECISION (int_mode), SIGNED);
6132 4170 : else if (overflow == wi::OVF_UNDERFLOW)
6133 278 : result = wi::min_value (GET_MODE_PRECISION (int_mode), SIGNED);
6134 3892 : else if (overflow != wi::OVF_NONE)
6135 : return NULL_RTX;
6136 : break;
6137 :
6138 2220 : case US_PLUS:
6139 2220 : result = wi::add (pop0, pop1, UNSIGNED, &overflow);
6140 2220 : clamp_unsigned_saturation:
6141 2220 : if (overflow != wi::OVF_NONE)
6142 461 : result = wi::max_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
6143 : break;
6144 :
6145 2214 : case SS_MINUS:
6146 2214 : result = wi::sub (pop0, pop1, SIGNED, &overflow);
6147 2214 : goto clamp_signed_saturation;
6148 :
6149 1852 : case US_MINUS:
6150 1852 : result = wi::sub (pop0, pop1, UNSIGNED, &overflow);
6151 1852 : if (overflow != wi::OVF_NONE)
6152 1203 : result = wi::min_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
6153 : break;
6154 :
6155 0 : case SS_MULT:
6156 0 : result = wi::mul (pop0, pop1, SIGNED, &overflow);
6157 0 : goto clamp_signed_saturation;
6158 :
6159 0 : case US_MULT:
6160 0 : result = wi::mul (pop0, pop1, UNSIGNED, &overflow);
6161 0 : goto clamp_unsigned_saturation;
6162 :
6163 6 : case SMUL_HIGHPART:
6164 6 : result = wi::mul_high (pop0, pop1, SIGNED);
6165 6 : break;
6166 :
6167 0 : case UMUL_HIGHPART:
6168 0 : result = wi::mul_high (pop0, pop1, UNSIGNED);
6169 0 : break;
6170 :
6171 : default:
6172 : return NULL_RTX;
6173 : }
6174 34046484 : return immed_wide_int_const (result, int_mode);
6175 34048800 : }
6176 :
6177 : /* Handle polynomial integers. */
6178 : if (NUM_POLY_INT_COEFFS > 1
6179 : && is_a <scalar_int_mode> (mode, &int_mode)
6180 : && poly_int_rtx_p (op0)
6181 : && poly_int_rtx_p (op1))
6182 : {
6183 : poly_wide_int result;
6184 : switch (code)
6185 : {
6186 : case PLUS:
6187 : result = wi::to_poly_wide (op0, mode) + wi::to_poly_wide (op1, mode);
6188 : break;
6189 :
6190 : case MINUS:
6191 : result = wi::to_poly_wide (op0, mode) - wi::to_poly_wide (op1, mode);
6192 : break;
6193 :
6194 : case MULT:
6195 : if (CONST_SCALAR_INT_P (op1))
6196 : result = wi::to_poly_wide (op0, mode) * rtx_mode_t (op1, mode);
6197 : else
6198 : return NULL_RTX;
6199 : break;
6200 :
6201 : case ASHIFT:
6202 : if (CONST_SCALAR_INT_P (op1))
6203 : {
6204 : wide_int shift
6205 : = rtx_mode_t (op1,
6206 : GET_MODE (op1) == VOIDmode
6207 : && (GET_MODE_PRECISION (int_mode)
6208 : < HOST_BITS_PER_WIDE_INT)
6209 : ? DImode : mode);
6210 : if (SHIFT_COUNT_TRUNCATED)
6211 : shift = wi::umod_trunc (shift, GET_MODE_PRECISION (int_mode));
6212 : else if (wi::geu_p (shift, GET_MODE_PRECISION (int_mode)))
6213 : return NULL_RTX;
6214 : result = wi::to_poly_wide (op0, mode) << shift;
6215 : }
6216 : else
6217 : return NULL_RTX;
6218 : break;
6219 :
6220 : case IOR:
6221 : if (!CONST_SCALAR_INT_P (op1)
6222 : || !can_ior_p (wi::to_poly_wide (op0, mode),
6223 : rtx_mode_t (op1, mode), &result))
6224 : return NULL_RTX;
6225 : break;
6226 :
6227 : default:
6228 : return NULL_RTX;
6229 : }
6230 : return immed_wide_int_const (result, int_mode);
6231 : }
6232 :
6233 : return NULL_RTX;
6234 : }
6235 :
6236 :
6237 :
6238 : /* Return a positive integer if X should sort after Y. The value
6239 : returned is 1 if and only if X and Y are both regs. */
6240 :
6241 : static int
6242 117320595 : simplify_plus_minus_op_data_cmp (rtx x, rtx y)
6243 : {
6244 117320595 : int result;
6245 :
6246 117320595 : result = (commutative_operand_precedence (y)
6247 117320595 : - commutative_operand_precedence (x));
6248 117320595 : if (result)
6249 81936993 : return result + result;
6250 :
6251 : /* Group together equal REGs to do more simplification. */
6252 35383602 : if (REG_P (x) && REG_P (y))
6253 8699824 : return REGNO (x) > REGNO (y);
6254 :
6255 : return 0;
6256 : }
6257 :
6258 : /* Simplify and canonicalize a PLUS or MINUS, at least one of whose
6259 : operands may be another PLUS or MINUS.
6260 :
6261 : Rather than test for specific case, we do this by a brute-force method
6262 : and do all possible simplifications until no more changes occur. Then
6263 : we rebuild the operation.
6264 :
6265 : May return NULL_RTX when no changes were made. */
6266 :
6267 : rtx
6268 39552649 : simplify_context::simplify_plus_minus (rtx_code code, machine_mode mode,
6269 : rtx op0, rtx op1)
6270 : {
6271 39552649 : struct simplify_plus_minus_op_data
6272 : {
6273 : rtx op;
6274 : short neg;
6275 : } ops[16];
6276 39552649 : rtx result, tem;
6277 39552649 : int n_ops = 2;
6278 39552649 : int changed, n_constants, canonicalized = 0;
6279 39552649 : int i, j;
6280 :
6281 39552649 : memset (ops, 0, sizeof ops);
6282 :
6283 : /* Set up the two operands and then expand them until nothing has been
6284 : changed. If we run out of room in our array, give up; this should
6285 : almost never happen. */
6286 :
6287 39552649 : ops[0].op = op0;
6288 39552649 : ops[0].neg = 0;
6289 39552649 : ops[1].op = op1;
6290 39552649 : ops[1].neg = (code == MINUS);
6291 :
6292 80419473 : do
6293 : {
6294 80419473 : changed = 0;
6295 80419473 : n_constants = 0;
6296 :
6297 325512627 : for (i = 0; i < n_ops; i++)
6298 : {
6299 245093174 : rtx this_op = ops[i].op;
6300 245093174 : int this_neg = ops[i].neg;
6301 245093174 : enum rtx_code this_code = GET_CODE (this_op);
6302 :
6303 245093174 : switch (this_code)
6304 : {
6305 39879524 : case PLUS:
6306 39879524 : case MINUS:
6307 39879524 : if (n_ops == ARRAY_SIZE (ops))
6308 : return NULL_RTX;
6309 :
6310 39879504 : ops[n_ops].op = XEXP (this_op, 1);
6311 39879504 : ops[n_ops].neg = (this_code == MINUS) ^ this_neg;
6312 39879504 : n_ops++;
6313 :
6314 39879504 : ops[i].op = XEXP (this_op, 0);
6315 39879504 : changed = 1;
6316 : /* If this operand was negated then we will potentially
6317 : canonicalize the expression. Similarly if we don't
6318 : place the operands adjacent we're re-ordering the
6319 : expression and thus might be performing a
6320 : canonicalization. Ignore register re-ordering.
6321 : ??? It might be better to shuffle the ops array here,
6322 : but then (plus (plus (A, B), plus (C, D))) wouldn't
6323 : be seen as non-canonical. */
6324 39879504 : if (this_neg
6325 39171627 : || (i != n_ops - 2
6326 38497549 : && !(REG_P (ops[i].op) && REG_P (ops[n_ops - 1].op))))
6327 245093154 : canonicalized = 1;
6328 : break;
6329 :
6330 2061 : case NEG:
6331 2061 : ops[i].op = XEXP (this_op, 0);
6332 2061 : ops[i].neg = ! this_neg;
6333 2061 : changed = 1;
6334 2061 : canonicalized = 1;
6335 2061 : break;
6336 :
6337 1610321 : case CONST:
6338 1610321 : if (n_ops != ARRAY_SIZE (ops)
6339 1610321 : && GET_CODE (XEXP (this_op, 0)) == PLUS
6340 1476807 : && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
6341 1455983 : && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
6342 : {
6343 1455983 : ops[i].op = XEXP (XEXP (this_op, 0), 0);
6344 1455983 : ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
6345 1455983 : ops[n_ops].neg = this_neg;
6346 1455983 : n_ops++;
6347 1455983 : changed = 1;
6348 1455983 : canonicalized = 1;
6349 : }
6350 : break;
6351 :
6352 66225 : case NOT:
6353 : /* ~a -> (-a - 1) */
6354 66225 : if (n_ops != ARRAY_SIZE (ops))
6355 : {
6356 66225 : ops[n_ops].op = CONSTM1_RTX (mode);
6357 66225 : ops[n_ops++].neg = this_neg;
6358 66225 : ops[i].op = XEXP (this_op, 0);
6359 66225 : ops[i].neg = !this_neg;
6360 66225 : changed = 1;
6361 66225 : canonicalized = 1;
6362 : }
6363 : break;
6364 :
6365 122165456 : CASE_CONST_SCALAR_INT:
6366 122165456 : case CONST_POLY_INT:
6367 122165456 : n_constants++;
6368 122165456 : if (this_neg)
6369 : {
6370 1212606 : ops[i].op = neg_poly_int_rtx (mode, this_op);
6371 1212606 : ops[i].neg = 0;
6372 1212606 : changed = 1;
6373 1212606 : canonicalized = 1;
6374 : }
6375 : break;
6376 :
6377 : default:
6378 : break;
6379 : }
6380 : }
6381 : }
6382 80419453 : while (changed);
6383 :
6384 39552629 : if (n_constants > 1)
6385 24193677 : canonicalized = 1;
6386 :
6387 39552629 : gcc_assert (n_ops >= 2);
6388 :
6389 : /* If we only have two operands, we can avoid the loops. */
6390 39552629 : if (n_ops == 2)
6391 : {
6392 0 : enum rtx_code code = ops[0].neg || ops[1].neg ? MINUS : PLUS;
6393 0 : rtx lhs, rhs;
6394 :
6395 : /* Get the two operands. Be careful with the order, especially for
6396 : the cases where code == MINUS. */
6397 0 : if (ops[0].neg && ops[1].neg)
6398 : {
6399 0 : lhs = gen_rtx_NEG (mode, ops[0].op);
6400 0 : rhs = ops[1].op;
6401 : }
6402 0 : else if (ops[0].neg)
6403 : {
6404 0 : lhs = ops[1].op;
6405 0 : rhs = ops[0].op;
6406 : }
6407 : else
6408 : {
6409 0 : lhs = ops[0].op;
6410 0 : rhs = ops[1].op;
6411 : }
6412 :
6413 0 : return simplify_const_binary_operation (code, mode, lhs, rhs);
6414 : }
6415 :
6416 : /* Now simplify each pair of operands until nothing changes. */
6417 64747218 : while (1)
6418 : {
6419 : /* Insertion sort is good enough for a small array. */
6420 171345413 : for (i = 1; i < n_ops; i++)
6421 : {
6422 106598195 : struct simplify_plus_minus_op_data save;
6423 106598195 : int cmp;
6424 :
6425 106598195 : j = i - 1;
6426 106598195 : cmp = simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op);
6427 106598195 : if (cmp <= 0)
6428 93758756 : continue;
6429 : /* Just swapping registers doesn't count as canonicalization. */
6430 12839439 : if (cmp != 1)
6431 9860560 : canonicalized = 1;
6432 :
6433 12839439 : save = ops[i];
6434 15220640 : do
6435 15220640 : ops[j + 1] = ops[j];
6436 15220640 : while (j--
6437 28060079 : && simplify_plus_minus_op_data_cmp (ops[j].op, save.op) > 0);
6438 12839439 : ops[j + 1] = save;
6439 : }
6440 :
6441 64747218 : changed = 0;
6442 171345413 : for (i = n_ops - 1; i > 0; i--)
6443 255751625 : for (j = i - 1; j >= 0; j--)
6444 : {
6445 150053969 : rtx lhs = ops[j].op, rhs = ops[i].op;
6446 150053969 : int lneg = ops[j].neg, rneg = ops[i].neg;
6447 :
6448 150053969 : if (lhs != 0 && rhs != 0)
6449 : {
6450 124106437 : enum rtx_code ncode = PLUS;
6451 :
6452 124106437 : if (lneg != rneg)
6453 : {
6454 11710906 : ncode = MINUS;
6455 11710906 : if (lneg)
6456 7380812 : std::swap (lhs, rhs);
6457 : }
6458 112395531 : else if (swap_commutative_operands_p (lhs, rhs))
6459 423365 : std::swap (lhs, rhs);
6460 :
6461 124106437 : if ((GET_CODE (lhs) == CONST || CONST_INT_P (lhs))
6462 29157629 : && (GET_CODE (rhs) == CONST || CONST_INT_P (rhs)))
6463 : {
6464 24347259 : rtx tem_lhs, tem_rhs;
6465 :
6466 24347259 : tem_lhs = GET_CODE (lhs) == CONST ? XEXP (lhs, 0) : lhs;
6467 24347259 : tem_rhs = GET_CODE (rhs) == CONST ? XEXP (rhs, 0) : rhs;
6468 24347259 : tem = simplify_binary_operation (ncode, mode, tem_lhs,
6469 : tem_rhs);
6470 :
6471 24347259 : if (tem && !CONSTANT_P (tem))
6472 1757 : tem = gen_rtx_CONST (GET_MODE (tem), tem);
6473 : }
6474 : else
6475 99759178 : tem = simplify_binary_operation (ncode, mode, lhs, rhs);
6476 :
6477 99760935 : if (tem)
6478 : {
6479 : /* Reject "simplifications" that just wrap the two
6480 : arguments in a CONST. Failure to do so can result
6481 : in infinite recursion with simplify_binary_operation
6482 : when it calls us to simplify CONST operations.
6483 : Also, if we find such a simplification, don't try
6484 : any more combinations with this rhs: We must have
6485 : something like symbol+offset, ie. one of the
6486 : trivial CONST expressions we handle later. */
6487 26532345 : if (GET_CODE (tem) == CONST
6488 902296 : && GET_CODE (XEXP (tem, 0)) == ncode
6489 901744 : && XEXP (XEXP (tem, 0), 0) == lhs
6490 900539 : && XEXP (XEXP (tem, 0), 1) == rhs)
6491 : break;
6492 25631806 : lneg &= rneg;
6493 25631806 : if (GET_CODE (tem) == NEG)
6494 45208 : tem = XEXP (tem, 0), lneg = !lneg;
6495 25631806 : if (poly_int_rtx_p (tem) && lneg)
6496 0 : tem = neg_poly_int_rtx (mode, tem), lneg = 0;
6497 :
6498 25631806 : ops[i].op = tem;
6499 25631806 : ops[i].neg = lneg;
6500 25631806 : ops[j].op = NULL_RTX;
6501 25631806 : changed = 1;
6502 25631806 : canonicalized = 1;
6503 : }
6504 : }
6505 : }
6506 :
6507 64747218 : if (!changed)
6508 : break;
6509 :
6510 : /* Pack all the operands to the lower-numbered entries. */
6511 101665118 : for (i = 0, j = 0; j < n_ops; j++)
6512 76470529 : if (ops[j].op)
6513 : {
6514 50838723 : ops[i] = ops[j];
6515 50838723 : i++;
6516 : }
6517 : n_ops = i;
6518 : }
6519 :
6520 : /* If nothing changed, check that rematerialization of rtl instructions
6521 : is still required. */
6522 39552629 : if (!canonicalized)
6523 : {
6524 : /* Perform rematerialization if only all operands are registers and
6525 : all operations are PLUS. */
6526 : /* ??? Also disallow (non-global, non-frame) fixed registers to work
6527 : around rs6000 and how it uses the CA register. See PR67145. */
6528 5073028 : for (i = 0; i < n_ops; i++)
6529 4095460 : if (ops[i].neg
6530 3810166 : || !REG_P (ops[i].op)
6531 7343357 : || (REGNO (ops[i].op) < FIRST_PSEUDO_REGISTER
6532 317736 : && fixed_regs[REGNO (ops[i].op)]
6533 238 : && !global_regs[REGNO (ops[i].op)]
6534 238 : && ops[i].op != frame_pointer_rtx
6535 118 : && ops[i].op != arg_pointer_rtx
6536 105 : && ops[i].op != stack_pointer_rtx))
6537 : return NULL_RTX;
6538 977568 : goto gen_result;
6539 : }
6540 :
6541 : /* Create (minus -C X) instead of (neg (const (plus X C))). */
6542 37727498 : if (n_ops == 2
6543 23609874 : && CONST_INT_P (ops[1].op)
6544 22943435 : && CONSTANT_P (ops[0].op)
6545 162 : && ops[0].neg)
6546 56 : return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
6547 :
6548 : /* We suppressed creation of trivial CONST expressions in the
6549 : combination loop to avoid recursion. Create one manually now.
6550 : The combination loop should have ensured that there is exactly
6551 : one CONST_INT, and the sort will have ensured that it is last
6552 : in the array and that any other constant will be next-to-last. */
6553 :
6554 37727442 : if (n_ops > 1
6555 37224250 : && poly_int_rtx_p (ops[n_ops - 1].op)
6556 72227339 : && CONSTANT_P (ops[n_ops - 2].op))
6557 : {
6558 1532466 : rtx value = ops[n_ops - 1].op;
6559 1532466 : if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg)
6560 710312 : value = neg_poly_int_rtx (mode, value);
6561 1532466 : if (CONST_INT_P (value))
6562 : {
6563 3064932 : ops[n_ops - 2].op = plus_constant (mode, ops[n_ops - 2].op,
6564 1532466 : INTVAL (value));
6565 1532466 : n_ops--;
6566 : }
6567 : }
6568 :
6569 : /* Put a non-negated operand first, if possible. */
6570 :
6571 39472628 : for (i = 0; i < n_ops && ops[i].neg; i++)
6572 1745186 : continue;
6573 37727442 : if (i == n_ops)
6574 9099 : ops[0].op = gen_rtx_NEG (mode, ops[0].op);
6575 37718343 : else if (i != 0)
6576 : {
6577 1639178 : tem = ops[0].op;
6578 1639178 : ops[0] = ops[i];
6579 1639178 : ops[i].op = tem;
6580 1639178 : ops[i].neg = 1;
6581 : }
6582 :
6583 : /* Now make the result by performing the requested operations. */
6584 36079165 : gen_result:
6585 38705010 : result = ops[0].op;
6586 90790955 : for (i = 1; i < n_ops; i++)
6587 104171890 : result = gen_rtx_fmt_ee (ops[i].neg ? MINUS : PLUS,
6588 : mode, result, ops[i].op);
6589 :
6590 : return result;
6591 1745186 : }
6592 :
6593 : /* Check whether an operand is suitable for calling simplify_plus_minus. */
6594 : static bool
6595 537859232 : plus_minus_operand_p (const_rtx x)
6596 : {
6597 537859232 : return GET_CODE (x) == PLUS
6598 537859232 : || GET_CODE (x) == MINUS
6599 537859232 : || (GET_CODE (x) == CONST
6600 1971333 : && GET_CODE (XEXP (x, 0)) == PLUS
6601 1348312 : && CONSTANT_P (XEXP (XEXP (x, 0), 0))
6602 1274387 : && CONSTANT_P (XEXP (XEXP (x, 0), 1)));
6603 : }
6604 :
6605 : /* Like simplify_binary_operation except used for relational operators.
6606 : MODE is the mode of the result. If MODE is VOIDmode, both operands must
6607 : not also be VOIDmode.
6608 :
6609 : CMP_MODE specifies in which mode the comparison is done in, so it is
6610 : the mode of the operands. If CMP_MODE is VOIDmode, it is taken from
6611 : the operands or, if both are VOIDmode, the operands are compared in
6612 : "infinite precision". */
6613 : rtx
6614 132131639 : simplify_context::simplify_relational_operation (rtx_code code,
6615 : machine_mode mode,
6616 : machine_mode cmp_mode,
6617 : rtx op0, rtx op1)
6618 : {
6619 132131639 : rtx tem, trueop0, trueop1;
6620 :
6621 132131639 : if (cmp_mode == VOIDmode)
6622 29190095 : cmp_mode = GET_MODE (op0);
6623 29190095 : if (cmp_mode == VOIDmode)
6624 272817 : cmp_mode = GET_MODE (op1);
6625 :
6626 132131639 : tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
6627 132131639 : if (tem)
6628 785485 : return relational_result (mode, cmp_mode, tem);
6629 :
6630 : /* For the following tests, ensure const0_rtx is op1. */
6631 131346154 : if (swap_commutative_operands_p (op0, op1)
6632 131346154 : || (op0 == const0_rtx && op1 != const0_rtx))
6633 2751804 : std::swap (op0, op1), code = swap_condition (code);
6634 :
6635 : /* If op0 is a compare, extract the comparison arguments from it. */
6636 131346154 : if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
6637 14356617 : return simplify_gen_relational (code, mode, VOIDmode,
6638 14356617 : XEXP (op0, 0), XEXP (op0, 1));
6639 :
6640 116989537 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
6641 : return NULL_RTX;
6642 :
6643 85978329 : trueop0 = avoid_constant_pool_reference (op0);
6644 85978329 : trueop1 = avoid_constant_pool_reference (op1);
6645 85978329 : return simplify_relational_operation_1 (code, mode, cmp_mode,
6646 85978329 : trueop0, trueop1);
6647 : }
6648 :
6649 : /* This part of simplify_relational_operation is only used when CMP_MODE
6650 : is not in class MODE_CC (i.e. it is a real comparison).
6651 :
6652 : MODE is the mode of the result, while CMP_MODE specifies in which
6653 : mode the comparison is done in, so it is the mode of the operands. */
6654 :
6655 : rtx
6656 85978329 : simplify_context::simplify_relational_operation_1 (rtx_code code,
6657 : machine_mode mode,
6658 : machine_mode cmp_mode,
6659 : rtx op0, rtx op1)
6660 : {
6661 85978329 : enum rtx_code op0code = GET_CODE (op0);
6662 :
6663 85978329 : if (op1 == const0_rtx && COMPARISON_P (op0))
6664 : {
6665 : /* If op0 is a comparison, extract the comparison arguments
6666 : from it. */
6667 300638 : if (code == NE)
6668 : {
6669 133359 : if (GET_MODE (op0) == mode)
6670 187 : return simplify_rtx (op0);
6671 : else
6672 133172 : return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
6673 133172 : XEXP (op0, 0), XEXP (op0, 1));
6674 : }
6675 167279 : else if (code == EQ)
6676 : {
6677 134836 : enum rtx_code new_code = reversed_comparison_code (op0, NULL);
6678 134836 : if (new_code != UNKNOWN)
6679 134519 : return simplify_gen_relational (new_code, mode, VOIDmode,
6680 134519 : XEXP (op0, 0), XEXP (op0, 1));
6681 : }
6682 : }
6683 :
6684 : /* (LTU/GEU (PLUS a C) C), where C is constant, can be simplified to
6685 : (GEU/LTU a -C). Likewise for (LTU/GEU (PLUS a C) a). */
6686 85710451 : if ((code == LTU || code == GEU)
6687 5188680 : && GET_CODE (op0) == PLUS
6688 633784 : && CONST_INT_P (XEXP (op0, 1))
6689 421039 : && (rtx_equal_p (op1, XEXP (op0, 0))
6690 282076 : || rtx_equal_p (op1, XEXP (op0, 1)))
6691 : /* (LTU/GEU (PLUS a 0) 0) is not the same as (GEU/LTU a 0). */
6692 85913065 : && XEXP (op0, 1) != const0_rtx)
6693 : {
6694 202614 : rtx new_cmp
6695 202614 : = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
6696 204175 : return simplify_gen_relational ((code == LTU ? GEU : LTU), mode,
6697 202614 : cmp_mode, XEXP (op0, 0), new_cmp);
6698 : }
6699 :
6700 : /* (GTU (PLUS a C) (C - 1)) where C is a non-zero constant can be
6701 : transformed into (LTU a -C). */
6702 85507837 : if (code == GTU && GET_CODE (op0) == PLUS && CONST_INT_P (op1)
6703 325308 : && CONST_INT_P (XEXP (op0, 1))
6704 244594 : && (UINTVAL (op1) == UINTVAL (XEXP (op0, 1)) - 1)
6705 20045 : && XEXP (op0, 1) != const0_rtx)
6706 : {
6707 20045 : rtx new_cmp
6708 20045 : = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
6709 20045 : return simplify_gen_relational (LTU, mode, cmp_mode,
6710 20045 : XEXP (op0, 0), new_cmp);
6711 : }
6712 :
6713 : /* Canonicalize (LTU/GEU (PLUS a b) b) as (LTU/GEU (PLUS a b) a). */
6714 85487792 : if ((code == LTU || code == GEU)
6715 4986066 : && GET_CODE (op0) == PLUS
6716 431170 : && rtx_equal_p (op1, XEXP (op0, 1))
6717 : /* Don't recurse "infinitely" for (LTU/GEU (PLUS b b) b). */
6718 85494440 : && !rtx_equal_p (op1, XEXP (op0, 0)))
6719 6648 : return simplify_gen_relational (code, mode, cmp_mode, op0,
6720 6648 : copy_rtx (XEXP (op0, 0)));
6721 :
6722 85481144 : if (op1 == const0_rtx)
6723 : {
6724 : /* Canonicalize (GTU x 0) as (NE x 0). */
6725 37382681 : if (code == GTU)
6726 76812 : return simplify_gen_relational (NE, mode, cmp_mode, op0, op1);
6727 : /* Canonicalize (LEU x 0) as (EQ x 0). */
6728 37305869 : if (code == LEU)
6729 33039 : return simplify_gen_relational (EQ, mode, cmp_mode, op0, op1);
6730 :
6731 37272830 : if ((code == NE || code == EQ)
6732 : /* Verify op0 is IOR */
6733 33493939 : && GET_CODE (op0) == IOR
6734 : /* only enters if op1 is 0 */
6735 : /* Verify IOR operand is NE */
6736 601417 : && GET_CODE (XEXP (op0, 0)) == NE
6737 21018 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) == cmp_mode
6738 : /* Verify second NE operand is 0 */
6739 348 : && XEXP (XEXP (op0, 0), 1) == CONST0_RTX (cmp_mode))
6740 : {
6741 31 : rtx t = gen_rtx_IOR (cmp_mode, XEXP (XEXP (op0, 0), 0), XEXP (op0, 1));
6742 31 : t = gen_rtx_fmt_ee (code, mode, t, CONST0_RTX (mode));
6743 31 : return t;
6744 : }
6745 :
6746 : }
6747 48098463 : else if (op1 == const1_rtx)
6748 : {
6749 3276877 : switch (code)
6750 : {
6751 10139 : case GE:
6752 : /* Canonicalize (GE x 1) as (GT x 0). */
6753 10139 : return simplify_gen_relational (GT, mode, cmp_mode,
6754 10139 : op0, const0_rtx);
6755 195146 : case GEU:
6756 : /* Canonicalize (GEU x 1) as (NE x 0). */
6757 195146 : return simplify_gen_relational (NE, mode, cmp_mode,
6758 195146 : op0, const0_rtx);
6759 10582 : case LT:
6760 : /* Canonicalize (LT x 1) as (LE x 0). */
6761 10582 : return simplify_gen_relational (LE, mode, cmp_mode,
6762 10582 : op0, const0_rtx);
6763 53067 : case LTU:
6764 : /* Canonicalize (LTU x 1) as (EQ x 0). */
6765 53067 : return simplify_gen_relational (EQ, mode, cmp_mode,
6766 53067 : op0, const0_rtx);
6767 : default:
6768 : break;
6769 : }
6770 : }
6771 44821586 : else if (op1 == constm1_rtx)
6772 : {
6773 : /* Canonicalize (LE x -1) as (LT x 0). */
6774 1160783 : if (code == LE)
6775 1566 : return simplify_gen_relational (LT, mode, cmp_mode, op0, const0_rtx);
6776 : /* Canonicalize (GT x -1) as (GE x 0). */
6777 1159217 : if (code == GT)
6778 5166 : return simplify_gen_relational (GE, mode, cmp_mode, op0, const0_rtx);
6779 : }
6780 :
6781 : /* (eq/ne (plus x cst1) cst2) simplifies to (eq/ne x (cst2 - cst1)) */
6782 81316705 : if ((code == EQ || code == NE)
6783 63275944 : && (op0code == PLUS || op0code == MINUS)
6784 2514712 : && CONSTANT_P (op1)
6785 913577 : && CONSTANT_P (XEXP (op0, 1))
6786 511955 : && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
6787 : {
6788 511921 : rtx x = XEXP (op0, 0);
6789 511921 : rtx c = XEXP (op0, 1);
6790 511921 : enum rtx_code invcode = op0code == PLUS ? MINUS : PLUS;
6791 511921 : rtx tem = simplify_gen_binary (invcode, cmp_mode, op1, c);
6792 :
6793 : /* Detect an infinite recursive condition, where we oscillate at this
6794 : simplification case between:
6795 : A + B == C <---> C - B == A,
6796 : where A, B, and C are all constants with non-simplifiable expressions,
6797 : usually SYMBOL_REFs. */
6798 511921 : if (GET_CODE (tem) == invcode
6799 57 : && CONSTANT_P (x)
6800 511939 : && rtx_equal_p (c, XEXP (tem, 1)))
6801 : return NULL_RTX;
6802 :
6803 511903 : return simplify_gen_relational (code, mode, cmp_mode, x, tem);
6804 : }
6805 :
6806 : /* (eq/ne (plus (x) (y)) y) simplifies to (eq/ne x 0). */
6807 62764023 : if ((code == EQ || code == NE)
6808 62764023 : && op0code == PLUS
6809 1662366 : && rtx_equal_p (XEXP (op0, 1), op1)
6810 248 : && !side_effects_p (op1)
6811 248 : && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
6812 224 : return simplify_gen_relational (code, mode, cmp_mode,
6813 224 : XEXP (op0, 0), CONST0_RTX (cmp_mode));
6814 :
6815 : /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is
6816 : the same as (zero_extract:SI FOO (const_int 1) BAR). */
6817 84583451 : scalar_int_mode int_mode, int_cmp_mode;
6818 84583451 : if (code == NE
6819 33791964 : && op1 == const0_rtx
6820 2281567 : && is_int_mode (mode, &int_mode)
6821 86790097 : && is_a <scalar_int_mode> (cmp_mode, &int_cmp_mode)
6822 : /* ??? Work-around BImode bugs in the ia64 backend. */
6823 2281567 : && int_mode != BImode
6824 2281547 : && int_cmp_mode != BImode
6825 2281547 : && nonzero_bits (op0, int_cmp_mode) == 1
6826 84583451 : && STORE_FLAG_VALUE == 1)
6827 149842 : return GET_MODE_SIZE (int_mode) > GET_MODE_SIZE (int_cmp_mode)
6828 74921 : ? simplify_gen_unary (ZERO_EXTEND, int_mode, op0, int_cmp_mode)
6829 18933 : : lowpart_subreg (int_mode, op0, int_cmp_mode);
6830 :
6831 : /* (eq/ne (xor x y) 0) simplifies to (eq/ne x y). */
6832 84508530 : if ((code == EQ || code == NE)
6833 62688878 : && op1 == const0_rtx
6834 33343905 : && op0code == XOR)
6835 14010 : return simplify_gen_relational (code, mode, cmp_mode,
6836 14010 : XEXP (op0, 0), XEXP (op0, 1));
6837 :
6838 : /* (eq/ne (xor x y) x) simplifies to (eq/ne y 0). */
6839 62674868 : if ((code == EQ || code == NE)
6840 62674868 : && op0code == XOR
6841 5341 : && rtx_equal_p (XEXP (op0, 0), op1)
6842 6 : && !side_effects_p (XEXP (op0, 0)))
6843 0 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 1),
6844 0 : CONST0_RTX (mode));
6845 :
6846 : /* Likewise (eq/ne (xor x y) y) simplifies to (eq/ne x 0). */
6847 84494520 : if ((code == EQ || code == NE)
6848 62674868 : && op0code == XOR
6849 5341 : && rtx_equal_p (XEXP (op0, 1), op1)
6850 84494688 : && !side_effects_p (XEXP (op0, 1)))
6851 168 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6852 168 : CONST0_RTX (mode));
6853 :
6854 : /* (eq/ne (xor x C1) C2) simplifies to (eq/ne x (C1^C2)). */
6855 84494352 : if ((code == EQ || code == NE)
6856 62674700 : && op0code == XOR
6857 5173 : && CONST_SCALAR_INT_P (op1)
6858 1409 : && CONST_SCALAR_INT_P (XEXP (op0, 1)))
6859 874 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6860 : simplify_gen_binary (XOR, cmp_mode,
6861 874 : XEXP (op0, 1), op1));
6862 :
6863 : /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or
6864 : constant folding if x/y is a constant. */
6865 62673826 : if ((code == EQ || code == NE)
6866 62673826 : && (op0code == AND || op0code == IOR)
6867 3623886 : && !side_effects_p (op1)
6868 3623780 : && op1 != CONST0_RTX (cmp_mode))
6869 : {
6870 : /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to
6871 : (eq/ne (and (not y) x) 0). */
6872 465468 : if ((op0code == AND && rtx_equal_p (XEXP (op0, 0), op1))
6873 933644 : || (op0code == IOR && rtx_equal_p (XEXP (op0, 1), op1)))
6874 : {
6875 24711 : rtx not_y = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 1),
6876 : cmp_mode);
6877 24711 : rtx lhs = simplify_gen_binary (AND, cmp_mode, not_y, XEXP (op0, 0));
6878 :
6879 24711 : return simplify_gen_relational (code, mode, cmp_mode, lhs,
6880 24711 : CONST0_RTX (cmp_mode));
6881 : }
6882 :
6883 : /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to
6884 : (eq/ne (and (not x) y) 0). */
6885 440840 : if ((op0code == AND && rtx_equal_p (XEXP (op0, 1), op1))
6886 863716 : || (op0code == IOR && rtx_equal_p (XEXP (op0, 0), op1)))
6887 : {
6888 45231 : rtx not_x = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 0),
6889 : cmp_mode);
6890 45231 : rtx lhs = simplify_gen_binary (AND, cmp_mode, not_x, XEXP (op0, 1));
6891 :
6892 45231 : return simplify_gen_relational (code, mode, cmp_mode, lhs,
6893 45231 : CONST0_RTX (cmp_mode));
6894 : }
6895 : }
6896 :
6897 : /* Optimize (cmp (and/ior x C1) C2) depending on the CMP and C1 and C2's
6898 : relationship. */
6899 84423536 : if ((op0code == AND || op0code == IOR)
6900 3803133 : && CONST_INT_P (op1)
6901 3623405 : && CONST_INT_P (XEXP (op0, 1)))
6902 : {
6903 2341168 : unsigned HOST_WIDE_INT c1 = UINTVAL (XEXP (op0, 1));
6904 2341168 : unsigned HOST_WIDE_INT c2 = UINTVAL (op1);
6905 :
6906 : /* For AND operations:
6907 : - (x & c1) == c2 when some bits are set in c2 but not in c1 -> false
6908 : - (x & c1) != c2 when some bits are set in c2 but not in c1 -> true
6909 : - (x & c1) >= c2 when c1 is less than c2 -> false
6910 : - (x & c1) < c2 when c1 is less than c2 -> true
6911 : - (x & c1) > c2 when c1 is less than or equal to c2 -> false
6912 : - (x & c1) <= c2 when c1 is less than or equal to c2 -> true
6913 :
6914 : For IOR operations:
6915 : - (x | c1) == c2 when some bits are set in c1 but not in c2 -> false
6916 : - (x | c1) != c2 when some bits are set in c1 but not in c2 -> true
6917 : - (x | c1) <= c2 when c1 is greater than c2 -> false
6918 : - (x | c1) > c2 when c1 is greater than c2 -> true
6919 : - (x | c1) < c2 when c1 is greater than or equal to c2 -> false
6920 : - (x | c1) >= c2 when c1 is greater than or equal to c2 -> true */
6921 2341168 : if ((op0code == AND
6922 2336929 : && ((code == EQ && (c1 & c2) != c2)
6923 2336916 : || (code == GEU && c1 < c2)
6924 2336916 : || (code == GTU && c1 <= c2)))
6925 2341155 : || ((op0code == IOR
6926 4239 : && ((code == EQ && (c1 & c2) != c1)
6927 4235 : || (code == LEU && c1 > c2)
6928 4235 : || (code == LTU && c1 >= c2)))))
6929 17 : return const0_rtx;
6930 :
6931 2341151 : if ((op0code == AND
6932 2336916 : && ((code == NE && (c1 & c2) != c2)
6933 2336836 : || (code == LTU && c1 < c2)
6934 2336836 : || (code == LEU && c1 <= c2)))
6935 2341071 : || ((op0code == IOR
6936 4235 : && ((code == NE && (c1 & c2) != c1)
6937 4175 : || (code == GTU && c1 > c2)
6938 4175 : || (code == GEU && c1 >= c2)))))
6939 140 : return const_true_rtx;
6940 : }
6941 :
6942 : /* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped. */
6943 84423379 : if ((code == EQ || code == NE)
6944 62603727 : && GET_CODE (op0) == BSWAP
6945 316 : && CONST_SCALAR_INT_P (op1))
6946 85 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6947 : simplify_gen_unary (BSWAP, cmp_mode,
6948 85 : op1, cmp_mode));
6949 :
6950 : /* (eq/ne (bswap x) (bswap y)) simplifies to (eq/ne x y). */
6951 62603642 : if ((code == EQ || code == NE)
6952 62603642 : && GET_CODE (op0) == BSWAP
6953 231 : && GET_CODE (op1) == BSWAP)
6954 18 : return simplify_gen_relational (code, mode, cmp_mode,
6955 18 : XEXP (op0, 0), XEXP (op1, 0));
6956 :
6957 84423276 : if (op0code == POPCOUNT && op1 == const0_rtx)
6958 0 : switch (code)
6959 : {
6960 0 : case EQ:
6961 0 : case LE:
6962 0 : case LEU:
6963 : /* (eq (popcount x) (const_int 0)) -> (eq x (const_int 0)). */
6964 0 : return simplify_gen_relational (EQ, mode, GET_MODE (XEXP (op0, 0)),
6965 : XEXP (op0, 0),
6966 0 : CONST0_RTX (GET_MODE (XEXP (op0, 0))));
6967 :
6968 0 : case NE:
6969 0 : case GT:
6970 0 : case GTU:
6971 : /* (ne (popcount x) (const_int 0)) -> (ne x (const_int 0)). */
6972 0 : return simplify_gen_relational (NE, mode, GET_MODE (XEXP (op0, 0)),
6973 : XEXP (op0, 0),
6974 0 : CONST0_RTX (GET_MODE (XEXP (op0, 0))));
6975 :
6976 : default:
6977 : break;
6978 : }
6979 :
6980 : /* (ne:SI (subreg:QI (ashift:SI x 7) 0) 0) -> (and:SI x 1). */
6981 84423276 : if (code == NE
6982 33673863 : && op1 == const0_rtx
6983 17450375 : && (op0code == TRUNCATE
6984 155036 : || (partial_subreg_p (op0)
6985 154309 : && subreg_lowpart_p (op0)))
6986 131186 : && SCALAR_INT_MODE_P (mode)
6987 84423276 : && STORE_FLAG_VALUE == 1)
6988 : {
6989 34379 : rtx tmp = XEXP (op0, 0);
6990 34379 : if (GET_CODE (tmp) == ASHIFT
6991 2736 : && GET_MODE (tmp) == mode
6992 241 : && CONST_INT_P (XEXP (tmp, 1))
6993 241 : && is_int_mode (GET_MODE (op0), &int_mode)
6994 34620 : && INTVAL (XEXP (tmp, 1)) == GET_MODE_PRECISION (int_mode) - 1)
6995 241 : return simplify_gen_binary (AND, mode, XEXP (tmp, 0), const1_rtx);
6996 : }
6997 :
6998 : /* For two unsigned booleans A and B:
6999 :
7000 : A > B == ~B & A
7001 : A >= B == ~B | A
7002 : A < B == ~A & B
7003 : A <= B == ~A | B
7004 : A == B == ~A ^ B (== ~B ^ A)
7005 : A != B == A ^ B
7006 :
7007 : For signed comparisons, we have to take STORE_FLAG_VALUE into account,
7008 : with the rules above applying for positive STORE_FLAG_VALUE and with
7009 : the relations reversed for negative STORE_FLAG_VALUE. */
7010 84423035 : if (is_a<scalar_int_mode> (cmp_mode)
7011 81684395 : && COMPARISON_P (op0)
7012 84538148 : && COMPARISON_P (op1))
7013 : {
7014 10031 : rtx t = NULL_RTX;
7015 10031 : if (code == GTU || code == (STORE_FLAG_VALUE > 0 ? GT : LT))
7016 755 : t = simplify_logical_relational_operation (AND, mode, op1, op0, true);
7017 : else if (code == GEU || code == (STORE_FLAG_VALUE > 0 ? GE : LE))
7018 720 : t = simplify_logical_relational_operation (IOR, mode, op1, op0, true);
7019 : else if (code == LTU || code == (STORE_FLAG_VALUE > 0 ? LT : GT))
7020 720 : t = simplify_logical_relational_operation (AND, mode, op0, op1, true);
7021 : else if (code == LEU || code == (STORE_FLAG_VALUE > 0 ? LE : GE))
7022 720 : t = simplify_logical_relational_operation (IOR, mode, op0, op1, true);
7023 : else if (code == EQ)
7024 3173 : t = simplify_logical_relational_operation (XOR, mode, op0, op1, true);
7025 : else if (code == NE)
7026 3943 : t = simplify_logical_relational_operation (XOR, mode, op0, op1);
7027 : if (t)
7028 : return t;
7029 : }
7030 :
7031 : return NULL_RTX;
7032 : }
7033 :
7034 : enum
7035 : {
7036 : CMP_EQ = 1,
7037 : CMP_LT = 2,
7038 : CMP_GT = 4,
7039 : CMP_LTU = 8,
7040 : CMP_GTU = 16
7041 : };
7042 :
7043 :
7044 : /* Convert the known results for EQ, LT, GT, LTU, GTU contained in
7045 : KNOWN_RESULT to a CONST_INT, based on the requested comparison CODE
7046 : For KNOWN_RESULT to make sense it should be either CMP_EQ, or the
7047 : logical OR of one of (CMP_LT, CMP_GT) and one of (CMP_LTU, CMP_GTU).
7048 : For floating-point comparisons, assume that the operands were ordered. */
7049 :
7050 : static rtx
7051 723305 : comparison_result (enum rtx_code code, int known_results)
7052 : {
7053 723305 : switch (code)
7054 : {
7055 132267 : case EQ:
7056 132267 : case UNEQ:
7057 132267 : return (known_results & CMP_EQ) ? const_true_rtx : const0_rtx;
7058 451084 : case NE:
7059 451084 : case LTGT:
7060 451084 : return (known_results & CMP_EQ) ? const0_rtx : const_true_rtx;
7061 :
7062 9424 : case LT:
7063 9424 : case UNLT:
7064 9424 : return (known_results & CMP_LT) ? const_true_rtx : const0_rtx;
7065 8682 : case GE:
7066 8682 : case UNGE:
7067 8682 : return (known_results & CMP_LT) ? const0_rtx : const_true_rtx;
7068 :
7069 12904 : case GT:
7070 12904 : case UNGT:
7071 12904 : return (known_results & CMP_GT) ? const_true_rtx : const0_rtx;
7072 15119 : case LE:
7073 15119 : case UNLE:
7074 15119 : return (known_results & CMP_GT) ? const0_rtx : const_true_rtx;
7075 :
7076 25047 : case LTU:
7077 25047 : return (known_results & CMP_LTU) ? const_true_rtx : const0_rtx;
7078 8851 : case GEU:
7079 8851 : return (known_results & CMP_LTU) ? const0_rtx : const_true_rtx;
7080 :
7081 49472 : case GTU:
7082 49472 : return (known_results & CMP_GTU) ? const_true_rtx : const0_rtx;
7083 10389 : case LEU:
7084 10389 : return (known_results & CMP_GTU) ? const0_rtx : const_true_rtx;
7085 :
7086 0 : case ORDERED:
7087 0 : return const_true_rtx;
7088 66 : case UNORDERED:
7089 66 : return const0_rtx;
7090 0 : default:
7091 0 : gcc_unreachable ();
7092 : }
7093 : }
7094 :
7095 : /* Check if the given comparison (done in the given MODE) is actually
7096 : a tautology or a contradiction. If the mode is VOIDmode, the
7097 : comparison is done in "infinite precision". If no simplification
7098 : is possible, this function returns zero. Otherwise, it returns
7099 : either const_true_rtx or const0_rtx. */
7100 :
7101 : rtx
7102 132221783 : simplify_const_relational_operation (enum rtx_code code,
7103 : machine_mode mode,
7104 : rtx op0, rtx op1)
7105 : {
7106 139266134 : rtx tem;
7107 139266134 : rtx trueop0;
7108 139266134 : rtx trueop1;
7109 :
7110 139266134 : gcc_assert (mode != VOIDmode
7111 : || (GET_MODE (op0) == VOIDmode
7112 : && GET_MODE (op1) == VOIDmode));
7113 :
7114 : /* We only handle MODE_CC comparisons that are COMPARE against zero. */
7115 139266134 : if (GET_MODE_CLASS (mode) == MODE_CC
7116 45374944 : && (op1 != const0_rtx
7117 45374944 : || GET_CODE (op0) != COMPARE))
7118 : return NULL_RTX;
7119 :
7120 : /* If op0 is a compare, extract the comparison arguments from it. */
7121 108254926 : if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
7122 : {
7123 14363736 : op1 = XEXP (op0, 1);
7124 14363736 : op0 = XEXP (op0, 0);
7125 :
7126 14363736 : if (GET_MODE (op0) != VOIDmode)
7127 14214310 : mode = GET_MODE (op0);
7128 149426 : else if (GET_MODE (op1) != VOIDmode)
7129 116976 : mode = GET_MODE (op1);
7130 : else
7131 : return 0;
7132 : }
7133 :
7134 : /* We can't simplify MODE_CC values since we don't know what the
7135 : actual comparison is. */
7136 108222476 : if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
7137 : return 0;
7138 :
7139 : /* Make sure the constant is second. */
7140 108222476 : if (swap_commutative_operands_p (op0, op1))
7141 : {
7142 3167032 : std::swap (op0, op1);
7143 3167032 : code = swap_condition (code);
7144 : }
7145 :
7146 108222476 : trueop0 = avoid_constant_pool_reference (op0);
7147 108222476 : trueop1 = avoid_constant_pool_reference (op1);
7148 :
7149 : /* For integer comparisons of A and B maybe we can simplify A - B and can
7150 : then simplify a comparison of that with zero. If A and B are both either
7151 : a register or a CONST_INT, this can't help; testing for these cases will
7152 : prevent infinite recursion here and speed things up.
7153 :
7154 : We can only do this for EQ and NE comparisons as otherwise we may
7155 : lose or introduce overflow which we cannot disregard as undefined as
7156 : we do not know the signedness of the operation on either the left or
7157 : the right hand side of the comparison. */
7158 :
7159 108222476 : if (INTEGRAL_MODE_P (mode)
7160 105542251 : && trueop1 != CONST0_RTX (mode)
7161 54460134 : && (code == EQ || code == NE)
7162 34484122 : && ! ((REG_P (op0)
7163 10065880 : || CONST_SCALAR_INT_P (trueop0)
7164 10037579 : || CONST_VECTOR_P (trueop0))
7165 24446563 : && (REG_P (op1)
7166 14671526 : || CONST_SCALAR_INT_P (trueop1)
7167 3457178 : || CONST_VECTOR_P (trueop1)))
7168 13491770 : && (tem = simplify_binary_operation (MINUS, mode, op0, op1)) != 0
7169 : /* We cannot do this if tem is a nonzero address. */
7170 7044353 : && ! nonzero_address_p (tem))
7171 7044351 : return simplify_const_relational_operation (signed_condition (code),
7172 7044351 : mode, tem, CONST0_RTX (mode));
7173 :
7174 101178125 : if (! HONOR_NANS (mode) && code == ORDERED)
7175 0 : return const_true_rtx;
7176 :
7177 101178125 : if (! HONOR_NANS (mode) && code == UNORDERED)
7178 8 : return const0_rtx;
7179 :
7180 : /* For modes without NaNs, if the two operands are equal, we know the
7181 : result except if they have side-effects. Even with NaNs we know
7182 : the result of unordered comparisons and, if signaling NaNs are
7183 : irrelevant, also the result of LT/GT/LTGT. */
7184 101178117 : if ((! HONOR_NANS (trueop0)
7185 2189053 : || code == UNEQ || code == UNLE || code == UNGE
7186 : || ((code == LT || code == GT || code == LTGT)
7187 894493 : && ! HONOR_SNANS (trueop0)))
7188 99991062 : && rtx_equal_p (trueop0, trueop1)
7189 101693693 : && ! side_effects_p (trueop0))
7190 515495 : return comparison_result (code, CMP_EQ);
7191 :
7192 : /* If the operands are floating-point constants, see if we can fold
7193 : the result. */
7194 100662622 : if (CONST_DOUBLE_AS_FLOAT_P (trueop0)
7195 1497 : && CONST_DOUBLE_AS_FLOAT_P (trueop1)
7196 1497 : && SCALAR_FLOAT_MODE_P (GET_MODE (trueop0)))
7197 : {
7198 1497 : const REAL_VALUE_TYPE *d0 = CONST_DOUBLE_REAL_VALUE (trueop0);
7199 1497 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
7200 :
7201 : /* Comparisons are unordered iff at least one of the values is NaN. */
7202 1497 : if (REAL_VALUE_ISNAN (*d0) || REAL_VALUE_ISNAN (*d1))
7203 173 : switch (code)
7204 : {
7205 0 : case UNEQ:
7206 0 : case UNLT:
7207 0 : case UNGT:
7208 0 : case UNLE:
7209 0 : case UNGE:
7210 0 : case NE:
7211 0 : case UNORDERED:
7212 0 : return const_true_rtx;
7213 173 : case EQ:
7214 173 : case LT:
7215 173 : case GT:
7216 173 : case LE:
7217 173 : case GE:
7218 173 : case LTGT:
7219 173 : case ORDERED:
7220 173 : return const0_rtx;
7221 : default:
7222 : return 0;
7223 : }
7224 :
7225 1484 : return comparison_result (code,
7226 1484 : (real_equal (d0, d1) ? CMP_EQ :
7227 1484 : real_less (d0, d1) ? CMP_LT : CMP_GT));
7228 : }
7229 :
7230 : /* Otherwise, see if the operands are both integers. */
7231 100661125 : if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
7232 97519439 : && CONST_SCALAR_INT_P (trueop0) && CONST_SCALAR_INT_P (trueop1))
7233 : {
7234 : /* It would be nice if we really had a mode here. However, the
7235 : largest int representable on the target is as good as
7236 : infinite. */
7237 206486 : machine_mode cmode = (mode == VOIDmode) ? MAX_MODE_INT : mode;
7238 206486 : rtx_mode_t ptrueop0 = rtx_mode_t (trueop0, cmode);
7239 206486 : rtx_mode_t ptrueop1 = rtx_mode_t (trueop1, cmode);
7240 :
7241 206486 : if (wi::eq_p (ptrueop0, ptrueop1))
7242 0 : return comparison_result (code, CMP_EQ);
7243 : else
7244 : {
7245 206486 : int cr = wi::lts_p (ptrueop0, ptrueop1) ? CMP_LT : CMP_GT;
7246 206486 : cr |= wi::ltu_p (ptrueop0, ptrueop1) ? CMP_LTU : CMP_GTU;
7247 206486 : return comparison_result (code, cr);
7248 : }
7249 : }
7250 :
7251 : /* Optimize comparisons with upper and lower bounds. */
7252 100454639 : scalar_int_mode int_mode;
7253 100454639 : if (CONST_INT_P (trueop1)
7254 70111623 : && is_a <scalar_int_mode> (mode, &int_mode)
7255 70111623 : && HWI_COMPUTABLE_MODE_P (int_mode)
7256 170110475 : && !side_effects_p (trueop0))
7257 : {
7258 69504584 : int sign;
7259 69504584 : unsigned HOST_WIDE_INT nonzero = nonzero_bits (trueop0, int_mode);
7260 69504584 : HOST_WIDE_INT val = INTVAL (trueop1);
7261 69504584 : HOST_WIDE_INT mmin, mmax;
7262 :
7263 69504584 : if (code == GEU
7264 69504584 : || code == LEU
7265 66191269 : || code == GTU
7266 66191269 : || code == LTU)
7267 : sign = 0;
7268 : else
7269 69504584 : sign = 1;
7270 :
7271 : /* Get a reduced range if the sign bit is zero. */
7272 69504584 : if (nonzero <= (GET_MODE_MASK (int_mode) >> 1))
7273 : {
7274 6264595 : mmin = 0;
7275 6264595 : mmax = nonzero;
7276 : }
7277 : else
7278 : {
7279 63239989 : rtx mmin_rtx, mmax_rtx;
7280 63239989 : get_mode_bounds (int_mode, sign, int_mode, &mmin_rtx, &mmax_rtx);
7281 :
7282 63239989 : mmin = INTVAL (mmin_rtx);
7283 63239989 : mmax = INTVAL (mmax_rtx);
7284 63239989 : if (sign)
7285 : {
7286 57059419 : unsigned int sign_copies
7287 57059419 : = num_sign_bit_copies (trueop0, int_mode);
7288 :
7289 57059419 : mmin >>= (sign_copies - 1);
7290 57059419 : mmax >>= (sign_copies - 1);
7291 : }
7292 : }
7293 :
7294 69504584 : switch (code)
7295 : {
7296 : /* x >= y is always true for y <= mmin, always false for y > mmax. */
7297 538669 : case GEU:
7298 538669 : if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
7299 6042 : return const_true_rtx;
7300 532627 : if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
7301 48 : return const0_rtx;
7302 : break;
7303 963304 : case GE:
7304 963304 : if (val <= mmin)
7305 2098 : return const_true_rtx;
7306 961206 : if (val > mmax)
7307 0 : return const0_rtx;
7308 : break;
7309 :
7310 : /* x <= y is always true for y >= mmax, always false for y < mmin. */
7311 2774646 : case LEU:
7312 2774646 : if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
7313 15293 : return const_true_rtx;
7314 2759353 : if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
7315 0 : return const0_rtx;
7316 : break;
7317 2567838 : case LE:
7318 2567838 : if (val >= mmax)
7319 459 : return const_true_rtx;
7320 2567379 : if (val < mmin)
7321 0 : return const0_rtx;
7322 : break;
7323 :
7324 25177065 : case EQ:
7325 : /* x == y is always false for y out of range. */
7326 25177065 : if (val < mmin || val > mmax)
7327 486 : return const0_rtx;
7328 : break;
7329 :
7330 : /* x > y is always false for y >= mmax, always true for y < mmin. */
7331 2489903 : case GTU:
7332 2489903 : if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
7333 40274 : return const0_rtx;
7334 2449629 : if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
7335 0 : return const_true_rtx;
7336 : break;
7337 1831582 : case GT:
7338 1831582 : if (val >= mmax)
7339 325 : return const0_rtx;
7340 1831257 : if (val < mmin)
7341 2 : return const_true_rtx;
7342 : break;
7343 :
7344 : /* x < y is always false for y <= mmin, always true for y > mmax. */
7345 842034 : case LTU:
7346 842034 : if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
7347 3897 : return const0_rtx;
7348 838137 : if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
7349 76653 : return const_true_rtx;
7350 : break;
7351 1083784 : case LT:
7352 1083784 : if (val <= mmin)
7353 2344 : return const0_rtx;
7354 1081440 : if (val > mmax)
7355 3364 : return const_true_rtx;
7356 : break;
7357 :
7358 31235759 : case NE:
7359 : /* x != y is always true for y out of range. */
7360 31235759 : if (val < mmin || val > mmax)
7361 121 : return const_true_rtx;
7362 : break;
7363 :
7364 : default:
7365 : break;
7366 : }
7367 : }
7368 :
7369 : /* Optimize integer comparisons with zero. */
7370 100303233 : if (is_a <scalar_int_mode> (mode, &int_mode)
7371 97204628 : && trueop1 == const0_rtx
7372 50341564 : && !side_effects_p (trueop0))
7373 : {
7374 : /* Some addresses are known to be nonzero. We don't know
7375 : their sign, but equality comparisons are known. */
7376 50188248 : if (nonzero_address_p (trueop0))
7377 : {
7378 533 : if (code == EQ || code == LEU)
7379 274 : return const0_rtx;
7380 259 : if (code == NE || code == GTU)
7381 259 : return const_true_rtx;
7382 : }
7383 :
7384 : /* See if the first operand is an IOR with a constant. If so, we
7385 : may be able to determine the result of this comparison. */
7386 50187715 : if (GET_CODE (op0) == IOR)
7387 : {
7388 691895 : rtx inner_const = avoid_constant_pool_reference (XEXP (op0, 1));
7389 691895 : if (CONST_INT_P (inner_const) && inner_const != const0_rtx)
7390 : {
7391 229 : int sign_bitnum = GET_MODE_PRECISION (int_mode) - 1;
7392 458 : int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
7393 229 : && (UINTVAL (inner_const)
7394 229 : & (HOST_WIDE_INT_1U
7395 : << sign_bitnum)));
7396 :
7397 229 : switch (code)
7398 : {
7399 : case EQ:
7400 : case LEU:
7401 : return const0_rtx;
7402 4 : case NE:
7403 4 : case GTU:
7404 4 : return const_true_rtx;
7405 17 : case LT:
7406 17 : case LE:
7407 17 : if (has_sign)
7408 2 : return const_true_rtx;
7409 : break;
7410 202 : case GT:
7411 202 : case GE:
7412 202 : if (has_sign)
7413 : return const0_rtx;
7414 : break;
7415 : default:
7416 : break;
7417 : }
7418 : }
7419 : }
7420 : }
7421 :
7422 : /* Optimize comparison of ABS with zero. */
7423 50693091 : if (trueop1 == CONST0_RTX (mode) && !side_effects_p (trueop0)
7424 150841958 : && (GET_CODE (trueop0) == ABS
7425 50538881 : || (GET_CODE (trueop0) == FLOAT_EXTEND
7426 100 : && GET_CODE (XEXP (trueop0, 0)) == ABS)))
7427 : {
7428 581 : switch (code)
7429 : {
7430 60 : case LT:
7431 : /* Optimize abs(x) < 0.0. */
7432 60 : if (!INTEGRAL_MODE_P (mode) && !HONOR_SNANS (mode))
7433 0 : return const0_rtx;
7434 : break;
7435 :
7436 42 : case GE:
7437 : /* Optimize abs(x) >= 0.0. */
7438 42 : if (!INTEGRAL_MODE_P (mode) && !HONOR_NANS (mode))
7439 0 : return const_true_rtx;
7440 : break;
7441 :
7442 0 : case UNGE:
7443 : /* Optimize ! (abs(x) < 0.0). */
7444 0 : return const_true_rtx;
7445 :
7446 : default:
7447 : break;
7448 : }
7449 : }
7450 :
7451 : return 0;
7452 : }
7453 :
7454 : /* Recognize expressions of the form (X CMP 0) ? VAL : OP (X)
7455 : where OP is CLZ or CTZ and VAL is the value from CLZ_DEFINED_VALUE_AT_ZERO
7456 : or CTZ_DEFINED_VALUE_AT_ZERO respectively and return OP (X) if the expression
7457 : can be simplified to that or NULL_RTX if not.
7458 : Assume X is compared against zero with CMP_CODE and the true
7459 : arm is TRUE_VAL and the false arm is FALSE_VAL. */
7460 :
7461 : rtx
7462 31472459 : simplify_context::simplify_cond_clz_ctz (rtx x, rtx_code cmp_code,
7463 : rtx true_val, rtx false_val)
7464 : {
7465 31472459 : if (cmp_code != EQ && cmp_code != NE)
7466 : return NULL_RTX;
7467 :
7468 : /* Result on X == 0 and X !=0 respectively. */
7469 22603142 : rtx on_zero, on_nonzero;
7470 22603142 : if (cmp_code == EQ)
7471 : {
7472 : on_zero = true_val;
7473 : on_nonzero = false_val;
7474 : }
7475 : else
7476 : {
7477 12353474 : on_zero = false_val;
7478 12353474 : on_nonzero = true_val;
7479 : }
7480 :
7481 22603142 : rtx_code op_code = GET_CODE (on_nonzero);
7482 22603142 : if ((op_code != CLZ && op_code != CTZ)
7483 2024 : || !rtx_equal_p (XEXP (on_nonzero, 0), x)
7484 22604198 : || !CONST_INT_P (on_zero))
7485 : return NULL_RTX;
7486 :
7487 301 : HOST_WIDE_INT op_val;
7488 301 : scalar_int_mode mode ATTRIBUTE_UNUSED
7489 301 : = as_a <scalar_int_mode> (GET_MODE (XEXP (on_nonzero, 0)));
7490 0 : if (((op_code == CLZ && CLZ_DEFINED_VALUE_AT_ZERO (mode, op_val))
7491 602 : || (op_code == CTZ && CTZ_DEFINED_VALUE_AT_ZERO (mode, op_val)))
7492 325 : && op_val == INTVAL (on_zero))
7493 0 : return on_nonzero;
7494 :
7495 : return NULL_RTX;
7496 : }
7497 :
7498 : /* Try to simplify X given that it appears within operand OP of a
7499 : VEC_MERGE operation whose mask is MASK. X need not use the same
7500 : vector mode as the VEC_MERGE, but it must have the same number of
7501 : elements.
7502 :
7503 : Return the simplified X on success, otherwise return NULL_RTX. */
7504 :
7505 : rtx
7506 2123784 : simplify_context::simplify_merge_mask (rtx x, rtx mask, int op)
7507 : {
7508 2123784 : gcc_assert (VECTOR_MODE_P (GET_MODE (x)));
7509 4247568 : poly_uint64 nunits = GET_MODE_NUNITS (GET_MODE (x));
7510 2123784 : if (GET_CODE (x) == VEC_MERGE && rtx_equal_p (XEXP (x, 2), mask))
7511 : {
7512 5491 : if (side_effects_p (XEXP (x, 1 - op)))
7513 : return NULL_RTX;
7514 :
7515 5267 : return XEXP (x, op);
7516 : }
7517 2118293 : if (UNARY_P (x)
7518 383029 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
7519 2176095 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits))
7520 : {
7521 24255 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
7522 24255 : if (top0)
7523 448 : return simplify_gen_unary (GET_CODE (x), GET_MODE (x), top0,
7524 448 : GET_MODE (XEXP (x, 0)));
7525 : }
7526 2117845 : if (BINARY_P (x)
7527 208785 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
7528 416942 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
7529 181373 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
7530 2406065 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits))
7531 : {
7532 144110 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
7533 144110 : rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
7534 144110 : if (top0 || top1)
7535 : {
7536 952 : if (COMPARISON_P (x))
7537 0 : return simplify_gen_relational (GET_CODE (x), GET_MODE (x),
7538 0 : GET_MODE (XEXP (x, 0)) != VOIDmode
7539 : ? GET_MODE (XEXP (x, 0))
7540 0 : : GET_MODE (XEXP (x, 1)),
7541 : top0 ? top0 : XEXP (x, 0),
7542 0 : top1 ? top1 : XEXP (x, 1));
7543 : else
7544 952 : return simplify_gen_binary (GET_CODE (x), GET_MODE (x),
7545 : top0 ? top0 : XEXP (x, 0),
7546 952 : top1 ? top1 : XEXP (x, 1));
7547 : }
7548 : }
7549 2116893 : if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY
7550 59830 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
7551 119660 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
7552 59830 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
7553 119660 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits)
7554 59830 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 2)))
7555 2133617 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 2))), nunits))
7556 : {
7557 8362 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
7558 8362 : rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
7559 8362 : rtx top2 = simplify_merge_mask (XEXP (x, 2), mask, op);
7560 8362 : if (top0 || top1 || top2)
7561 448 : return simplify_gen_ternary (GET_CODE (x), GET_MODE (x),
7562 448 : GET_MODE (XEXP (x, 0)),
7563 : top0 ? top0 : XEXP (x, 0),
7564 : top1 ? top1 : XEXP (x, 1),
7565 448 : top2 ? top2 : XEXP (x, 2));
7566 : }
7567 : return NULL_RTX;
7568 : }
7569 :
7570 :
7571 : /* Simplify CODE, an operation with result mode MODE and three operands,
7572 : OP0, OP1, and OP2. OP0_MODE was the mode of OP0 before it became
7573 : a constant. Return 0 if no simplifications is possible. */
7574 :
7575 : rtx
7576 43839980 : simplify_context::simplify_ternary_operation (rtx_code code, machine_mode mode,
7577 : machine_mode op0_mode,
7578 : rtx op0, rtx op1, rtx op2)
7579 : {
7580 43839980 : bool any_change = false;
7581 43839980 : rtx tem, trueop2;
7582 43839980 : scalar_int_mode int_mode, int_op0_mode;
7583 43839980 : unsigned int n_elts;
7584 :
7585 43839980 : switch (code)
7586 : {
7587 336323 : case FMA:
7588 : /* Simplify negations around the multiplication. */
7589 : /* -a * -b + c => a * b + c. */
7590 336323 : if (GET_CODE (op0) == NEG)
7591 : {
7592 83004 : tem = simplify_unary_operation (NEG, mode, op1, mode);
7593 83004 : if (tem)
7594 271 : op1 = tem, op0 = XEXP (op0, 0), any_change = true;
7595 : }
7596 253319 : else if (GET_CODE (op1) == NEG)
7597 : {
7598 1068 : tem = simplify_unary_operation (NEG, mode, op0, mode);
7599 1068 : if (tem)
7600 0 : op0 = tem, op1 = XEXP (op1, 0), any_change = true;
7601 : }
7602 :
7603 : /* Canonicalize the two multiplication operands. */
7604 : /* a * -b + c => -b * a + c. */
7605 336323 : if (swap_commutative_operands_p (op0, op1))
7606 : std::swap (op0, op1), any_change = true;
7607 :
7608 306536 : if (any_change)
7609 30049 : return gen_rtx_FMA (mode, op0, op1, op2);
7610 : return NULL_RTX;
7611 :
7612 760034 : case SIGN_EXTRACT:
7613 760034 : case ZERO_EXTRACT:
7614 760034 : if (CONST_INT_P (op0)
7615 17318 : && CONST_INT_P (op1)
7616 17318 : && CONST_INT_P (op2)
7617 43840012 : && is_a <scalar_int_mode> (mode, &int_mode)
7618 32 : && INTVAL (op1) + INTVAL (op2) <= GET_MODE_PRECISION (int_mode)
7619 760066 : && HWI_COMPUTABLE_MODE_P (int_mode))
7620 : {
7621 : /* Extracting a bit-field from a constant */
7622 32 : unsigned HOST_WIDE_INT val = UINTVAL (op0);
7623 32 : HOST_WIDE_INT op1val = INTVAL (op1);
7624 32 : HOST_WIDE_INT op2val = INTVAL (op2);
7625 32 : if (!BITS_BIG_ENDIAN)
7626 32 : val >>= op2val;
7627 : else if (is_a <scalar_int_mode> (op0_mode, &int_op0_mode))
7628 : val >>= GET_MODE_PRECISION (int_op0_mode) - op2val - op1val;
7629 : else
7630 : /* Not enough information to calculate the bit position. */
7631 : break;
7632 :
7633 32 : if (HOST_BITS_PER_WIDE_INT != op1val)
7634 : {
7635 : /* First zero-extend. */
7636 29 : val &= (HOST_WIDE_INT_1U << op1val) - 1;
7637 : /* If desired, propagate sign bit. */
7638 29 : if (code == SIGN_EXTRACT
7639 5 : && (val & (HOST_WIDE_INT_1U << (op1val - 1)))
7640 5 : != 0)
7641 2 : val |= ~ ((HOST_WIDE_INT_1U << op1val) - 1);
7642 : }
7643 :
7644 32 : return gen_int_mode (val, int_mode);
7645 : }
7646 : break;
7647 :
7648 41658516 : case IF_THEN_ELSE:
7649 41658516 : if (CONST_INT_P (op0))
7650 200390 : return op0 != const0_rtx ? op1 : op2;
7651 :
7652 : /* Convert c ? a : a into "a". Beware that two rtx_equal_p MEMs can
7653 : still carry different memory attributes, in particular incompatible
7654 : alias sets; returning one of them would narrow the aliasing of the
7655 : result to that operand's, which is unsound (PR125683). When the
7656 : attributes differ, fold to a copy that keeps only what both operands
7657 : guarantee, like merge_memattrs does when cross-jumping commons two
7658 : memory references. */
7659 41458126 : if (rtx_equal_p (op1, op2) && ! side_effects_p (op0))
7660 : {
7661 3364 : if (op1 == op2
7662 2912 : || !MEM_P (op1)
7663 3386 : || (mem_attrs_eq_p (get_mem_attrs (op1), get_mem_attrs (op2))
7664 8 : && MEM_READONLY_P (op1) == MEM_READONLY_P (op2)
7665 8 : && MEM_NOTRAP_P (op1) == MEM_NOTRAP_P (op2)
7666 8 : && MEM_POINTER (op1) == MEM_POINTER (op2)))
7667 : return op1;
7668 :
7669 : /* For BLKmode the size in MEM_ATTRS describes the access itself,
7670 : so it cannot be dropped. Volatility is not merged either: it
7671 : constrains when the access happens rather than describing the
7672 : memory, so unlike the flags below it cannot be weakened to what
7673 : both operands allow. Dropping it would lose a required access;
7674 : merge_memattrs and noce_try_cmove_arith instead set it, which is
7675 : sound but claims more than either operand did. Those two have to
7676 : put something on a reference they are already committed to, while
7677 : this fold is free to do nothing, and if-conversion never reaches
7678 : it with a volatile operand in any case: side_effects_p is true
7679 : for one, so noce_operand_ok rejects it. Decline the fold. */
7680 14 : if (GET_MODE (op1) != BLKmode
7681 14 : && MEM_VOLATILE_P (op1) == MEM_VOLATILE_P (op2))
7682 : {
7683 14 : rtx mem = shallow_copy_rtx (op1);
7684 :
7685 14 : if (MEM_ALIAS_SET (op1) != MEM_ALIAS_SET (op2))
7686 1 : set_mem_alias_set (mem, 0);
7687 :
7688 14 : if (!mem_expr_equal_p (MEM_EXPR (op1), MEM_EXPR (op2)))
7689 : {
7690 14 : set_mem_expr (mem, NULL_TREE);
7691 14 : clear_mem_offset (mem);
7692 : }
7693 0 : else if (MEM_OFFSET_KNOWN_P (op1) != MEM_OFFSET_KNOWN_P (op2)
7694 0 : || (MEM_OFFSET_KNOWN_P (op1)
7695 0 : && maybe_ne (MEM_OFFSET (op1), MEM_OFFSET (op2))))
7696 0 : clear_mem_offset (mem);
7697 :
7698 : /* Unlike merge_memattrs, which fixes up two references that
7699 : both stay in the stream, this returns a single reference
7700 : that stands in for either arm, so keep the size only when
7701 : both agree rather than taking the larger one. */
7702 28 : if (!MEM_SIZE_KNOWN_P (op1) || !MEM_SIZE_KNOWN_P (op2)
7703 28 : || maybe_ne (MEM_SIZE (op1), MEM_SIZE (op2)))
7704 0 : clear_mem_size (mem);
7705 :
7706 14 : set_mem_align (mem, MIN (MEM_ALIGN (op1), MEM_ALIGN (op2)));
7707 :
7708 : /* MEM_READONLY_P, MEM_NOTRAP_P and MEM_POINTER are rtx flag
7709 : bits rather than MEM_ATTRS fields, so shallow_copy_rtx has
7710 : already taken them from OP1 and they need clearing by hand.
7711 : Each asserts something about the reference, so the copy may
7712 : only keep it when both operands do, as merge_memattrs does
7713 : for the first two. */
7714 14 : if (MEM_READONLY_P (op1) != MEM_READONLY_P (op2))
7715 0 : MEM_READONLY_P (mem) = 0;
7716 14 : if (MEM_NOTRAP_P (op1) != MEM_NOTRAP_P (op2))
7717 0 : MEM_NOTRAP_P (mem) = 0;
7718 14 : if (MEM_POINTER (op1) != MEM_POINTER (op2))
7719 0 : MEM_POINTER (mem) = 0;
7720 :
7721 : return mem;
7722 : }
7723 : }
7724 :
7725 : /* Convert a != b ? a : b into "a". */
7726 41454762 : if (GET_CODE (op0) == NE
7727 16166294 : && ! side_effects_p (op0)
7728 16117675 : && ! HONOR_NANS (mode)
7729 15927248 : && ! HONOR_SIGNED_ZEROS (mode)
7730 57382010 : && ((rtx_equal_p (XEXP (op0, 0), op1)
7731 127875 : && rtx_equal_p (XEXP (op0, 1), op2))
7732 15926921 : || (rtx_equal_p (XEXP (op0, 0), op2)
7733 3610 : && rtx_equal_p (XEXP (op0, 1), op1))))
7734 : return op1;
7735 :
7736 : /* Convert a == b ? a : b into "b". */
7737 41454196 : if (GET_CODE (op0) == EQ
7738 12838747 : && ! side_effects_p (op0)
7739 12819702 : && ! HONOR_NANS (mode)
7740 12794446 : && ! HONOR_SIGNED_ZEROS (mode)
7741 54248642 : && ((rtx_equal_p (XEXP (op0, 0), op1)
7742 15024 : && rtx_equal_p (XEXP (op0, 1), op2))
7743 12794442 : || (rtx_equal_p (XEXP (op0, 0), op2)
7744 7634 : && rtx_equal_p (XEXP (op0, 1), op1))))
7745 : return op2;
7746 :
7747 : /* Convert a != 0 ? -a : 0 into "-a". */
7748 41454174 : if (GET_CODE (op0) == NE
7749 16165728 : && ! side_effects_p (op0)
7750 16117109 : && ! HONOR_NANS (mode)
7751 15926682 : && ! HONOR_SIGNED_ZEROS (mode)
7752 15926682 : && XEXP (op0, 1) == CONST0_RTX (mode)
7753 12162870 : && op2 == CONST0_RTX (mode)
7754 179843 : && GET_CODE (op1) == NEG
7755 41454214 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0)))
7756 : return op1;
7757 :
7758 : /* Convert a == 0 ? 0 : -a into "-a". */
7759 41454165 : if (GET_CODE (op0) == EQ
7760 12838725 : && ! side_effects_p (op0)
7761 12819680 : && ! HONOR_NANS (mode)
7762 12794424 : && ! HONOR_SIGNED_ZEROS (mode)
7763 12794424 : && op1 == CONST0_RTX (mode)
7764 41907 : && XEXP (op0, 1) == CONST0_RTX (mode)
7765 21523 : && GET_CODE (op2) == NEG
7766 41454171 : && rtx_equal_p (XEXP (op0, 0), XEXP (op2, 0)))
7767 : return op2;
7768 :
7769 : /* Convert (!c) != {0,...,0} ? a : b into
7770 : c != {0,...,0} ? b : a for vector modes. */
7771 41454159 : if (VECTOR_MODE_P (GET_MODE (op1))
7772 14815 : && GET_CODE (op0) == NE
7773 477 : && GET_CODE (XEXP (op0, 0)) == NOT
7774 0 : && GET_CODE (XEXP (op0, 1)) == CONST_VECTOR)
7775 : {
7776 0 : rtx cv = XEXP (op0, 1);
7777 0 : int nunits;
7778 0 : bool ok = true;
7779 0 : if (!CONST_VECTOR_NUNITS (cv).is_constant (&nunits))
7780 : ok = false;
7781 : else
7782 0 : for (int i = 0; i < nunits; ++i)
7783 0 : if (CONST_VECTOR_ELT (cv, i) != const0_rtx)
7784 : {
7785 : ok = false;
7786 : break;
7787 : }
7788 0 : if (ok)
7789 : {
7790 0 : rtx new_op0 = gen_rtx_NE (GET_MODE (op0),
7791 : XEXP (XEXP (op0, 0), 0),
7792 : XEXP (op0, 1));
7793 0 : rtx retval = gen_rtx_IF_THEN_ELSE (mode, new_op0, op2, op1);
7794 0 : return retval;
7795 : }
7796 : }
7797 :
7798 : /* Convert x == 0 ? N : clz (x) into clz (x) when
7799 : CLZ_DEFINED_VALUE_AT_ZERO is defined to N for the mode of x.
7800 : Similarly for ctz (x). */
7801 41453166 : if (COMPARISON_P (op0) && !side_effects_p (op0)
7802 82806944 : && XEXP (op0, 1) == const0_rtx)
7803 : {
7804 31472459 : rtx simplified
7805 31472459 : = simplify_cond_clz_ctz (XEXP (op0, 0), GET_CODE (op0),
7806 : op1, op2);
7807 31472459 : if (simplified)
7808 : return simplified;
7809 : }
7810 :
7811 41454159 : if (COMPARISON_P (op0) && ! side_effects_p (op0))
7812 : {
7813 82802054 : machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
7814 41352785 : ? GET_MODE (XEXP (op0, 1))
7815 : : GET_MODE (XEXP (op0, 0)));
7816 41352785 : rtx temp;
7817 :
7818 : /* Look for happy constants in op1 and op2. */
7819 41352785 : if (CONST_INT_P (op1) && CONST_INT_P (op2))
7820 : {
7821 231253 : HOST_WIDE_INT t = INTVAL (op1);
7822 231253 : HOST_WIDE_INT f = INTVAL (op2);
7823 :
7824 231253 : if (t == STORE_FLAG_VALUE && f == 0)
7825 55290 : code = GET_CODE (op0);
7826 175963 : else if (t == 0 && f == STORE_FLAG_VALUE)
7827 : {
7828 31258 : enum rtx_code tmp;
7829 31258 : tmp = reversed_comparison_code (op0, NULL);
7830 31258 : if (tmp == UNKNOWN)
7831 : break;
7832 : code = tmp;
7833 : }
7834 : else
7835 : break;
7836 :
7837 81383 : return simplify_gen_relational (code, mode, cmp_mode,
7838 81383 : XEXP (op0, 0), XEXP (op0, 1));
7839 : }
7840 :
7841 41121532 : temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
7842 : cmp_mode, XEXP (op0, 0),
7843 : XEXP (op0, 1));
7844 :
7845 : /* See if any simplifications were possible. */
7846 41121532 : if (temp)
7847 : {
7848 7009 : if (CONST_INT_P (temp))
7849 827 : return temp == const0_rtx ? op2 : op1;
7850 6182 : else if (temp)
7851 6182 : return gen_rtx_IF_THEN_ELSE (mode, temp, op1, op2);
7852 : }
7853 : }
7854 : break;
7855 :
7856 1085107 : case VEC_MERGE:
7857 1085107 : gcc_assert (GET_MODE (op0) == mode);
7858 1085107 : gcc_assert (GET_MODE (op1) == mode);
7859 1085107 : gcc_assert (VECTOR_MODE_P (mode));
7860 1085107 : trueop2 = avoid_constant_pool_reference (op2);
7861 1085107 : if (CONST_INT_P (trueop2)
7862 1843657 : && GET_MODE_NUNITS (mode).is_constant (&n_elts))
7863 : {
7864 758550 : unsigned HOST_WIDE_INT sel = UINTVAL (trueop2);
7865 758550 : unsigned HOST_WIDE_INT mask;
7866 758550 : if (n_elts == HOST_BITS_PER_WIDE_INT)
7867 : mask = -1;
7868 : else
7869 756073 : mask = (HOST_WIDE_INT_1U << n_elts) - 1;
7870 :
7871 758550 : if (!(sel & mask) && !side_effects_p (op0))
7872 : return op1;
7873 758125 : if ((sel & mask) == mask && !side_effects_p (op1))
7874 : return op0;
7875 :
7876 747024 : rtx trueop0 = avoid_constant_pool_reference (op0);
7877 747024 : rtx trueop1 = avoid_constant_pool_reference (op1);
7878 747024 : if (GET_CODE (trueop0) == CONST_VECTOR
7879 11357 : && GET_CODE (trueop1) == CONST_VECTOR)
7880 : {
7881 6968 : rtvec v = rtvec_alloc (n_elts);
7882 6968 : unsigned int i;
7883 :
7884 67198 : for (i = 0; i < n_elts; i++)
7885 53262 : RTVEC_ELT (v, i) = ((sel & (HOST_WIDE_INT_1U << i))
7886 53262 : ? CONST_VECTOR_ELT (trueop0, i)
7887 31413 : : CONST_VECTOR_ELT (trueop1, i));
7888 6968 : return gen_rtx_CONST_VECTOR (mode, v);
7889 : }
7890 :
7891 740056 : if (swap_commutative_operands_p (op0, op1)
7892 : /* Two operands have same precedence, then first bit of mask
7893 : select first operand. */
7894 740056 : || (!swap_commutative_operands_p (op1, op0) && !(sel & 1)))
7895 33844 : return simplify_gen_ternary (code, mode, mode, op1, op0,
7896 67688 : GEN_INT (~sel & mask));
7897 :
7898 : /* Replace (vec_merge (vec_merge a b m) c n) with (vec_merge b c n)
7899 : if no element from a appears in the result. */
7900 706212 : if (GET_CODE (op0) == VEC_MERGE)
7901 : {
7902 47331 : tem = avoid_constant_pool_reference (XEXP (op0, 2));
7903 47331 : if (CONST_INT_P (tem))
7904 : {
7905 31608 : unsigned HOST_WIDE_INT sel0 = UINTVAL (tem);
7906 31608 : if (!(sel & sel0 & mask) && !side_effects_p (XEXP (op0, 0)))
7907 99 : return simplify_gen_ternary (code, mode, mode,
7908 99 : XEXP (op0, 1), op1, op2);
7909 31509 : if (!(sel & ~sel0 & mask) && !side_effects_p (XEXP (op0, 1)))
7910 815 : return simplify_gen_ternary (code, mode, mode,
7911 815 : XEXP (op0, 0), op1, op2);
7912 :
7913 : /* Replace (vec_merge (vec_merge a b m) a n) with
7914 : (vec_merge a b (m|~n)). */
7915 30694 : if (rtx_equal_p (XEXP (op0, 0), op1)
7916 30694 : && ! side_effects_p (op1))
7917 143 : return simplify_gen_ternary (code, mode, mode,
7918 : op1, XEXP (op0, 1),
7919 286 : GEN_INT ((sel0 | ~sel) & mask));
7920 : /* Replace (vec_merge (vec_merge b a m) a n) with
7921 : (vec_merge b a (m&n)). */
7922 30551 : if (rtx_equal_p (XEXP (op0, 1), op1)
7923 30551 : && ! side_effects_p (op1))
7924 48 : return simplify_gen_ternary (code, mode, mode,
7925 : XEXP (op0, 0), op1,
7926 48 : GEN_INT (sel & sel0 & mask));
7927 : }
7928 : }
7929 705107 : if (GET_CODE (op1) == VEC_MERGE)
7930 : {
7931 585 : tem = avoid_constant_pool_reference (XEXP (op1, 2));
7932 585 : if (CONST_INT_P (tem))
7933 : {
7934 554 : unsigned HOST_WIDE_INT sel1 = UINTVAL (tem);
7935 554 : if (!(~sel & sel1 & mask) && !side_effects_p (XEXP (op1, 0)))
7936 523 : return simplify_gen_ternary (code, mode, mode,
7937 523 : op0, XEXP (op1, 1), op2);
7938 31 : if (!(~sel & ~sel1 & mask) && !side_effects_p (XEXP (op1, 1)))
7939 4 : return simplify_gen_ternary (code, mode, mode,
7940 4 : op0, XEXP (op1, 0), op2);
7941 :
7942 : /* Replace (vec_merge a (vec_merge a b m) n) with
7943 : (vec_merge a b (m|n)). */
7944 27 : if (rtx_equal_p (XEXP (op1, 0), op0)
7945 27 : && ! side_effects_p (op0))
7946 1 : return simplify_gen_ternary (code, mode, mode,
7947 : op0, XEXP (op1, 1),
7948 1 : GEN_INT ((sel | sel1) & mask));
7949 :
7950 : /* Replace (vec_merge a (vec_merge b a m) n) with
7951 : (vec_merge a b (~m|n)). */
7952 26 : if (rtx_equal_p (XEXP (op1, 1), op0)
7953 26 : && ! side_effects_p (op0))
7954 0 : return simplify_gen_ternary (code, mode, mode,
7955 : op0, XEXP (op1, 0),
7956 0 : GEN_INT ((sel | ~sel1) & mask));
7957 : }
7958 : }
7959 :
7960 : /* Replace (vec_merge (vec_duplicate (vec_select a parallel (i))) a 1 << i)
7961 : with a. */
7962 704579 : if (GET_CODE (op0) == VEC_DUPLICATE
7963 398779 : && GET_CODE (XEXP (op0, 0)) == VEC_SELECT
7964 5369 : && GET_CODE (XEXP (XEXP (op0, 0), 1)) == PARALLEL
7965 715317 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (op0, 0))), 1))
7966 : {
7967 5301 : tem = XVECEXP ((XEXP (XEXP (op0, 0), 1)), 0, 0);
7968 5301 : if (CONST_INT_P (tem) && CONST_INT_P (op2))
7969 : {
7970 5301 : if (XEXP (XEXP (op0, 0), 0) == op1
7971 2 : && UINTVAL (op2) == HOST_WIDE_INT_1U << UINTVAL (tem))
7972 : return op1;
7973 : }
7974 : }
7975 : /* Replace (vec_merge (vec_duplicate (X)) (const_vector [A, B])
7976 : (const_int N))
7977 : with (vec_concat (X) (B)) if N == 1 or
7978 : (vec_concat (A) (X)) if N == 2. */
7979 704577 : if (GET_CODE (op0) == VEC_DUPLICATE
7980 398777 : && GET_CODE (op1) == CONST_VECTOR
7981 596982 : && known_eq (CONST_VECTOR_NUNITS (op1), 2)
7982 1804 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7983 705479 : && IN_RANGE (sel, 1, 2))
7984 : {
7985 900 : rtx newop0 = XEXP (op0, 0);
7986 900 : rtx newop1 = CONST_VECTOR_ELT (op1, 2 - sel);
7987 900 : if (sel == 2)
7988 111 : std::swap (newop0, newop1);
7989 900 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7990 : }
7991 : /* Replace (vec_merge (vec_duplicate x) (vec_concat (y) (z)) (const_int N))
7992 : with (vec_concat x z) if N == 1, or (vec_concat y x) if N == 2.
7993 : Only applies for vectors of two elements. */
7994 703677 : if (GET_CODE (op0) == VEC_DUPLICATE
7995 397877 : && GET_CODE (op1) == VEC_CONCAT
7996 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7997 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
7998 703677 : && IN_RANGE (sel, 1, 2))
7999 : {
8000 0 : rtx newop0 = XEXP (op0, 0);
8001 0 : rtx newop1 = XEXP (op1, 2 - sel);
8002 0 : rtx otherop = XEXP (op1, sel - 1);
8003 0 : if (sel == 2)
8004 0 : std::swap (newop0, newop1);
8005 : /* Don't want to throw away the other part of the vec_concat if
8006 : it has side-effects. */
8007 0 : if (!side_effects_p (otherop))
8008 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
8009 : }
8010 :
8011 : /* Replace:
8012 :
8013 : (vec_merge:outer (vec_duplicate:outer x:inner)
8014 : (subreg:outer y:inner 0)
8015 : (const_int N))
8016 :
8017 : with (vec_concat:outer x:inner y:inner) if N == 1,
8018 : or (vec_concat:outer y:inner x:inner) if N == 2.
8019 :
8020 : Implicitly, this means we have a paradoxical subreg, but such
8021 : a check is cheap, so make it anyway.
8022 :
8023 : Only applies for vectors of two elements. */
8024 703677 : if (GET_CODE (op0) == VEC_DUPLICATE
8025 397877 : && GET_CODE (op1) == SUBREG
8026 35075 : && GET_MODE (op1) == GET_MODE (op0)
8027 35075 : && GET_MODE (SUBREG_REG (op1)) == GET_MODE (XEXP (op0, 0))
8028 0 : && paradoxical_subreg_p (op1)
8029 0 : && subreg_lowpart_p (op1)
8030 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
8031 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
8032 703677 : && IN_RANGE (sel, 1, 2))
8033 : {
8034 0 : rtx newop0 = XEXP (op0, 0);
8035 0 : rtx newop1 = SUBREG_REG (op1);
8036 0 : if (sel == 2)
8037 0 : std::swap (newop0, newop1);
8038 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
8039 : }
8040 :
8041 : /* Same as above but with switched operands:
8042 : Replace (vec_merge:outer (subreg:outer x:inner 0)
8043 : (vec_duplicate:outer y:inner)
8044 : (const_int N))
8045 :
8046 : with (vec_concat:outer x:inner y:inner) if N == 1,
8047 : or (vec_concat:outer y:inner x:inner) if N == 2. */
8048 703677 : if (GET_CODE (op1) == VEC_DUPLICATE
8049 53857 : && GET_CODE (op0) == SUBREG
8050 20654 : && GET_MODE (op0) == GET_MODE (op1)
8051 20654 : && GET_MODE (SUBREG_REG (op0)) == GET_MODE (XEXP (op1, 0))
8052 0 : && paradoxical_subreg_p (op0)
8053 0 : && subreg_lowpart_p (op0)
8054 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
8055 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
8056 703677 : && IN_RANGE (sel, 1, 2))
8057 : {
8058 0 : rtx newop0 = SUBREG_REG (op0);
8059 0 : rtx newop1 = XEXP (op1, 0);
8060 0 : if (sel == 2)
8061 0 : std::swap (newop0, newop1);
8062 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
8063 : }
8064 :
8065 : /* Replace (vec_merge (vec_duplicate x) (vec_duplicate y)
8066 : (const_int n))
8067 : with (vec_concat x y) or (vec_concat y x) depending on value
8068 : of N. */
8069 703677 : if (GET_CODE (op0) == VEC_DUPLICATE
8070 397877 : && GET_CODE (op1) == VEC_DUPLICATE
8071 208 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
8072 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
8073 703677 : && IN_RANGE (sel, 1, 2))
8074 : {
8075 0 : rtx newop0 = XEXP (op0, 0);
8076 0 : rtx newop1 = XEXP (op1, 0);
8077 0 : if (sel == 2)
8078 0 : std::swap (newop0, newop1);
8079 :
8080 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
8081 : }
8082 : }
8083 :
8084 1030234 : if (rtx_equal_p (op0, op1)
8085 1030234 : && !side_effects_p (op2) && !side_effects_p (op1))
8086 : return op0;
8087 :
8088 1029938 : if (!side_effects_p (op2))
8089 : {
8090 1026150 : rtx top0
8091 1026150 : = may_trap_p (op0) ? NULL_RTX : simplify_merge_mask (op0, op2, 0);
8092 1026150 : rtx top1
8093 1026150 : = may_trap_p (op1) ? NULL_RTX : simplify_merge_mask (op1, op2, 1);
8094 1026150 : if (top0 || top1)
8095 998 : return simplify_gen_ternary (code, mode, mode,
8096 : top0 ? top0 : op0,
8097 819 : top1 ? top1 : op1, op2);
8098 : }
8099 :
8100 : break;
8101 :
8102 0 : default:
8103 0 : gcc_unreachable ();
8104 : }
8105 :
8106 : return 0;
8107 : }
8108 :
8109 : /* Try to calculate NUM_BYTES bytes of the target memory image of X,
8110 : starting at byte FIRST_BYTE. Return true on success and add the
8111 : bytes to BYTES, such that each byte has BITS_PER_UNIT bits and such
8112 : that the bytes follow target memory order. Leave BYTES unmodified
8113 : on failure.
8114 :
8115 : MODE is the mode of X. The caller must reserve NUM_BYTES bytes in
8116 : BYTES before calling this function. */
8117 :
8118 : bool
8119 13939368 : native_encode_rtx (machine_mode mode, rtx x, vec<target_unit> &bytes,
8120 : unsigned int first_byte, unsigned int num_bytes)
8121 : {
8122 : /* Check the mode is sensible. */
8123 13939368 : gcc_assert (GET_MODE (x) == VOIDmode
8124 : ? is_a <scalar_int_mode> (mode)
8125 : : mode == GET_MODE (x));
8126 :
8127 13939368 : if (GET_CODE (x) == CONST_VECTOR)
8128 : {
8129 : /* CONST_VECTOR_ELT follows target memory order, so no shuffling
8130 : is necessary. The only complication is that MODE_VECTOR_BOOL
8131 : vectors can have several elements per byte. */
8132 1123924 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
8133 : GET_MODE_NUNITS (mode));
8134 561962 : unsigned int elt = first_byte * BITS_PER_UNIT / elt_bits;
8135 561962 : if (elt_bits < BITS_PER_UNIT)
8136 : {
8137 : /* This is the only case in which elements can be smaller than
8138 : a byte. */
8139 0 : gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
8140 0 : auto mask = GET_MODE_MASK (GET_MODE_INNER (mode));
8141 0 : for (unsigned int i = 0; i < num_bytes; ++i)
8142 : {
8143 0 : target_unit value = 0;
8144 0 : for (unsigned int j = 0; j < BITS_PER_UNIT; j += elt_bits)
8145 : {
8146 0 : if (INTVAL (CONST_VECTOR_ELT (x, elt)))
8147 0 : value |= mask << j;
8148 0 : elt += 1;
8149 : }
8150 0 : bytes.quick_push (value);
8151 : }
8152 : return true;
8153 : }
8154 :
8155 561962 : unsigned int start = bytes.length ();
8156 561962 : unsigned int elt_bytes = GET_MODE_UNIT_SIZE (mode);
8157 : /* Make FIRST_BYTE relative to ELT. */
8158 561962 : first_byte %= elt_bytes;
8159 2813890 : while (num_bytes > 0)
8160 : {
8161 : /* Work out how many bytes we want from element ELT. */
8162 2251928 : unsigned int chunk_bytes = MIN (num_bytes, elt_bytes - first_byte);
8163 4503856 : if (!native_encode_rtx (GET_MODE_INNER (mode),
8164 : CONST_VECTOR_ELT (x, elt), bytes,
8165 : first_byte, chunk_bytes))
8166 : {
8167 0 : bytes.truncate (start);
8168 0 : return false;
8169 : }
8170 2251928 : elt += 1;
8171 2251928 : first_byte = 0;
8172 2251928 : num_bytes -= chunk_bytes;
8173 : }
8174 : return true;
8175 : }
8176 :
8177 : /* All subsequent cases are limited to scalars. */
8178 13377406 : scalar_mode smode;
8179 13377406 : if (!is_a <scalar_mode> (mode, &smode))
8180 : return false;
8181 :
8182 : /* Make sure that the region is in range. */
8183 13377406 : unsigned int end_byte = first_byte + num_bytes;
8184 13377406 : unsigned int mode_bytes = GET_MODE_SIZE (smode);
8185 13377406 : gcc_assert (end_byte <= mode_bytes);
8186 :
8187 13377406 : if (CONST_SCALAR_INT_P (x))
8188 : {
8189 : /* The target memory layout is affected by both BYTES_BIG_ENDIAN
8190 : and WORDS_BIG_ENDIAN. Use the subreg machinery to get the lsb
8191 : position of each byte. */
8192 12697459 : rtx_mode_t value (x, smode);
8193 12697459 : wide_int_ref value_wi (value);
8194 66781865 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
8195 : {
8196 : /* Always constant because the inputs are. */
8197 41386947 : unsigned int lsb
8198 41386947 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
8199 : /* Operate directly on the encoding rather than using
8200 : wi::extract_uhwi, so that we preserve the sign or zero
8201 : extension for modes that are not a whole number of bits in
8202 : size. (Zero extension is only used for the combination of
8203 : innermode == BImode && STORE_FLAG_VALUE == 1). */
8204 41386947 : unsigned int elt = lsb / HOST_BITS_PER_WIDE_INT;
8205 41386947 : unsigned int shift = lsb % HOST_BITS_PER_WIDE_INT;
8206 41386947 : unsigned HOST_WIDE_INT uhwi = value_wi.elt (elt);
8207 41386947 : bytes.quick_push (uhwi >> shift);
8208 : }
8209 12697459 : return true;
8210 : }
8211 :
8212 679947 : if (CONST_DOUBLE_P (x))
8213 : {
8214 : /* real_to_target produces an array of integers in target memory order.
8215 : All integers before the last one have 32 bits; the last one may
8216 : have 32 bits or fewer, depending on whether the mode bitsize
8217 : is divisible by 32. Each of these integers is then laid out
8218 : in target memory as any other integer would be. */
8219 651765 : long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
8220 651765 : real_to_target (el32, CONST_DOUBLE_REAL_VALUE (x), smode);
8221 :
8222 : /* The (maximum) number of target bytes per element of el32. */
8223 651765 : unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
8224 651765 : gcc_assert (bytes_per_el32 != 0);
8225 :
8226 : /* Build up the integers in a similar way to the CONST_SCALAR_INT_P
8227 : handling above. */
8228 4460672 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
8229 : {
8230 3808907 : unsigned int index = byte / bytes_per_el32;
8231 3808907 : unsigned int subbyte = byte % bytes_per_el32;
8232 3808907 : unsigned int int_bytes = MIN (bytes_per_el32,
8233 : mode_bytes - index * bytes_per_el32);
8234 : /* Always constant because the inputs are. */
8235 3808907 : unsigned int lsb
8236 3808907 : = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
8237 3808907 : bytes.quick_push ((unsigned long) el32[index] >> lsb);
8238 : }
8239 651765 : return true;
8240 : }
8241 :
8242 28182 : if (GET_CODE (x) == CONST_FIXED)
8243 : {
8244 0 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
8245 : {
8246 : /* Always constant because the inputs are. */
8247 0 : unsigned int lsb
8248 0 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
8249 0 : unsigned HOST_WIDE_INT piece = CONST_FIXED_VALUE_LOW (x);
8250 0 : if (lsb >= HOST_BITS_PER_WIDE_INT)
8251 : {
8252 0 : lsb -= HOST_BITS_PER_WIDE_INT;
8253 0 : piece = CONST_FIXED_VALUE_HIGH (x);
8254 : }
8255 0 : bytes.quick_push (piece >> lsb);
8256 : }
8257 : return true;
8258 : }
8259 :
8260 : return false;
8261 : }
8262 :
8263 : /* Read a vector of mode MODE from the target memory image given by BYTES,
8264 : starting at byte FIRST_BYTE. The vector is known to be encodable using
8265 : NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each,
8266 : and BYTES is known to have enough bytes to supply NPATTERNS *
8267 : NELTS_PER_PATTERN vector elements. Each element of BYTES contains
8268 : BITS_PER_UNIT bits and the bytes are in target memory order.
8269 :
8270 : Return the vector on success, otherwise return NULL_RTX. */
8271 :
8272 : rtx
8273 293720 : native_decode_vector_rtx (machine_mode mode, const vec<target_unit> &bytes,
8274 : unsigned int first_byte, unsigned int npatterns,
8275 : unsigned int nelts_per_pattern)
8276 : {
8277 293720 : rtx_vector_builder builder (mode, npatterns, nelts_per_pattern);
8278 :
8279 587440 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
8280 : GET_MODE_NUNITS (mode));
8281 293720 : if (elt_bits < BITS_PER_UNIT)
8282 : {
8283 : /* This is the only case in which elements can be smaller than a byte.
8284 : Element 0 is always in the lsb of the containing byte. */
8285 0 : gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
8286 0 : for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
8287 : {
8288 0 : unsigned int bit_index = first_byte * BITS_PER_UNIT + i * elt_bits;
8289 0 : unsigned int byte_index = bit_index / BITS_PER_UNIT;
8290 0 : unsigned int lsb = bit_index % BITS_PER_UNIT;
8291 0 : unsigned int value = bytes[byte_index] >> lsb;
8292 0 : builder.quick_push (gen_int_mode (value, GET_MODE_INNER (mode)));
8293 : }
8294 : }
8295 : else
8296 : {
8297 1189353 : for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
8298 : {
8299 1791266 : rtx x = native_decode_rtx (GET_MODE_INNER (mode), bytes, first_byte);
8300 895633 : if (!x)
8301 0 : return NULL_RTX;
8302 895633 : builder.quick_push (x);
8303 895633 : first_byte += elt_bits / BITS_PER_UNIT;
8304 : }
8305 : }
8306 293720 : return builder.build ();
8307 293720 : }
8308 :
8309 : /* Extract a PRECISION-bit integer from bytes [FIRST_BYTE, FIRST_BYTE + SIZE)
8310 : of target memory image BYTES. */
8311 :
8312 : wide_int
8313 11802621 : native_decode_int (const vec<target_unit> &bytes, unsigned int first_byte,
8314 : unsigned int size, unsigned int precision)
8315 : {
8316 : /* Pull the bytes msb first, so that we can use simple
8317 : shift-and-insert wide_int operations. */
8318 11802621 : wide_int result (wi::zero (precision));
8319 54384064 : for (unsigned int i = 0; i < size; ++i)
8320 : {
8321 42581443 : unsigned int lsb = (size - i - 1) * BITS_PER_UNIT;
8322 : /* Always constant because the inputs are. */
8323 42581443 : unsigned int subbyte
8324 42581443 : = subreg_size_offset_from_lsb (1, size, lsb).to_constant ();
8325 42581443 : result <<= BITS_PER_UNIT;
8326 42581443 : result |= bytes[first_byte + subbyte];
8327 : }
8328 11802621 : return result;
8329 : }
8330 :
8331 : /* Read an rtx of mode MODE from the target memory image given by BYTES,
8332 : starting at byte FIRST_BYTE. Each element of BYTES contains BITS_PER_UNIT
8333 : bits and the bytes are in target memory order. The image has enough
8334 : values to specify all bytes of MODE.
8335 :
8336 : Return the rtx on success, otherwise return NULL_RTX. */
8337 :
8338 : rtx
8339 12139060 : native_decode_rtx (machine_mode mode, const vec<target_unit> &bytes,
8340 : unsigned int first_byte)
8341 : {
8342 12139060 : if (VECTOR_MODE_P (mode))
8343 : {
8344 : /* If we know at compile time how many elements there are,
8345 : pull each element directly from BYTES. */
8346 91390 : unsigned int nelts;
8347 182780 : if (GET_MODE_NUNITS (mode).is_constant (&nelts))
8348 91390 : return native_decode_vector_rtx (mode, bytes, first_byte, nelts, 1);
8349 : return NULL_RTX;
8350 : }
8351 :
8352 12047670 : scalar_int_mode imode;
8353 12047670 : if (is_a <scalar_int_mode> (mode, &imode)
8354 11802621 : && GET_MODE_PRECISION (imode) <= MAX_BITSIZE_MODE_ANY_INT)
8355 : {
8356 11802621 : auto result = native_decode_int (bytes, first_byte,
8357 11802621 : GET_MODE_SIZE (imode),
8358 23605242 : GET_MODE_PRECISION (imode));
8359 11802621 : return immed_wide_int_const (result, imode);
8360 11802621 : }
8361 :
8362 245049 : scalar_float_mode fmode;
8363 245049 : if (is_a <scalar_float_mode> (mode, &fmode))
8364 : {
8365 : /* We need to build an array of integers in target memory order.
8366 : All integers before the last one have 32 bits; the last one may
8367 : have 32 bits or fewer, depending on whether the mode bitsize
8368 : is divisible by 32. */
8369 245019 : long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
8370 245019 : unsigned int num_el32 = CEIL (GET_MODE_BITSIZE (fmode), 32);
8371 245019 : memset (el32, 0, num_el32 * sizeof (long));
8372 :
8373 : /* The (maximum) number of target bytes per element of el32. */
8374 245019 : unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
8375 245019 : gcc_assert (bytes_per_el32 != 0);
8376 :
8377 245019 : unsigned int mode_bytes = GET_MODE_SIZE (fmode);
8378 1702889 : for (unsigned int byte = 0; byte < mode_bytes; ++byte)
8379 : {
8380 1457870 : unsigned int index = byte / bytes_per_el32;
8381 1457870 : unsigned int subbyte = byte % bytes_per_el32;
8382 1457870 : unsigned int int_bytes = MIN (bytes_per_el32,
8383 : mode_bytes - index * bytes_per_el32);
8384 : /* Always constant because the inputs are. */
8385 1457870 : unsigned int lsb
8386 1457870 : = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
8387 1457870 : el32[index] |= (unsigned long) bytes[first_byte + byte] << lsb;
8388 : }
8389 245019 : REAL_VALUE_TYPE r;
8390 245019 : real_from_target (&r, el32, fmode);
8391 245019 : return const_double_from_real_value (r, fmode);
8392 : }
8393 :
8394 30 : if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
8395 : {
8396 0 : scalar_mode smode = as_a <scalar_mode> (mode);
8397 0 : FIXED_VALUE_TYPE f;
8398 0 : f.data.low = 0;
8399 0 : f.data.high = 0;
8400 0 : f.mode = smode;
8401 :
8402 0 : unsigned int mode_bytes = GET_MODE_SIZE (smode);
8403 0 : for (unsigned int byte = 0; byte < mode_bytes; ++byte)
8404 : {
8405 : /* Always constant because the inputs are. */
8406 0 : unsigned int lsb
8407 0 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
8408 0 : unsigned HOST_WIDE_INT unit = bytes[first_byte + byte];
8409 0 : if (lsb >= HOST_BITS_PER_WIDE_INT)
8410 0 : f.data.high |= unit << (lsb - HOST_BITS_PER_WIDE_INT);
8411 : else
8412 0 : f.data.low |= unit << lsb;
8413 : }
8414 0 : return CONST_FIXED_FROM_FIXED_VALUE (f, mode);
8415 : }
8416 :
8417 : return NULL_RTX;
8418 : }
8419 :
8420 : /* Simplify a byte offset BYTE into CONST_VECTOR X. The main purpose
8421 : is to convert a runtime BYTE value into a constant one. */
8422 :
8423 : static poly_uint64
8424 352052 : simplify_const_vector_byte_offset (rtx x, poly_uint64 byte)
8425 : {
8426 : /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
8427 352052 : machine_mode mode = GET_MODE (x);
8428 704104 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
8429 : GET_MODE_NUNITS (mode));
8430 : /* The number of bits needed to encode one element from each pattern. */
8431 352052 : unsigned int sequence_bits = CONST_VECTOR_NPATTERNS (x) * elt_bits;
8432 :
8433 : /* Identify the start point in terms of a sequence number and a byte offset
8434 : within that sequence. */
8435 352052 : poly_uint64 first_sequence;
8436 352052 : unsigned HOST_WIDE_INT subbit;
8437 352052 : if (can_div_trunc_p (byte * BITS_PER_UNIT, sequence_bits,
8438 : &first_sequence, &subbit))
8439 : {
8440 352052 : unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
8441 352052 : if (nelts_per_pattern == 1)
8442 : /* This is a duplicated vector, so the value of FIRST_SEQUENCE
8443 : doesn't matter. */
8444 268983 : byte = subbit / BITS_PER_UNIT;
8445 83069 : else if (nelts_per_pattern == 2 && known_gt (first_sequence, 0U))
8446 : {
8447 : /* The subreg drops the first element from each pattern and
8448 : only uses the second element. Find the first sequence
8449 : that starts on a byte boundary. */
8450 5568 : subbit += least_common_multiple (sequence_bits, BITS_PER_UNIT);
8451 5568 : byte = subbit / BITS_PER_UNIT;
8452 : }
8453 : }
8454 352052 : return byte;
8455 : }
8456 :
8457 : /* Subroutine of simplify_subreg in which:
8458 :
8459 : - X is known to be a CONST_VECTOR
8460 : - OUTERMODE is known to be a vector mode
8461 :
8462 : Try to handle the subreg by operating on the CONST_VECTOR encoding
8463 : rather than on each individual element of the CONST_VECTOR.
8464 :
8465 : Return the simplified subreg on success, otherwise return NULL_RTX. */
8466 :
8467 : static rtx
8468 210319 : simplify_const_vector_subreg (machine_mode outermode, rtx x,
8469 : machine_mode innermode, unsigned int first_byte)
8470 : {
8471 : /* Paradoxical subregs of vectors have dubious semantics. */
8472 210319 : if (paradoxical_subreg_p (outermode, innermode))
8473 : return NULL_RTX;
8474 :
8475 : /* We can only preserve the semantics of a stepped pattern if the new
8476 : vector element is the same as the original one. */
8477 210171 : if (CONST_VECTOR_STEPPED_P (x)
8478 231077 : && GET_MODE_INNER (outermode) != GET_MODE_INNER (innermode))
8479 : return NULL_RTX;
8480 :
8481 : /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
8482 202330 : unsigned int x_elt_bits
8483 202330 : = vector_element_size (GET_MODE_PRECISION (innermode),
8484 : GET_MODE_NUNITS (innermode));
8485 202330 : unsigned int out_elt_bits
8486 202330 : = vector_element_size (GET_MODE_PRECISION (outermode),
8487 : GET_MODE_NUNITS (outermode));
8488 :
8489 : /* The number of bits needed to encode one element from every pattern
8490 : of the original vector. */
8491 202330 : unsigned int x_sequence_bits = CONST_VECTOR_NPATTERNS (x) * x_elt_bits;
8492 :
8493 : /* The number of bits needed to encode one element from every pattern
8494 : of the result. */
8495 202330 : unsigned int out_sequence_bits
8496 202330 : = least_common_multiple (x_sequence_bits, out_elt_bits);
8497 :
8498 : /* Work out the number of interleaved patterns in the output vector
8499 : and the number of encoded elements per pattern. */
8500 202330 : unsigned int out_npatterns = out_sequence_bits / out_elt_bits;
8501 202330 : unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
8502 :
8503 : /* The encoding scheme requires the number of elements to be a multiple
8504 : of the number of patterns, so that each pattern appears at least once
8505 : and so that the same number of elements appear from each pattern. */
8506 404660 : bool ok_p = multiple_p (GET_MODE_NUNITS (outermode), out_npatterns);
8507 202330 : unsigned int const_nunits;
8508 404660 : if (GET_MODE_NUNITS (outermode).is_constant (&const_nunits)
8509 202330 : && (!ok_p || out_npatterns * nelts_per_pattern > const_nunits))
8510 : {
8511 : /* Either the encoding is invalid, or applying it would give us
8512 : more elements than we need. Just encode each element directly. */
8513 : out_npatterns = const_nunits;
8514 : nelts_per_pattern = 1;
8515 : }
8516 : else if (!ok_p)
8517 : return NULL_RTX;
8518 :
8519 : /* Get enough bytes of X to form the new encoding. */
8520 202330 : unsigned int buffer_bits = out_npatterns * nelts_per_pattern * out_elt_bits;
8521 202330 : unsigned int buffer_bytes = CEIL (buffer_bits, BITS_PER_UNIT);
8522 202330 : auto_vec<target_unit, 128> buffer (buffer_bytes);
8523 202330 : if (!native_encode_rtx (innermode, x, buffer, first_byte, buffer_bytes))
8524 : return NULL_RTX;
8525 :
8526 : /* Re-encode the bytes as OUTERMODE. */
8527 202330 : return native_decode_vector_rtx (outermode, buffer, 0, out_npatterns,
8528 202330 : nelts_per_pattern);
8529 202330 : }
8530 :
8531 : /* Try to simplify a subreg of a constant by encoding the subreg region
8532 : as a sequence of target bytes and reading them back in the new mode.
8533 : Return the new value on success, otherwise return null.
8534 :
8535 : The subreg has outer mode OUTERMODE, inner mode INNERMODE, inner value X
8536 : and byte offset FIRST_BYTE. */
8537 :
8538 : static rtx
8539 10953790 : simplify_immed_subreg (fixed_size_mode outermode, rtx x,
8540 : machine_mode innermode, unsigned int first_byte)
8541 : {
8542 10953790 : unsigned int buffer_bytes = GET_MODE_SIZE (outermode);
8543 10953790 : auto_vec<target_unit, 128> buffer (buffer_bytes);
8544 :
8545 : /* Some ports misuse CCmode. */
8546 10953790 : if (GET_MODE_CLASS (outermode) == MODE_CC && CONST_INT_P (x))
8547 : return x;
8548 :
8549 : /* Paradoxical subregs read undefined values for bytes outside of the
8550 : inner value. However, we have traditionally always sign-extended
8551 : integer constants and zero-extended others. */
8552 10951784 : unsigned int inner_bytes = buffer_bytes;
8553 10951784 : if (paradoxical_subreg_p (outermode, innermode))
8554 : {
8555 1019830 : if (!GET_MODE_SIZE (innermode).is_constant (&inner_bytes))
8556 0 : return NULL_RTX;
8557 :
8558 509915 : target_unit filler = 0;
8559 509915 : if (CONST_SCALAR_INT_P (x) && wi::neg_p (rtx_mode_t (x, innermode)))
8560 51717 : filler = -1;
8561 :
8562 : /* Add any leading bytes due to big-endian layout. The number of
8563 : bytes must be constant because both modes have constant size. */
8564 509915 : unsigned int leading_bytes
8565 509915 : = -byte_lowpart_offset (outermode, innermode).to_constant ();
8566 509915 : for (unsigned int i = 0; i < leading_bytes; ++i)
8567 0 : buffer.quick_push (filler);
8568 :
8569 509915 : if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
8570 0 : return NULL_RTX;
8571 :
8572 : /* Add any trailing bytes due to little-endian layout. */
8573 6638654 : while (buffer.length () < buffer_bytes)
8574 2809412 : buffer.quick_push (filler);
8575 : }
8576 10441869 : else if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
8577 : return NULL_RTX;
8578 10951784 : rtx ret = native_decode_rtx (outermode, buffer, 0);
8579 10951784 : if (ret && FLOAT_MODE_P (outermode))
8580 : {
8581 129422 : auto_vec<target_unit, 128> buffer2 (buffer_bytes);
8582 129422 : if (!native_encode_rtx (outermode, ret, buffer2, 0, buffer_bytes))
8583 : return NULL_RTX;
8584 1424573 : for (unsigned int i = 0; i < buffer_bytes; ++i)
8585 1295186 : if (buffer[i] != buffer2[i])
8586 : return NULL_RTX;
8587 129422 : }
8588 : return ret;
8589 10953790 : }
8590 :
8591 : /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
8592 : Return 0 if no simplifications are possible. */
8593 : rtx
8594 74435167 : simplify_context::simplify_subreg (machine_mode outermode, rtx op,
8595 : machine_mode innermode, poly_uint64 byte)
8596 : {
8597 : /* Little bit of sanity checking. */
8598 74435167 : gcc_assert (innermode != VOIDmode);
8599 74435167 : gcc_assert (outermode != VOIDmode);
8600 74435167 : gcc_assert (innermode != BLKmode);
8601 74435167 : gcc_assert (outermode != BLKmode);
8602 :
8603 74435167 : gcc_assert (GET_MODE (op) == innermode
8604 : || GET_MODE (op) == VOIDmode);
8605 :
8606 148870334 : poly_uint64 outersize = GET_MODE_SIZE (outermode);
8607 74435167 : if (!multiple_p (byte, outersize))
8608 : return NULL_RTX;
8609 :
8610 148870294 : poly_uint64 innersize = GET_MODE_SIZE (innermode);
8611 74435147 : if (maybe_ge (byte, innersize))
8612 : return NULL_RTX;
8613 :
8614 74435147 : if (outermode == innermode && known_eq (byte, 0U))
8615 4599700 : return op;
8616 :
8617 69835447 : if (GET_CODE (op) == CONST_VECTOR)
8618 352052 : byte = simplify_const_vector_byte_offset (op, byte);
8619 :
8620 139670894 : if (multiple_p (byte, GET_MODE_UNIT_SIZE (innermode)))
8621 : {
8622 63816859 : rtx elt;
8623 :
8624 54821508 : if (VECTOR_MODE_P (outermode)
8625 26986053 : && GET_MODE_INNER (outermode) == GET_MODE_INNER (innermode)
8626 65574802 : && vec_duplicate_p (op, &elt))
8627 14307 : return gen_vec_duplicate (outermode, elt);
8628 :
8629 63810815 : if (outermode == GET_MODE_INNER (innermode)
8630 63810815 : && vec_duplicate_p (op, &elt))
8631 8263 : return elt;
8632 : }
8633 :
8634 69821140 : if (CONST_SCALAR_INT_P (op)
8635 59065892 : || CONST_DOUBLE_AS_FLOAT_P (op)
8636 59008539 : || CONST_FIXED_P (op)
8637 59008539 : || GET_CODE (op) == CONST_VECTOR)
8638 : {
8639 11156120 : unsigned HOST_WIDE_INT cbyte;
8640 11156120 : if (byte.is_constant (&cbyte))
8641 : {
8642 11156120 : if (GET_CODE (op) == CONST_VECTOR && VECTOR_MODE_P (outermode))
8643 : {
8644 210319 : rtx tmp = simplify_const_vector_subreg (outermode, op,
8645 : innermode, cbyte);
8646 210319 : if (tmp)
8647 11156120 : return tmp;
8648 : }
8649 :
8650 10953790 : fixed_size_mode fs_outermode;
8651 10953790 : if (is_a <fixed_size_mode> (outermode, &fs_outermode))
8652 10953790 : return simplify_immed_subreg (fs_outermode, op, innermode, cbyte);
8653 : }
8654 : }
8655 :
8656 : /* Changing mode twice with SUBREG => just change it once,
8657 : or not at all if changing back op starting mode. */
8658 58665020 : if (GET_CODE (op) == SUBREG)
8659 : {
8660 1337287 : machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
8661 2674574 : poly_uint64 innermostsize = GET_MODE_SIZE (innermostmode);
8662 1337287 : rtx newx;
8663 :
8664 : /* Make sure that the relationship between the two subregs is
8665 : known at compile time. */
8666 1337287 : if (!ordered_p (outersize, innermostsize))
8667 : return NULL_RTX;
8668 :
8669 1337287 : if (outermode == innermostmode
8670 665591 : && known_eq (byte, subreg_lowpart_offset (outermode, innermode))
8671 2002871 : && known_eq (SUBREG_BYTE (op),
8672 : subreg_lowpart_offset (innermode, innermostmode)))
8673 665584 : return SUBREG_REG (op);
8674 :
8675 : /* Work out the memory offset of the final OUTERMODE value relative
8676 : to the inner value of OP. */
8677 671703 : poly_int64 mem_offset = subreg_memory_offset (outermode,
8678 : innermode, byte);
8679 671703 : poly_int64 op_mem_offset = subreg_memory_offset (op);
8680 671703 : poly_int64 final_offset = mem_offset + op_mem_offset;
8681 :
8682 : /* See whether resulting subreg will be paradoxical. */
8683 671703 : if (!paradoxical_subreg_p (outermode, innermostmode))
8684 : {
8685 : /* Bail out in case resulting subreg would be incorrect. */
8686 1065196 : if (maybe_lt (final_offset, 0)
8687 1065189 : || maybe_ge (poly_uint64 (final_offset), innermostsize)
8688 1065189 : || !multiple_p (final_offset, outersize))
8689 : return NULL_RTX;
8690 : }
8691 : else
8692 : {
8693 139105 : poly_int64 required_offset = subreg_memory_offset (outermode,
8694 : innermostmode, 0);
8695 139105 : if (maybe_ne (final_offset, required_offset))
8696 0 : return NULL_RTX;
8697 : /* Paradoxical subregs always have byte offset 0. */
8698 139105 : final_offset = 0;
8699 : }
8700 :
8701 : /* Recurse for further possible simplifications. */
8702 671688 : newx = simplify_subreg (outermode, SUBREG_REG (op), innermostmode,
8703 671688 : final_offset);
8704 671688 : if (newx)
8705 : return newx;
8706 671291 : if (validate_subreg (outermode, innermostmode,
8707 671291 : SUBREG_REG (op), final_offset))
8708 : {
8709 611583 : newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
8710 611583 : if (SUBREG_PROMOTED_VAR_P (op)
8711 721 : && SUBREG_PROMOTED_SIGN (op) >= 0
8712 721 : && GET_MODE_CLASS (outermode) == MODE_INT
8713 717 : && known_ge (outersize, innersize)
8714 298 : && known_le (outersize, innermostsize)
8715 611593 : && subreg_lowpart_p (newx))
8716 : {
8717 10 : SUBREG_PROMOTED_VAR_P (newx) = 1;
8718 10 : SUBREG_PROMOTED_SET (newx, SUBREG_PROMOTED_GET (op));
8719 : }
8720 : return newx;
8721 : }
8722 : return NULL_RTX;
8723 : }
8724 :
8725 : /* SUBREG of a hard register => just change the register number
8726 : and/or mode. If the hard register is not valid in that mode,
8727 : suppress this simplification. If the hard register is the stack,
8728 : frame, or argument pointer, leave this as a SUBREG. */
8729 :
8730 57327733 : if (REG_P (op) && HARD_REGISTER_P (op))
8731 : {
8732 11072868 : unsigned int regno, final_regno;
8733 :
8734 11072868 : regno = REGNO (op);
8735 11072868 : final_regno = simplify_subreg_regno (regno, innermode, byte, outermode);
8736 11072868 : if (HARD_REGISTER_NUM_P (final_regno))
8737 : {
8738 11047177 : rtx x = gen_rtx_REG_offset (op, outermode, final_regno,
8739 : subreg_memory_offset (outermode,
8740 : innermode, byte));
8741 :
8742 : /* Propagate original regno. We don't have any way to specify
8743 : the offset inside original regno, so do so only for lowpart.
8744 : The information is used only by alias analysis that cannot
8745 : grog partial register anyway. */
8746 :
8747 11047177 : if (known_eq (subreg_lowpart_offset (outermode, innermode), byte))
8748 8276473 : ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op);
8749 : return x;
8750 : }
8751 : }
8752 :
8753 : /* If we have a SUBREG of a register that we are replacing and we are
8754 : replacing it with a MEM, make a new MEM and try replacing the
8755 : SUBREG with it. Don't do this if the MEM has a mode-dependent address
8756 : or if we would be widening it. */
8757 :
8758 46280556 : if (MEM_P (op)
8759 1660725 : && ! mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op))
8760 : /* Allow splitting of volatile memory references in case we don't
8761 : have instruction to move the whole thing. */
8762 1660722 : && (! MEM_VOLATILE_P (op)
8763 45486 : || ! have_insn_for (SET, innermode))
8764 : && !(STRICT_ALIGNMENT && MEM_ALIGN (op) < GET_MODE_ALIGNMENT (outermode))
8765 47895792 : && known_le (outersize, innersize))
8766 826087 : return adjust_address_nv (op, outermode, byte);
8767 :
8768 : /* Handle complex or vector values represented as CONCAT or VEC_CONCAT
8769 : of two parts. */
8770 45454469 : if (GET_CODE (op) == CONCAT
8771 45454469 : || GET_CODE (op) == VEC_CONCAT)
8772 : {
8773 258078 : poly_uint64 final_offset;
8774 258078 : rtx part, res;
8775 :
8776 258078 : machine_mode part_mode = GET_MODE (XEXP (op, 0));
8777 258078 : if (part_mode == VOIDmode)
8778 27 : part_mode = GET_MODE_INNER (GET_MODE (op));
8779 516156 : poly_uint64 part_size = GET_MODE_SIZE (part_mode);
8780 258078 : if (known_lt (byte, part_size))
8781 : {
8782 256567 : part = XEXP (op, 0);
8783 256567 : final_offset = byte;
8784 : }
8785 1511 : else if (known_ge (byte, part_size))
8786 : {
8787 1511 : part = XEXP (op, 1);
8788 1511 : final_offset = byte - part_size;
8789 : }
8790 : else
8791 : return NULL_RTX;
8792 :
8793 258078 : if (maybe_gt (final_offset + outersize, part_size))
8794 : return NULL_RTX;
8795 :
8796 128936 : part_mode = GET_MODE (part);
8797 128936 : if (part_mode == VOIDmode)
8798 0 : part_mode = GET_MODE_INNER (GET_MODE (op));
8799 128936 : res = simplify_subreg (outermode, part, part_mode, final_offset);
8800 128936 : if (res)
8801 : return res;
8802 306 : if (GET_MODE (part) != VOIDmode
8803 306 : && validate_subreg (outermode, part_mode, part, final_offset))
8804 306 : return gen_rtx_SUBREG (outermode, part, final_offset);
8805 : return NULL_RTX;
8806 : }
8807 :
8808 : /* Simplify
8809 : (subreg (vec_merge (X)
8810 : (vector)
8811 : (const_int ((1 << N) | M)))
8812 : (N * sizeof (outermode)))
8813 : to
8814 : (subreg (X) (N * sizeof (outermode)))
8815 : */
8816 45196391 : unsigned int idx;
8817 90392782 : if (constant_multiple_p (byte, GET_MODE_SIZE (outermode), &idx)
8818 45196391 : && idx < HOST_BITS_PER_WIDE_INT
8819 45196391 : && GET_CODE (op) == VEC_MERGE
8820 537194 : && GET_MODE_INNER (innermode) == outermode
8821 4889 : && CONST_INT_P (XEXP (op, 2))
8822 45200698 : && (UINTVAL (XEXP (op, 2)) & (HOST_WIDE_INT_1U << idx)) != 0)
8823 4298 : return simplify_gen_subreg (outermode, XEXP (op, 0), innermode, byte);
8824 :
8825 : /* A SUBREG resulting from a zero extension may fold to zero if
8826 : it extracts higher bits that the ZERO_EXTEND's source bits. */
8827 45192093 : if (GET_CODE (op) == ZERO_EXTEND && SCALAR_INT_MODE_P (innermode))
8828 : {
8829 232446 : poly_uint64 bitpos = subreg_lsb_1 (outermode, innermode, byte);
8830 232446 : if (known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (XEXP (op, 0)))))
8831 55291 : return CONST0_RTX (outermode);
8832 : }
8833 :
8834 : /* Optimize SUBREGS of scalar integral ASHIFT by a valid constant. */
8835 45136802 : if (GET_CODE (op) == ASHIFT
8836 1070053 : && SCALAR_INT_MODE_P (innermode)
8837 988432 : && CONST_INT_P (XEXP (op, 1))
8838 906233 : && INTVAL (XEXP (op, 1)) > 0
8839 47113088 : && known_gt (GET_MODE_BITSIZE (innermode), INTVAL (XEXP (op, 1))))
8840 : {
8841 906233 : HOST_WIDE_INT val = INTVAL (XEXP (op, 1));
8842 : /* A lowpart SUBREG of a ASHIFT by a constant may fold to zero. */
8843 906233 : if (known_eq (subreg_lowpart_offset (outermode, innermode), byte)
8844 1775008 : && known_le (GET_MODE_BITSIZE (outermode), val))
8845 192246 : return CONST0_RTX (outermode);
8846 : /* Optimize the highpart SUBREG of a suitable ASHIFT (ZERO_EXTEND). */
8847 748208 : if (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
8848 34901 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == outermode
8849 69484 : && known_eq (GET_MODE_BITSIZE (outermode), val)
8850 68442 : && known_eq (GET_MODE_BITSIZE (innermode), 2 * val)
8851 783109 : && known_eq (subreg_highpart_offset (outermode, innermode), byte))
8852 34221 : return XEXP (XEXP (op, 0), 0);
8853 : }
8854 :
8855 46547514 : auto distribute_subreg = [&](rtx op)
8856 : {
8857 1602958 : return simplify_subreg (outermode, op, innermode, byte);
8858 44944556 : };
8859 :
8860 : /* Try distributing the subreg through logic operations, if that
8861 : leads to all subexpressions being simplified. For example,
8862 : distributing the outer subreg in:
8863 :
8864 : (subreg:SI (not:QI (subreg:QI (reg:SI X) <lowpart>)) 0)
8865 :
8866 : gives:
8867 :
8868 : (not:SI (reg:SI X))
8869 :
8870 : This should be a win if the outermode is word_mode, since logical
8871 : operations on word_mode should (a) be no more expensive than logical
8872 : operations on subword modes and (b) are likely to be cheaper than
8873 : logical operations on multiword modes.
8874 :
8875 : Otherwise, handle the case where the subreg is non-narrowing and does
8876 : not change the number of words. The non-narrowing condition ensures
8877 : that we don't convert word_mode operations to subword operations. */
8878 44944556 : scalar_int_mode int_outermode, int_innermode;
8879 44944556 : if (is_a <scalar_int_mode> (outermode, &int_outermode)
8880 37878120 : && is_a <scalar_int_mode> (innermode, &int_innermode)
8881 81303972 : && (outermode == word_mode
8882 22013726 : || ((GET_MODE_PRECISION (int_outermode)
8883 22013726 : >= GET_MODE_PRECISION (int_innermode))
8884 4321174 : && (CEIL (GET_MODE_SIZE (int_outermode), UNITS_PER_WORD)
8885 4251441 : <= CEIL (GET_MODE_SIZE (int_innermode), UNITS_PER_WORD)))))
8886 18536690 : switch (GET_CODE (op))
8887 : {
8888 34875 : case NOT:
8889 34875 : if (rtx op0 = distribute_subreg (XEXP (op, 0)))
8890 1871 : return simplify_gen_unary (GET_CODE (op), outermode, op0, outermode);
8891 : break;
8892 :
8893 468197 : case AND:
8894 468197 : case IOR:
8895 468197 : case XOR:
8896 468197 : if (rtx op0 = distribute_subreg (XEXP (op, 0)))
8897 205232 : if (rtx op1 = distribute_subreg (XEXP (op, 1)))
8898 200444 : return simplify_gen_binary (GET_CODE (op), outermode, op0, op1);
8899 : break;
8900 :
8901 : default:
8902 : break;
8903 : }
8904 :
8905 44742241 : if (is_a <scalar_int_mode> (outermode, &int_outermode)
8906 37675805 : && is_a <scalar_int_mode> (innermode, &int_innermode)
8907 82418046 : && known_eq (byte, subreg_lowpart_offset (int_outermode, int_innermode)))
8908 : {
8909 : /* Handle polynomial integers. The upper bits of a paradoxical
8910 : subreg are undefined, so this is safe regardless of whether
8911 : we're truncating or extending. */
8912 33887047 : if (CONST_POLY_INT_P (op))
8913 : {
8914 : poly_wide_int val
8915 : = poly_wide_int::from (const_poly_int_value (op),
8916 : GET_MODE_PRECISION (int_outermode),
8917 : SIGNED);
8918 : return immed_wide_int_const (val, int_outermode);
8919 : }
8920 :
8921 33887047 : if (GET_MODE_PRECISION (int_outermode)
8922 33887047 : < GET_MODE_PRECISION (int_innermode))
8923 : {
8924 21235233 : rtx tem = simplify_truncation (int_outermode, op, int_innermode);
8925 21235233 : if (tem)
8926 : return tem;
8927 : }
8928 : }
8929 :
8930 : /* If the outer mode is not integral, try taking a subreg with the equivalent
8931 : integer outer mode and then bitcasting the result.
8932 : Other simplifications rely on integer to integer subregs and we'd
8933 : potentially miss out on optimizations otherwise. */
8934 85913724 : if (known_gt (GET_MODE_SIZE (innermode),
8935 : GET_MODE_SIZE (outermode))
8936 23086747 : && SCALAR_INT_MODE_P (innermode)
8937 21803785 : && !SCALAR_INT_MODE_P (outermode)
8938 66211363 : && int_mode_for_size (GET_MODE_BITSIZE (outermode),
8939 83877 : 0).exists (&int_outermode))
8940 : {
8941 83877 : rtx tem = simplify_subreg (int_outermode, op, innermode, byte);
8942 83877 : if (tem)
8943 1979 : return lowpart_subreg (outermode, tem, int_outermode);
8944 : }
8945 :
8946 : /* If OP is a vector comparison and the subreg is not changing the
8947 : number of elements or the size of the elements, change the result
8948 : of the comparison to the new mode. */
8949 42954883 : if (COMPARISON_P (op)
8950 302227 : && VECTOR_MODE_P (outermode)
8951 214097 : && VECTOR_MODE_P (innermode)
8952 642267 : && known_eq (GET_MODE_NUNITS (outermode), GET_MODE_NUNITS (innermode))
8953 43355950 : && known_eq (GET_MODE_UNIT_SIZE (outermode),
8954 : GET_MODE_UNIT_SIZE (innermode)))
8955 133345 : return simplify_gen_relational (GET_CODE (op), outermode, innermode,
8956 133345 : XEXP (op, 0), XEXP (op, 1));
8957 :
8958 : /* Distribute non-paradoxical subregs through logic ops in cases where
8959 : one term disappears.
8960 :
8961 : (subreg:M1 (and:M2 X C1)) -> (subreg:M1 X)
8962 : (subreg:M1 (ior:M2 X C1)) -> (subreg:M1 C1)
8963 : (subreg:M1 (xor:M2 X C1)) -> (subreg:M1 (not:M2 X))
8964 :
8965 : if M2 is no smaller than M1 and (subreg:M1 C1) is all-ones.
8966 :
8967 : (subreg:M1 (and:M2 X C2)) -> (subreg:M1 C2)
8968 : (subreg:M1 (ior/xor:M2 X C2)) -> (subreg:M1 X)
8969 :
8970 : if M2 is no smaller than M1 and (subreg:M1 C2) is zero. */
8971 42821538 : if (known_ge (innersize, outersize)
8972 29586584 : && GET_MODE_CLASS (outermode) == GET_MODE_CLASS (innermode)
8973 27237460 : && (GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR)
8974 44528705 : && CONSTANT_P (XEXP (op, 1)))
8975 : {
8976 887381 : rtx op1_subreg = distribute_subreg (XEXP (op, 1));
8977 887381 : if (op1_subreg == CONSTM1_RTX (outermode))
8978 : {
8979 120764 : if (GET_CODE (op) == IOR)
8980 : return op1_subreg;
8981 120530 : rtx op0 = XEXP (op, 0);
8982 120530 : if (GET_CODE (op) == XOR)
8983 909 : op0 = simplify_gen_unary (NOT, innermode, op0, innermode);
8984 120530 : return simplify_gen_subreg (outermode, op0, innermode, byte);
8985 : }
8986 :
8987 766617 : if (op1_subreg == CONST0_RTX (outermode))
8988 12384 : return (GET_CODE (op) == AND
8989 12384 : ? op1_subreg
8990 7273 : : distribute_subreg (XEXP (op, 0)));
8991 : }
8992 :
8993 : return NULL_RTX;
8994 : }
8995 :
8996 : /* Make a SUBREG operation or equivalent if it folds. */
8997 :
8998 : rtx
8999 45851139 : simplify_context::simplify_gen_subreg (machine_mode outermode, rtx op,
9000 : machine_mode innermode,
9001 : poly_uint64 byte)
9002 : {
9003 45851139 : rtx newx;
9004 :
9005 45851139 : newx = simplify_subreg (outermode, op, innermode, byte);
9006 45851139 : if (newx)
9007 : return newx;
9008 :
9009 21804744 : if (GET_CODE (op) == SUBREG
9010 21804744 : || GET_CODE (op) == CONCAT
9011 21768310 : || CONST_SCALAR_INT_P (op)
9012 21768284 : || CONST_DOUBLE_AS_FLOAT_P (op)
9013 21768284 : || CONST_FIXED_P (op)
9014 21768284 : || GET_CODE (op) == CONST_VECTOR)
9015 : return NULL_RTX;
9016 :
9017 21768274 : if (validate_subreg (outermode, innermode, op, byte))
9018 21735188 : return gen_rtx_SUBREG (outermode, op, byte);
9019 :
9020 : return NULL_RTX;
9021 : }
9022 :
9023 : /* Generates a subreg to get the least significant part of EXPR (in mode
9024 : INNER_MODE) to OUTER_MODE. */
9025 :
9026 : rtx
9027 33985532 : simplify_context::lowpart_subreg (machine_mode outer_mode, rtx expr,
9028 : machine_mode inner_mode)
9029 : {
9030 33985532 : return simplify_gen_subreg (outer_mode, expr, inner_mode,
9031 33985532 : subreg_lowpart_offset (outer_mode, inner_mode));
9032 : }
9033 :
9034 : /* Generate RTX to select element at INDEX out of vector OP. */
9035 :
9036 : rtx
9037 678673 : simplify_context::simplify_gen_vec_select (rtx op, unsigned int index)
9038 : {
9039 678673 : gcc_assert (VECTOR_MODE_P (GET_MODE (op)));
9040 :
9041 678673 : scalar_mode imode = GET_MODE_INNER (GET_MODE (op));
9042 :
9043 1357346 : if (known_eq (index * GET_MODE_SIZE (imode),
9044 : subreg_lowpart_offset (imode, GET_MODE (op))))
9045 : {
9046 678523 : rtx res = lowpart_subreg (imode, op, GET_MODE (op));
9047 678523 : if (res)
9048 : return res;
9049 : }
9050 :
9051 671 : rtx tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, GEN_INT (index)));
9052 671 : return gen_rtx_VEC_SELECT (imode, op, tmp);
9053 : }
9054 :
9055 :
9056 : /* Simplify X, an rtx expression.
9057 :
9058 : Return the simplified expression or NULL if no simplifications
9059 : were possible.
9060 :
9061 : This is the preferred entry point into the simplification routines;
9062 : however, we still allow passes to call the more specific routines.
9063 :
9064 : Right now GCC has three (yes, three) major bodies of RTL simplification
9065 : code that need to be unified.
9066 :
9067 : 1. fold_rtx in cse.cc. This code uses various CSE specific
9068 : information to aid in RTL simplification.
9069 :
9070 : 2. simplify_rtx in combine.cc. Similar to fold_rtx, except that
9071 : it uses combine specific information to aid in RTL
9072 : simplification.
9073 :
9074 : 3. The routines in this file.
9075 :
9076 :
9077 : Long term we want to only have one body of simplification code; to
9078 : get to that state I recommend the following steps:
9079 :
9080 : 1. Pour over fold_rtx & simplify_rtx and move any simplifications
9081 : which are not pass dependent state into these routines.
9082 :
9083 : 2. As code is moved by #1, change fold_rtx & simplify_rtx to
9084 : use this routine whenever possible.
9085 :
9086 : 3. Allow for pass dependent state to be provided to these
9087 : routines and add simplifications based on the pass dependent
9088 : state. Remove code from cse.cc & combine.cc that becomes
9089 : redundant/dead.
9090 :
9091 : It will take time, but ultimately the compiler will be easier to
9092 : maintain and improve. It's totally silly that when we add a
9093 : simplification that it needs to be added to 4 places (3 for RTL
9094 : simplification and 1 for tree simplification. */
9095 :
9096 : rtx
9097 47851852 : simplify_rtx (const_rtx x)
9098 : {
9099 47851852 : const enum rtx_code code = GET_CODE (x);
9100 47851852 : const machine_mode mode = GET_MODE (x);
9101 :
9102 47851852 : switch (GET_RTX_CLASS (code))
9103 : {
9104 783606 : case RTX_UNARY:
9105 1567212 : return simplify_unary_operation (code, mode,
9106 783606 : XEXP (x, 0), GET_MODE (XEXP (x, 0)));
9107 27394058 : case RTX_COMM_ARITH:
9108 27394058 : if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
9109 463072 : return simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
9110 :
9111 : /* Fall through. */
9112 :
9113 33567910 : case RTX_BIN_ARITH:
9114 33567910 : return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
9115 :
9116 109289 : case RTX_TERNARY:
9117 109289 : case RTX_BITFIELD_OPS:
9118 109289 : return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
9119 109289 : XEXP (x, 0), XEXP (x, 1),
9120 109289 : XEXP (x, 2));
9121 :
9122 230893 : case RTX_COMPARE:
9123 230893 : case RTX_COMM_COMPARE:
9124 230893 : return simplify_relational_operation (code, mode,
9125 230893 : ((GET_MODE (XEXP (x, 0))
9126 : != VOIDmode)
9127 : ? GET_MODE (XEXP (x, 0))
9128 329 : : GET_MODE (XEXP (x, 1))),
9129 230893 : XEXP (x, 0),
9130 461786 : XEXP (x, 1));
9131 :
9132 234360 : case RTX_EXTRA:
9133 234360 : if (code == SUBREG)
9134 2505 : return simplify_subreg (mode, SUBREG_REG (x),
9135 2505 : GET_MODE (SUBREG_REG (x)),
9136 2505 : SUBREG_BYTE (x));
9137 : break;
9138 :
9139 6693324 : case RTX_OBJ:
9140 6693324 : if (code == LO_SUM)
9141 : {
9142 : /* Convert (lo_sum (high FOO) FOO) to FOO. */
9143 0 : if (GET_CODE (XEXP (x, 0)) == HIGH
9144 0 : && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
9145 0 : return XEXP (x, 1);
9146 : }
9147 : break;
9148 :
9149 : default:
9150 : break;
9151 : }
9152 : return NULL;
9153 : }
9154 :
9155 : #if CHECKING_P
9156 :
9157 : namespace selftest {
9158 :
9159 : /* Make a unique pseudo REG of mode MODE for use by selftests. */
9160 :
9161 : static rtx
9162 2672 : make_test_reg (machine_mode mode)
9163 : {
9164 2672 : static int test_reg_num = LAST_VIRTUAL_REGISTER + 1;
9165 :
9166 2672 : return gen_rtx_REG (mode, test_reg_num++);
9167 : }
9168 :
9169 : static void
9170 40 : test_scalar_int_ops (machine_mode mode)
9171 : {
9172 40 : rtx op0 = make_test_reg (mode);
9173 40 : rtx op1 = make_test_reg (mode);
9174 40 : rtx six = GEN_INT (6);
9175 :
9176 40 : rtx neg_op0 = simplify_gen_unary (NEG, mode, op0, mode);
9177 40 : rtx not_op0 = simplify_gen_unary (NOT, mode, op0, mode);
9178 40 : rtx bswap_op0 = simplify_gen_unary (BSWAP, mode, op0, mode);
9179 :
9180 40 : rtx and_op0_op1 = simplify_gen_binary (AND, mode, op0, op1);
9181 40 : rtx ior_op0_op1 = simplify_gen_binary (IOR, mode, op0, op1);
9182 40 : rtx xor_op0_op1 = simplify_gen_binary (XOR, mode, op0, op1);
9183 :
9184 40 : rtx and_op0_6 = simplify_gen_binary (AND, mode, op0, six);
9185 40 : rtx and_op1_6 = simplify_gen_binary (AND, mode, op1, six);
9186 :
9187 : /* Test some binary identities. */
9188 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, op0, const0_rtx));
9189 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, const0_rtx, op0));
9190 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MINUS, mode, op0, const0_rtx));
9191 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, op0, const1_rtx));
9192 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, const1_rtx, op0));
9193 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (DIV, mode, op0, const1_rtx));
9194 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, constm1_rtx));
9195 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, constm1_rtx, op0));
9196 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, const0_rtx));
9197 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, const0_rtx, op0));
9198 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, op0, const0_rtx));
9199 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, const0_rtx, op0));
9200 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFT, mode, op0, const0_rtx));
9201 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATE, mode, op0, const0_rtx));
9202 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFTRT, mode, op0, const0_rtx));
9203 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (LSHIFTRT, mode, op0, const0_rtx));
9204 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATERT, mode, op0, const0_rtx));
9205 :
9206 : /* Test some self-inverse operations. */
9207 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (NEG, mode, neg_op0, mode));
9208 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (NOT, mode, not_op0, mode));
9209 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (BSWAP, mode, bswap_op0, mode));
9210 :
9211 : /* Test some reflexive operations. */
9212 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, op0));
9213 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, op0));
9214 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (SMIN, mode, op0, op0));
9215 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (SMAX, mode, op0, op0));
9216 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (UMIN, mode, op0, op0));
9217 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (UMAX, mode, op0, op0));
9218 :
9219 40 : ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (MINUS, mode, op0, op0));
9220 40 : ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (XOR, mode, op0, op0));
9221 :
9222 : /* Test simplify_distributive_operation. */
9223 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, xor_op0_op1, six),
9224 : simplify_gen_binary (XOR, mode, and_op0_6, and_op1_6));
9225 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, ior_op0_op1, six),
9226 : simplify_gen_binary (IOR, mode, and_op0_6, and_op1_6));
9227 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, and_op0_op1, six),
9228 : simplify_gen_binary (AND, mode, and_op0_6, and_op1_6));
9229 :
9230 : /* Test useless extensions are eliminated. */
9231 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (TRUNCATE, mode, op0, mode));
9232 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (ZERO_EXTEND, mode, op0, mode));
9233 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (SIGN_EXTEND, mode, op0, mode));
9234 40 : ASSERT_RTX_EQ (op0, lowpart_subreg (mode, op0, mode));
9235 40 : }
9236 :
9237 : /* Verify some simplifications of integer extension/truncation.
9238 : Machine mode BMODE is the guaranteed wider than SMODE. */
9239 :
9240 : static void
9241 24 : test_scalar_int_ext_ops (machine_mode bmode, machine_mode smode)
9242 : {
9243 24 : rtx sreg = make_test_reg (smode);
9244 :
9245 : /* Check truncation of extension. */
9246 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9247 : simplify_gen_unary (ZERO_EXTEND, bmode,
9248 : sreg, smode),
9249 : bmode),
9250 : sreg);
9251 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9252 : simplify_gen_unary (SIGN_EXTEND, bmode,
9253 : sreg, smode),
9254 : bmode),
9255 : sreg);
9256 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9257 : lowpart_subreg (bmode, sreg, smode),
9258 : bmode),
9259 : sreg);
9260 :
9261 : /* Test extensions, followed by logic ops, followed by truncations. */
9262 24 : rtx bsubreg = lowpart_subreg (bmode, sreg, smode);
9263 24 : rtx smask = gen_int_mode (GET_MODE_MASK (smode), bmode);
9264 24 : rtx inv_smask = gen_int_mode (~GET_MODE_MASK (smode), bmode);
9265 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9266 : simplify_gen_binary (AND, bmode,
9267 : bsubreg, smask),
9268 : bmode),
9269 : sreg);
9270 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9271 : simplify_gen_binary (AND, bmode,
9272 : bsubreg, inv_smask),
9273 : bmode),
9274 : const0_rtx);
9275 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9276 : simplify_gen_binary (IOR, bmode,
9277 : bsubreg, smask),
9278 : bmode),
9279 : constm1_rtx);
9280 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9281 : simplify_gen_binary (IOR, bmode,
9282 : bsubreg, inv_smask),
9283 : bmode),
9284 : sreg);
9285 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9286 : simplify_gen_binary (XOR, bmode,
9287 : bsubreg, smask),
9288 : bmode),
9289 : lowpart_subreg (smode,
9290 : gen_rtx_NOT (bmode, bsubreg),
9291 : bmode));
9292 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9293 : simplify_gen_binary (XOR, bmode,
9294 : bsubreg, inv_smask),
9295 : bmode),
9296 : sreg);
9297 :
9298 24 : if (known_le (GET_MODE_PRECISION (bmode), BITS_PER_WORD))
9299 : {
9300 24 : rtx breg1 = make_test_reg (bmode);
9301 24 : rtx breg2 = make_test_reg (bmode);
9302 24 : rtx ssubreg1 = lowpart_subreg (smode, breg1, bmode);
9303 24 : rtx ssubreg2 = lowpart_subreg (smode, breg2, bmode);
9304 24 : rtx not_1 = simplify_gen_unary (NOT, smode, ssubreg1, smode);
9305 24 : rtx and_12 = simplify_gen_binary (AND, smode, ssubreg1, ssubreg2);
9306 24 : rtx ior_12 = simplify_gen_binary (IOR, smode, ssubreg1, ssubreg2);
9307 24 : rtx xor_12 = simplify_gen_binary (XOR, smode, ssubreg1, ssubreg2);
9308 24 : rtx and_n12 = simplify_gen_binary (AND, smode, not_1, ssubreg2);
9309 24 : rtx ior_n12 = simplify_gen_binary (IOR, smode, not_1, ssubreg2);
9310 24 : rtx xor_12_c = simplify_gen_binary (XOR, smode, xor_12, const1_rtx);
9311 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, not_1, smode),
9312 : gen_rtx_NOT (bmode, breg1));
9313 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, and_12, smode),
9314 : gen_rtx_AND (bmode, breg1, breg2));
9315 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, ior_12, smode),
9316 : gen_rtx_IOR (bmode, breg1, breg2));
9317 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, xor_12, smode),
9318 : gen_rtx_XOR (bmode, breg1, breg2));
9319 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, and_n12, smode),
9320 : gen_rtx_AND (bmode, gen_rtx_NOT (bmode, breg1), breg2));
9321 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, ior_n12, smode),
9322 : gen_rtx_IOR (bmode, gen_rtx_NOT (bmode, breg1), breg2));
9323 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, xor_12_c, smode),
9324 : gen_rtx_XOR (bmode,
9325 : gen_rtx_XOR (bmode, breg1, breg2),
9326 : const1_rtx));
9327 : }
9328 24 : }
9329 :
9330 : /* Verify more simplifications of integer extension/truncation.
9331 : BMODE is wider than MMODE which is wider than SMODE. */
9332 :
9333 : static void
9334 16 : test_scalar_int_ext_ops2 (machine_mode bmode, machine_mode mmode,
9335 : machine_mode smode)
9336 : {
9337 16 : rtx breg = make_test_reg (bmode);
9338 16 : rtx mreg = make_test_reg (mmode);
9339 16 : rtx sreg = make_test_reg (smode);
9340 :
9341 : /* Check truncate of truncate. */
9342 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9343 : simplify_gen_unary (TRUNCATE, mmode,
9344 : breg, bmode),
9345 : mmode),
9346 : simplify_gen_unary (TRUNCATE, smode, breg, bmode));
9347 :
9348 : /* Check extension of extension. */
9349 16 : ASSERT_RTX_EQ (simplify_gen_unary (ZERO_EXTEND, bmode,
9350 : simplify_gen_unary (ZERO_EXTEND, mmode,
9351 : sreg, smode),
9352 : mmode),
9353 : simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
9354 16 : ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
9355 : simplify_gen_unary (SIGN_EXTEND, mmode,
9356 : sreg, smode),
9357 : mmode),
9358 : simplify_gen_unary (SIGN_EXTEND, bmode, sreg, smode));
9359 16 : ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
9360 : simplify_gen_unary (ZERO_EXTEND, mmode,
9361 : sreg, smode),
9362 : mmode),
9363 : simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
9364 :
9365 : /* Check truncation of extension. */
9366 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9367 : simplify_gen_unary (ZERO_EXTEND, bmode,
9368 : mreg, mmode),
9369 : bmode),
9370 : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
9371 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9372 : simplify_gen_unary (SIGN_EXTEND, bmode,
9373 : mreg, mmode),
9374 : bmode),
9375 : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
9376 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9377 : lowpart_subreg (bmode, mreg, mmode),
9378 : bmode),
9379 : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
9380 16 : }
9381 :
9382 : /* Test comparisons of comparisons, with the inner comparisons being
9383 : between values of mode MODE2 and producing results of mode MODE1,
9384 : and with the outer comparisons producing results of mode MODE0. */
9385 :
9386 : static void
9387 4 : test_comparisons (machine_mode mode0, machine_mode mode1, machine_mode mode2)
9388 : {
9389 4 : rtx reg0 = make_test_reg (mode2);
9390 4 : rtx reg1 = make_test_reg (mode2);
9391 :
9392 4 : static const rtx_code codes[] = {
9393 : EQ, NE, LT, LTU, LE, LEU, GE, GEU, GT, GTU
9394 : };
9395 4 : constexpr auto num_codes = ARRAY_SIZE (codes);
9396 4 : rtx cmps[num_codes];
9397 4 : rtx vals[] = { constm1_rtx, const0_rtx, const1_rtx };
9398 :
9399 44 : for (unsigned int i = 0; i < num_codes; ++i)
9400 40 : cmps[i] = gen_rtx_fmt_ee (codes[i], mode1, reg0, reg1);
9401 :
9402 44 : for (auto code : codes)
9403 440 : for (unsigned int i0 = 0; i0 < num_codes; ++i0)
9404 4400 : for (unsigned int i1 = 0; i1 < num_codes; ++i1)
9405 : {
9406 4000 : rtx cmp_res = simplify_relational_operation (code, mode0, mode1,
9407 : cmps[i0], cmps[i1]);
9408 4000 : if (i0 >= 2 && i1 >= 2 && (i0 ^ i1) & 1)
9409 1280 : ASSERT_TRUE (cmp_res == NULL_RTX);
9410 : else
9411 : {
9412 2720 : ASSERT_TRUE (cmp_res != NULL_RTX
9413 : && (CONSTANT_P (cmp_res)
9414 : || (COMPARISON_P (cmp_res)
9415 : && GET_MODE (cmp_res) == mode0
9416 : && REG_P (XEXP (cmp_res, 0))
9417 : && REG_P (XEXP (cmp_res, 1)))));
9418 10880 : for (rtx reg0_val : vals)
9419 32640 : for (rtx reg1_val : vals)
9420 : {
9421 24480 : rtx val0 = simplify_const_relational_operation
9422 24480 : (codes[i0], mode1, reg0_val, reg1_val);
9423 24480 : rtx val1 = simplify_const_relational_operation
9424 24480 : (codes[i1], mode1, reg0_val, reg1_val);
9425 24480 : rtx val = simplify_const_relational_operation
9426 24480 : (code, mode0, val0, val1);
9427 24480 : rtx folded = cmp_res;
9428 24480 : if (COMPARISON_P (cmp_res))
9429 16704 : folded = simplify_const_relational_operation
9430 16704 : (GET_CODE (cmp_res), mode0,
9431 16704 : XEXP (cmp_res, 0) == reg0 ? reg0_val : reg1_val,
9432 16704 : XEXP (cmp_res, 1) == reg0 ? reg0_val : reg1_val);
9433 24480 : ASSERT_RTX_EQ (val, folded);
9434 : }
9435 : }
9436 : }
9437 4 : }
9438 :
9439 :
9440 : /* Verify some simplifications involving scalar expressions. */
9441 :
9442 : static void
9443 4 : test_scalar_ops ()
9444 : {
9445 500 : for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
9446 : {
9447 496 : machine_mode mode = (machine_mode) i;
9448 496 : if (SCALAR_INT_MODE_P (mode) && mode != BImode)
9449 40 : test_scalar_int_ops (mode);
9450 : }
9451 :
9452 4 : test_scalar_int_ext_ops (HImode, QImode);
9453 4 : test_scalar_int_ext_ops (SImode, QImode);
9454 4 : test_scalar_int_ext_ops (SImode, HImode);
9455 4 : test_scalar_int_ext_ops (DImode, QImode);
9456 4 : test_scalar_int_ext_ops (DImode, HImode);
9457 4 : test_scalar_int_ext_ops (DImode, SImode);
9458 :
9459 4 : test_scalar_int_ext_ops2 (SImode, HImode, QImode);
9460 4 : test_scalar_int_ext_ops2 (DImode, HImode, QImode);
9461 4 : test_scalar_int_ext_ops2 (DImode, SImode, QImode);
9462 4 : test_scalar_int_ext_ops2 (DImode, SImode, HImode);
9463 :
9464 4 : test_comparisons (QImode, HImode, SImode);
9465 4 : }
9466 :
9467 : /* Test vector simplifications involving VEC_DUPLICATE in which the
9468 : operands and result have vector mode MODE. SCALAR_REG is a pseudo
9469 : register that holds one element of MODE. */
9470 :
9471 : static void
9472 224 : test_vector_ops_duplicate (machine_mode mode, rtx scalar_reg)
9473 : {
9474 224 : scalar_mode inner_mode = GET_MODE_INNER (mode);
9475 224 : rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
9476 448 : poly_uint64 nunits = GET_MODE_NUNITS (mode);
9477 224 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
9478 : {
9479 : /* Test some simple unary cases with VEC_DUPLICATE arguments. */
9480 124 : rtx not_scalar_reg = gen_rtx_NOT (inner_mode, scalar_reg);
9481 124 : rtx duplicate_not = gen_rtx_VEC_DUPLICATE (mode, not_scalar_reg);
9482 124 : ASSERT_RTX_EQ (duplicate,
9483 : simplify_unary_operation (NOT, mode,
9484 : duplicate_not, mode));
9485 :
9486 124 : rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
9487 124 : rtx duplicate_neg = gen_rtx_VEC_DUPLICATE (mode, neg_scalar_reg);
9488 124 : ASSERT_RTX_EQ (duplicate,
9489 : simplify_unary_operation (NEG, mode,
9490 : duplicate_neg, mode));
9491 :
9492 : /* Test some simple binary cases with VEC_DUPLICATE arguments. */
9493 124 : ASSERT_RTX_EQ (duplicate,
9494 : simplify_binary_operation (PLUS, mode, duplicate,
9495 : CONST0_RTX (mode)));
9496 :
9497 124 : ASSERT_RTX_EQ (duplicate,
9498 : simplify_binary_operation (MINUS, mode, duplicate,
9499 : CONST0_RTX (mode)));
9500 :
9501 124 : ASSERT_RTX_PTR_EQ (CONST0_RTX (mode),
9502 : simplify_binary_operation (MINUS, mode, duplicate,
9503 : duplicate));
9504 : }
9505 :
9506 : /* Test a scalar VEC_SELECT of a VEC_DUPLICATE. */
9507 224 : rtx zero_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const0_rtx));
9508 224 : ASSERT_RTX_PTR_EQ (scalar_reg,
9509 : simplify_binary_operation (VEC_SELECT, inner_mode,
9510 : duplicate, zero_par));
9511 :
9512 224 : unsigned HOST_WIDE_INT const_nunits;
9513 224 : if (nunits.is_constant (&const_nunits))
9514 : {
9515 : /* And again with the final element. */
9516 224 : rtx last_index = gen_int_mode (const_nunits - 1, word_mode);
9517 224 : rtx last_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, last_index));
9518 224 : ASSERT_RTX_PTR_EQ (scalar_reg,
9519 : simplify_binary_operation (VEC_SELECT, inner_mode,
9520 : duplicate, last_par));
9521 :
9522 : /* Test a scalar subreg of a VEC_MERGE of a VEC_DUPLICATE. */
9523 : /* Skip this test for vectors of booleans, because offset is in bytes,
9524 : while vec_merge indices are in elements (usually bits). */
9525 224 : if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
9526 : {
9527 224 : rtx vector_reg = make_test_reg (mode);
9528 3732 : for (unsigned HOST_WIDE_INT i = 0; i < const_nunits; i++)
9529 : {
9530 3288 : if (i >= HOST_BITS_PER_WIDE_INT)
9531 : break;
9532 3284 : rtx mask = GEN_INT ((HOST_WIDE_INT_1U << i) | (i + 1));
9533 3284 : rtx vm = gen_rtx_VEC_MERGE (mode, duplicate, vector_reg, mask);
9534 6568 : poly_uint64 offset = i * GET_MODE_SIZE (inner_mode);
9535 :
9536 3284 : ASSERT_RTX_EQ (scalar_reg,
9537 : simplify_gen_subreg (inner_mode, vm,
9538 : mode, offset));
9539 : }
9540 : }
9541 : }
9542 :
9543 : /* Test a scalar subreg of a VEC_DUPLICATE. */
9544 224 : poly_uint64 offset = subreg_lowpart_offset (inner_mode, mode);
9545 224 : ASSERT_RTX_EQ (scalar_reg,
9546 : simplify_gen_subreg (inner_mode, duplicate,
9547 : mode, offset));
9548 :
9549 224 : machine_mode narrower_mode;
9550 224 : if (maybe_ne (nunits, 2U)
9551 184 : && multiple_p (nunits, 2)
9552 396 : && mode_for_vector (inner_mode, 2).exists (&narrower_mode)
9553 396 : && VECTOR_MODE_P (narrower_mode))
9554 : {
9555 : /* Test VEC_DUPLICATE of a vector. */
9556 172 : rtx_vector_builder nbuilder (narrower_mode, 2, 1);
9557 172 : nbuilder.quick_push (const0_rtx);
9558 172 : nbuilder.quick_push (const1_rtx);
9559 172 : rtx_vector_builder builder (mode, 2, 1);
9560 172 : builder.quick_push (const0_rtx);
9561 172 : builder.quick_push (const1_rtx);
9562 172 : ASSERT_RTX_EQ (builder.build (),
9563 : simplify_unary_operation (VEC_DUPLICATE, mode,
9564 : nbuilder.build (),
9565 : narrower_mode));
9566 :
9567 : /* Test VEC_SELECT of a vector. */
9568 172 : rtx vec_par
9569 172 : = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, const1_rtx, const0_rtx));
9570 172 : rtx narrower_duplicate
9571 172 : = gen_rtx_VEC_DUPLICATE (narrower_mode, scalar_reg);
9572 172 : ASSERT_RTX_EQ (narrower_duplicate,
9573 : simplify_binary_operation (VEC_SELECT, narrower_mode,
9574 : duplicate, vec_par));
9575 :
9576 : /* Test a vector subreg of a VEC_DUPLICATE. */
9577 172 : poly_uint64 offset = subreg_lowpart_offset (narrower_mode, mode);
9578 172 : ASSERT_RTX_EQ (narrower_duplicate,
9579 : simplify_gen_subreg (narrower_mode, duplicate,
9580 : mode, offset));
9581 172 : }
9582 224 : }
9583 :
9584 : /* Test vector simplifications involving VEC_SERIES in which the
9585 : operands and result have vector mode MODE. SCALAR_REG is a pseudo
9586 : register that holds one element of MODE. */
9587 :
9588 : static void
9589 92 : test_vector_ops_series (machine_mode mode, rtx scalar_reg)
9590 : {
9591 : /* Test unary cases with VEC_SERIES arguments. */
9592 92 : scalar_mode inner_mode = GET_MODE_INNER (mode);
9593 92 : rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
9594 92 : rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
9595 92 : rtx series_0_r = gen_rtx_VEC_SERIES (mode, const0_rtx, scalar_reg);
9596 92 : rtx series_0_nr = gen_rtx_VEC_SERIES (mode, const0_rtx, neg_scalar_reg);
9597 92 : rtx series_nr_1 = gen_rtx_VEC_SERIES (mode, neg_scalar_reg, const1_rtx);
9598 92 : rtx series_r_m1 = gen_rtx_VEC_SERIES (mode, scalar_reg, constm1_rtx);
9599 92 : rtx series_r_r = gen_rtx_VEC_SERIES (mode, scalar_reg, scalar_reg);
9600 92 : rtx series_nr_nr = gen_rtx_VEC_SERIES (mode, neg_scalar_reg,
9601 : neg_scalar_reg);
9602 92 : ASSERT_RTX_EQ (series_0_r,
9603 : simplify_unary_operation (NEG, mode, series_0_nr, mode));
9604 92 : ASSERT_RTX_EQ (series_r_m1,
9605 : simplify_unary_operation (NEG, mode, series_nr_1, mode));
9606 92 : ASSERT_RTX_EQ (series_r_r,
9607 : simplify_unary_operation (NEG, mode, series_nr_nr, mode));
9608 :
9609 : /* Test that a VEC_SERIES with a zero step is simplified away. */
9610 92 : ASSERT_RTX_EQ (duplicate,
9611 : simplify_binary_operation (VEC_SERIES, mode,
9612 : scalar_reg, const0_rtx));
9613 :
9614 : /* Test PLUS and MINUS with VEC_SERIES. */
9615 92 : rtx series_0_1 = gen_const_vec_series (mode, const0_rtx, const1_rtx);
9616 92 : rtx series_0_m1 = gen_const_vec_series (mode, const0_rtx, constm1_rtx);
9617 92 : rtx series_r_1 = gen_rtx_VEC_SERIES (mode, scalar_reg, const1_rtx);
9618 92 : ASSERT_RTX_EQ (series_r_r,
9619 : simplify_binary_operation (PLUS, mode, series_0_r,
9620 : duplicate));
9621 92 : ASSERT_RTX_EQ (series_r_1,
9622 : simplify_binary_operation (PLUS, mode, duplicate,
9623 : series_0_1));
9624 92 : ASSERT_RTX_EQ (series_r_m1,
9625 : simplify_binary_operation (PLUS, mode, duplicate,
9626 : series_0_m1));
9627 92 : ASSERT_RTX_EQ (series_0_r,
9628 : simplify_binary_operation (MINUS, mode, series_r_r,
9629 : duplicate));
9630 92 : ASSERT_RTX_EQ (series_r_m1,
9631 : simplify_binary_operation (MINUS, mode, duplicate,
9632 : series_0_1));
9633 92 : ASSERT_RTX_EQ (series_r_1,
9634 : simplify_binary_operation (MINUS, mode, duplicate,
9635 : series_0_m1));
9636 92 : ASSERT_RTX_EQ (series_0_m1,
9637 : simplify_binary_operation (VEC_SERIES, mode, const0_rtx,
9638 : constm1_rtx));
9639 :
9640 : /* Test NEG on constant vector series. */
9641 92 : ASSERT_RTX_EQ (series_0_m1,
9642 : simplify_unary_operation (NEG, mode, series_0_1, mode));
9643 92 : ASSERT_RTX_EQ (series_0_1,
9644 : simplify_unary_operation (NEG, mode, series_0_m1, mode));
9645 :
9646 : /* Test PLUS and MINUS on constant vector series. */
9647 92 : rtx scalar2 = gen_int_mode (2, inner_mode);
9648 92 : rtx scalar3 = gen_int_mode (3, inner_mode);
9649 92 : rtx series_1_1 = gen_const_vec_series (mode, const1_rtx, const1_rtx);
9650 92 : rtx series_0_2 = gen_const_vec_series (mode, const0_rtx, scalar2);
9651 92 : rtx series_1_3 = gen_const_vec_series (mode, const1_rtx, scalar3);
9652 92 : ASSERT_RTX_EQ (series_1_1,
9653 : simplify_binary_operation (PLUS, mode, series_0_1,
9654 : CONST1_RTX (mode)));
9655 92 : ASSERT_RTX_EQ (series_0_m1,
9656 : simplify_binary_operation (PLUS, mode, CONST0_RTX (mode),
9657 : series_0_m1));
9658 92 : ASSERT_RTX_EQ (series_1_3,
9659 : simplify_binary_operation (PLUS, mode, series_1_1,
9660 : series_0_2));
9661 92 : ASSERT_RTX_EQ (series_0_1,
9662 : simplify_binary_operation (MINUS, mode, series_1_1,
9663 : CONST1_RTX (mode)));
9664 92 : ASSERT_RTX_EQ (series_1_1,
9665 : simplify_binary_operation (MINUS, mode, CONST1_RTX (mode),
9666 : series_0_m1));
9667 92 : ASSERT_RTX_EQ (series_1_1,
9668 : simplify_binary_operation (MINUS, mode, series_1_3,
9669 : series_0_2));
9670 :
9671 : /* Test MULT between constant vectors. */
9672 92 : rtx vec2 = gen_const_vec_duplicate (mode, scalar2);
9673 92 : rtx vec3 = gen_const_vec_duplicate (mode, scalar3);
9674 92 : rtx scalar9 = gen_int_mode (9, inner_mode);
9675 92 : rtx series_3_9 = gen_const_vec_series (mode, scalar3, scalar9);
9676 92 : ASSERT_RTX_EQ (series_0_2,
9677 : simplify_binary_operation (MULT, mode, series_0_1, vec2));
9678 92 : ASSERT_RTX_EQ (series_3_9,
9679 : simplify_binary_operation (MULT, mode, vec3, series_1_3));
9680 92 : if (!GET_MODE_NUNITS (mode).is_constant ())
9681 : ASSERT_FALSE (simplify_binary_operation (MULT, mode, series_0_1,
9682 : series_0_1));
9683 :
9684 : /* Test ASHIFT between constant vectors. */
9685 92 : ASSERT_RTX_EQ (series_0_2,
9686 : simplify_binary_operation (ASHIFT, mode, series_0_1,
9687 : CONST1_RTX (mode)));
9688 92 : if (!GET_MODE_NUNITS (mode).is_constant ())
9689 : ASSERT_FALSE (simplify_binary_operation (ASHIFT, mode, CONST1_RTX (mode),
9690 : series_0_1));
9691 92 : }
9692 :
9693 : static rtx
9694 3136 : simplify_merge_mask (rtx x, rtx mask, int op)
9695 : {
9696 0 : return simplify_context ().simplify_merge_mask (x, mask, op);
9697 : }
9698 :
9699 : /* Verify simplify_merge_mask works correctly. */
9700 :
9701 : static void
9702 224 : test_vec_merge (machine_mode mode)
9703 : {
9704 224 : rtx op0 = make_test_reg (mode);
9705 224 : rtx op1 = make_test_reg (mode);
9706 224 : rtx op2 = make_test_reg (mode);
9707 224 : rtx op3 = make_test_reg (mode);
9708 224 : rtx op4 = make_test_reg (mode);
9709 224 : rtx op5 = make_test_reg (mode);
9710 224 : rtx mask1 = make_test_reg (SImode);
9711 224 : rtx mask2 = make_test_reg (SImode);
9712 224 : rtx vm1 = gen_rtx_VEC_MERGE (mode, op0, op1, mask1);
9713 224 : rtx vm2 = gen_rtx_VEC_MERGE (mode, op2, op3, mask1);
9714 224 : rtx vm3 = gen_rtx_VEC_MERGE (mode, op4, op5, mask1);
9715 :
9716 : /* Simple vec_merge. */
9717 224 : ASSERT_EQ (op0, simplify_merge_mask (vm1, mask1, 0));
9718 224 : ASSERT_EQ (op1, simplify_merge_mask (vm1, mask1, 1));
9719 224 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 0));
9720 224 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 1));
9721 :
9722 : /* Nested vec_merge.
9723 : It's tempting to make this simplify right down to opN, but we don't
9724 : because all the simplify_* functions assume that the operands have
9725 : already been simplified. */
9726 224 : rtx nvm = gen_rtx_VEC_MERGE (mode, vm1, vm2, mask1);
9727 224 : ASSERT_EQ (vm1, simplify_merge_mask (nvm, mask1, 0));
9728 224 : ASSERT_EQ (vm2, simplify_merge_mask (nvm, mask1, 1));
9729 :
9730 : /* Intermediate unary op. */
9731 224 : rtx unop = gen_rtx_NOT (mode, vm1);
9732 224 : ASSERT_RTX_EQ (gen_rtx_NOT (mode, op0),
9733 : simplify_merge_mask (unop, mask1, 0));
9734 224 : ASSERT_RTX_EQ (gen_rtx_NOT (mode, op1),
9735 : simplify_merge_mask (unop, mask1, 1));
9736 :
9737 : /* Intermediate binary op. */
9738 224 : rtx binop = gen_rtx_PLUS (mode, vm1, vm2);
9739 224 : ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op0, op2),
9740 : simplify_merge_mask (binop, mask1, 0));
9741 224 : ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op1, op3),
9742 : simplify_merge_mask (binop, mask1, 1));
9743 :
9744 : /* Intermediate ternary op. */
9745 224 : rtx tenop = gen_rtx_FMA (mode, vm1, vm2, vm3);
9746 224 : ASSERT_RTX_EQ (gen_rtx_FMA (mode, op0, op2, op4),
9747 : simplify_merge_mask (tenop, mask1, 0));
9748 224 : ASSERT_RTX_EQ (gen_rtx_FMA (mode, op1, op3, op5),
9749 : simplify_merge_mask (tenop, mask1, 1));
9750 :
9751 : /* Side effects. */
9752 224 : rtx badop0 = gen_rtx_PRE_INC (mode, op0);
9753 224 : rtx badvm = gen_rtx_VEC_MERGE (mode, badop0, op1, mask1);
9754 224 : ASSERT_EQ (badop0, simplify_merge_mask (badvm, mask1, 0));
9755 224 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (badvm, mask1, 1));
9756 :
9757 : /* Called indirectly. */
9758 224 : ASSERT_RTX_EQ (gen_rtx_VEC_MERGE (mode, op0, op3, mask1),
9759 : simplify_rtx (nvm));
9760 224 : }
9761 :
9762 : /* Test that vector rotate formation works at RTL level. Try various
9763 : combinations of (REG << C) [|,^,+] (REG >> (<bitwidth> - C)). */
9764 :
9765 : static void
9766 92 : test_vector_rotate (rtx reg)
9767 : {
9768 92 : machine_mode mode = GET_MODE (reg);
9769 92 : unsigned bitwidth = GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT;
9770 92 : rtx plus_rtx = gen_rtx_PLUS (mode, reg, reg);
9771 92 : rtx lshftrt_amnt = GEN_INT (bitwidth - 1);
9772 92 : lshftrt_amnt = gen_const_vec_duplicate (mode, lshftrt_amnt);
9773 92 : rtx lshiftrt_rtx = gen_rtx_LSHIFTRT (mode, reg, lshftrt_amnt);
9774 92 : rtx rotate_rtx = gen_rtx_ROTATE (mode, reg, CONST1_RTX (mode));
9775 : /* Test explicitly the case where ASHIFT (x, 1) is a PLUS (x, x). */
9776 92 : ASSERT_RTX_EQ (rotate_rtx,
9777 : simplify_rtx (gen_rtx_IOR (mode, plus_rtx, lshiftrt_rtx)));
9778 92 : ASSERT_RTX_EQ (rotate_rtx,
9779 : simplify_rtx (gen_rtx_XOR (mode, plus_rtx, lshiftrt_rtx)));
9780 92 : ASSERT_RTX_EQ (rotate_rtx,
9781 : simplify_rtx (gen_rtx_PLUS (mode, plus_rtx, lshiftrt_rtx)));
9782 :
9783 : /* Don't go through every possible rotate amount to save execution time.
9784 : Multiple of BITS_PER_UNIT amounts could conceivably be simplified to
9785 : other bswap operations sometimes. Go through just the odd amounts. */
9786 1380 : for (unsigned i = 3; i < bitwidth - 2; i += 2)
9787 : {
9788 1288 : rtx rot_amnt = gen_const_vec_duplicate (mode, GEN_INT (i));
9789 1288 : rtx ashift_rtx = gen_rtx_ASHIFT (mode, reg, rot_amnt);
9790 1288 : lshftrt_amnt = gen_const_vec_duplicate (mode, GEN_INT (bitwidth - i));
9791 1288 : lshiftrt_rtx = gen_rtx_LSHIFTRT (mode, reg, lshftrt_amnt);
9792 1288 : rotate_rtx = gen_rtx_ROTATE (mode, reg, rot_amnt);
9793 1288 : ASSERT_RTX_EQ (rotate_rtx,
9794 : simplify_rtx (gen_rtx_IOR (mode, ashift_rtx, lshiftrt_rtx)));
9795 1288 : ASSERT_RTX_EQ (rotate_rtx,
9796 : simplify_rtx (gen_rtx_XOR (mode, ashift_rtx, lshiftrt_rtx)));
9797 1288 : ASSERT_RTX_EQ (rotate_rtx,
9798 : simplify_rtx (gen_rtx_PLUS (mode, ashift_rtx, lshiftrt_rtx)));
9799 : }
9800 92 : }
9801 :
9802 : /* Test subregs of integer vector constant X, trying elements in
9803 : the range [ELT_BIAS, ELT_BIAS + constant_lower_bound (NELTS)),
9804 : where NELTS is the number of elements in X. Subregs involving
9805 : elements [ELT_BIAS, ELT_BIAS + FIRST_VALID) are expected to fail. */
9806 :
9807 : static void
9808 276 : test_vector_subregs_modes (rtx x, poly_uint64 elt_bias = 0,
9809 : unsigned int first_valid = 0)
9810 : {
9811 276 : machine_mode inner_mode = GET_MODE (x);
9812 276 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9813 :
9814 34500 : for (unsigned int modei = 0; modei < NUM_MACHINE_MODES; ++modei)
9815 : {
9816 34224 : machine_mode outer_mode = (machine_mode) modei;
9817 34224 : if (!VECTOR_MODE_P (outer_mode))
9818 18768 : continue;
9819 :
9820 15456 : unsigned int outer_nunits;
9821 15456 : if (GET_MODE_INNER (outer_mode) == int_mode
9822 1932 : && GET_MODE_NUNITS (outer_mode).is_constant (&outer_nunits)
9823 20412 : && multiple_p (GET_MODE_NUNITS (inner_mode), outer_nunits))
9824 : {
9825 : /* Test subregs in which the outer mode is a smaller,
9826 : constant-sized vector of the same element type. */
9827 1092 : unsigned int limit
9828 1092 : = constant_lower_bound (GET_MODE_NUNITS (inner_mode));
9829 8028 : for (unsigned int elt = 0; elt < limit; elt += outer_nunits)
9830 : {
9831 6936 : rtx expected = NULL_RTX;
9832 6936 : if (elt >= first_valid)
9833 : {
9834 6936 : rtx_vector_builder builder (outer_mode, outer_nunits, 1);
9835 46704 : for (unsigned int i = 0; i < outer_nunits; ++i)
9836 32832 : builder.quick_push (CONST_VECTOR_ELT (x, elt + i));
9837 6936 : expected = builder.build ();
9838 6936 : }
9839 13872 : poly_uint64 byte = (elt_bias + elt) * GET_MODE_SIZE (int_mode);
9840 6936 : ASSERT_RTX_EQ (expected,
9841 : simplify_subreg (outer_mode, x,
9842 : inner_mode, byte));
9843 : }
9844 : }
9845 28728 : else if (known_eq (GET_MODE_SIZE (outer_mode),
9846 : GET_MODE_SIZE (inner_mode))
9847 2040 : && known_eq (elt_bias, 0U)
9848 2040 : && (GET_MODE_CLASS (outer_mode) != MODE_VECTOR_BOOL
9849 0 : || known_eq (GET_MODE_BITSIZE (outer_mode),
9850 : GET_MODE_NUNITS (outer_mode)))
9851 2040 : && (!FLOAT_MODE_P (outer_mode)
9852 15876 : || (FLOAT_MODE_FORMAT (outer_mode)->ieee_bits
9853 1104 : == GET_MODE_UNIT_PRECISION (outer_mode)))
9854 14364 : && (GET_MODE_SIZE (inner_mode).is_constant ()
9855 : || !CONST_VECTOR_STEPPED_P (x)))
9856 : {
9857 : /* Try converting to OUTER_MODE and back. */
9858 1800 : rtx outer_x = simplify_subreg (outer_mode, x, inner_mode, 0);
9859 1800 : ASSERT_TRUE (outer_x != NULL_RTX);
9860 1800 : ASSERT_RTX_EQ (x, simplify_subreg (inner_mode, outer_x,
9861 : outer_mode, 0));
9862 : }
9863 : }
9864 :
9865 276 : if (BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
9866 : {
9867 : /* Test each byte in the element range. */
9868 276 : unsigned int limit
9869 276 : = constant_lower_bound (GET_MODE_SIZE (inner_mode));
9870 14604 : for (unsigned int i = 0; i < limit; ++i)
9871 : {
9872 14328 : unsigned int elt = i / GET_MODE_SIZE (int_mode);
9873 14328 : rtx expected = NULL_RTX;
9874 14328 : if (elt >= first_valid)
9875 : {
9876 14328 : unsigned int byte_shift = i % GET_MODE_SIZE (int_mode);
9877 14328 : if (BYTES_BIG_ENDIAN)
9878 : byte_shift = GET_MODE_SIZE (int_mode) - byte_shift - 1;
9879 14328 : rtx_mode_t vec_elt (CONST_VECTOR_ELT (x, elt), int_mode);
9880 14328 : wide_int shifted_elt
9881 14328 : = wi::lrshift (vec_elt, byte_shift * BITS_PER_UNIT);
9882 14328 : expected = immed_wide_int_const (shifted_elt, QImode);
9883 14328 : }
9884 28656 : poly_uint64 byte = elt_bias * GET_MODE_SIZE (int_mode) + i;
9885 14328 : ASSERT_RTX_EQ (expected,
9886 : simplify_subreg (QImode, x, inner_mode, byte));
9887 : }
9888 : }
9889 276 : }
9890 :
9891 : /* Test constant subregs of integer vector mode INNER_MODE, using 1
9892 : element per pattern. */
9893 :
9894 : static void
9895 92 : test_vector_subregs_repeating (machine_mode inner_mode)
9896 : {
9897 184 : poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
9898 92 : unsigned int min_nunits = constant_lower_bound (nunits);
9899 92 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9900 92 : unsigned int count = gcd (min_nunits, 8);
9901 :
9902 92 : rtx_vector_builder builder (inner_mode, count, 1);
9903 776 : for (unsigned int i = 0; i < count; ++i)
9904 592 : builder.quick_push (gen_int_mode (8 - i, int_mode));
9905 92 : rtx x = builder.build ();
9906 :
9907 92 : test_vector_subregs_modes (x);
9908 92 : if (!nunits.is_constant ())
9909 : test_vector_subregs_modes (x, nunits - min_nunits);
9910 92 : }
9911 :
9912 : /* Test constant subregs of integer vector mode INNER_MODE, using 2
9913 : elements per pattern. */
9914 :
9915 : static void
9916 92 : test_vector_subregs_fore_back (machine_mode inner_mode)
9917 : {
9918 184 : poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
9919 92 : unsigned int min_nunits = constant_lower_bound (nunits);
9920 92 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9921 92 : unsigned int count = gcd (min_nunits, 4);
9922 :
9923 92 : rtx_vector_builder builder (inner_mode, count, 2);
9924 536 : for (unsigned int i = 0; i < count; ++i)
9925 352 : builder.quick_push (gen_int_mode (i, int_mode));
9926 444 : for (unsigned int i = 0; i < count; ++i)
9927 352 : builder.quick_push (gen_int_mode (-1 - (int) i, int_mode));
9928 92 : rtx x = builder.build ();
9929 :
9930 92 : test_vector_subregs_modes (x);
9931 92 : if (!nunits.is_constant ())
9932 : test_vector_subregs_modes (x, nunits - min_nunits, count);
9933 92 : }
9934 :
9935 : /* Test constant subregs of integer vector mode INNER_MODE, using 3
9936 : elements per pattern. */
9937 :
9938 : static void
9939 92 : test_vector_subregs_stepped (machine_mode inner_mode)
9940 : {
9941 : /* Build { 0, 1, 2, 3, ... }. */
9942 92 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9943 92 : rtx_vector_builder builder (inner_mode, 1, 3);
9944 460 : for (unsigned int i = 0; i < 3; ++i)
9945 276 : builder.quick_push (gen_int_mode (i, int_mode));
9946 92 : rtx x = builder.build ();
9947 :
9948 92 : test_vector_subregs_modes (x);
9949 92 : }
9950 :
9951 : /* Test constant subregs of integer vector mode INNER_MODE. */
9952 :
9953 : static void
9954 92 : test_vector_subregs (machine_mode inner_mode)
9955 : {
9956 92 : test_vector_subregs_repeating (inner_mode);
9957 92 : test_vector_subregs_fore_back (inner_mode);
9958 92 : test_vector_subregs_stepped (inner_mode);
9959 92 : }
9960 :
9961 : /* Verify some simplifications involving vectors. */
9962 :
9963 : static void
9964 4 : test_vector_ops ()
9965 : {
9966 500 : for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
9967 : {
9968 496 : machine_mode mode = (machine_mode) i;
9969 496 : if (VECTOR_MODE_P (mode))
9970 : {
9971 448 : rtx scalar_reg = make_test_reg (GET_MODE_INNER (mode));
9972 224 : test_vector_ops_duplicate (mode, scalar_reg);
9973 224 : rtx vector_reg = make_test_reg (mode);
9974 224 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
9975 348 : && maybe_gt (GET_MODE_NUNITS (mode), 2))
9976 : {
9977 92 : test_vector_ops_series (mode, scalar_reg);
9978 92 : test_vector_subregs (mode);
9979 92 : test_vector_rotate (vector_reg);
9980 : }
9981 224 : test_vec_merge (mode);
9982 : }
9983 : }
9984 4 : }
9985 :
9986 : template<unsigned int N>
9987 : struct simplify_const_poly_int_tests
9988 : {
9989 : static void run ();
9990 : };
9991 :
9992 : template<>
9993 : struct simplify_const_poly_int_tests<1>
9994 : {
9995 : static void run () {}
9996 : };
9997 :
9998 : /* Test various CONST_POLY_INT properties. */
9999 :
10000 : template<unsigned int N>
10001 : void
10002 : simplify_const_poly_int_tests<N>::run ()
10003 : {
10004 : using poly_int64 = poly_int<N, HOST_WIDE_INT>;
10005 : rtx x1 = gen_int_mode (poly_int64 (1, 1), QImode);
10006 : rtx x2 = gen_int_mode (poly_int64 (-80, 127), QImode);
10007 : rtx x3 = gen_int_mode (poly_int64 (-79, -128), QImode);
10008 : rtx x4 = gen_int_mode (poly_int64 (5, 4), QImode);
10009 : rtx x5 = gen_int_mode (poly_int64 (30, 24), QImode);
10010 : rtx x6 = gen_int_mode (poly_int64 (20, 16), QImode);
10011 : rtx x7 = gen_int_mode (poly_int64 (7, 4), QImode);
10012 : rtx x8 = gen_int_mode (poly_int64 (30, 24), HImode);
10013 : rtx x9 = gen_int_mode (poly_int64 (-30, -24), HImode);
10014 : rtx x10 = gen_int_mode (poly_int64 (-31, -24), HImode);
10015 : rtx two = GEN_INT (2);
10016 : rtx six = GEN_INT (6);
10017 : poly_uint64 offset = subreg_lowpart_offset (QImode, HImode);
10018 :
10019 : /* These tests only try limited operation combinations. Fuller arithmetic
10020 : testing is done directly on poly_ints. */
10021 : ASSERT_EQ (simplify_unary_operation (NEG, HImode, x8, HImode), x9);
10022 : ASSERT_EQ (simplify_unary_operation (NOT, HImode, x8, HImode), x10);
10023 : ASSERT_EQ (simplify_unary_operation (TRUNCATE, QImode, x8, HImode), x5);
10024 : ASSERT_EQ (simplify_binary_operation (PLUS, QImode, x1, x2), x3);
10025 : ASSERT_EQ (simplify_binary_operation (MINUS, QImode, x3, x1), x2);
10026 : ASSERT_EQ (simplify_binary_operation (MULT, QImode, x4, six), x5);
10027 : ASSERT_EQ (simplify_binary_operation (MULT, QImode, six, x4), x5);
10028 : ASSERT_EQ (simplify_binary_operation (ASHIFT, QImode, x4, two), x6);
10029 : ASSERT_EQ (simplify_binary_operation (IOR, QImode, x4, two), x7);
10030 : ASSERT_EQ (simplify_subreg (HImode, x5, QImode, 0), x8);
10031 : ASSERT_EQ (simplify_subreg (QImode, x8, HImode, offset), x5);
10032 : }
10033 :
10034 : /* Run all of the selftests within this file. */
10035 :
10036 : void
10037 4 : simplify_rtx_cc_tests ()
10038 : {
10039 4 : test_scalar_ops ();
10040 4 : test_vector_ops ();
10041 4 : simplify_const_poly_int_tests<NUM_POLY_INT_COEFFS>::run ();
10042 4 : }
10043 :
10044 : } // namespace selftest
10045 :
10046 : #endif /* CHECKING_P */
|