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 8860490 : neg_poly_int_rtx (machine_mode mode, const_rtx i)
56 : {
57 8860490 : 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 6175401 : mode_signbit_p (machine_mode mode, const_rtx x)
65 : {
66 6175401 : unsigned HOST_WIDE_INT val;
67 6175401 : unsigned int width;
68 6175401 : scalar_int_mode int_mode;
69 :
70 6175401 : if (!is_int_mode (mode, &int_mode))
71 : return false;
72 :
73 6175393 : width = GET_MODE_PRECISION (int_mode);
74 6175393 : if (width == 0)
75 : return false;
76 :
77 6175393 : if (width <= HOST_BITS_PER_WIDE_INT
78 6173863 : && CONST_INT_P (x))
79 6024888 : val = INTVAL (x);
80 : #if TARGET_SUPPORTS_WIDE_INT
81 150505 : else if (CONST_WIDE_INT_P (x))
82 : {
83 474 : unsigned int i;
84 474 : unsigned int elts = CONST_WIDE_INT_NUNITS (x);
85 474 : if (elts != (width + HOST_BITS_PER_WIDE_INT - 1) / HOST_BITS_PER_WIDE_INT)
86 : return false;
87 888 : for (i = 0; i < elts - 1; i++)
88 474 : if (CONST_WIDE_INT_ELT (x, i) != 0)
89 : return false;
90 414 : val = CONST_WIDE_INT_ELT (x, elts - 1);
91 414 : width %= HOST_BITS_PER_WIDE_INT;
92 414 : if (width == 0)
93 : width = HOST_BITS_PER_WIDE_INT;
94 : }
95 : #else
96 : else if (width <= HOST_BITS_PER_DOUBLE_INT
97 : && CONST_DOUBLE_AS_INT_P (x)
98 : && CONST_DOUBLE_LOW (x) == 0)
99 : {
100 : val = CONST_DOUBLE_HIGH (x);
101 : width -= HOST_BITS_PER_WIDE_INT;
102 : }
103 : #endif
104 : else
105 : /* X is not an integer constant. */
106 : return false;
107 :
108 6024888 : if (width < HOST_BITS_PER_WIDE_INT)
109 5459701 : val &= (HOST_WIDE_INT_1U << width) - 1;
110 6025302 : 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 3535489 : val_signbit_p (machine_mode mode, unsigned HOST_WIDE_INT val)
119 : {
120 3535489 : unsigned int width;
121 3535489 : scalar_int_mode int_mode;
122 :
123 3535489 : if (!is_int_mode (mode, &int_mode))
124 : return false;
125 :
126 3535453 : width = GET_MODE_PRECISION (int_mode);
127 3535453 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
128 : return false;
129 :
130 3530825 : val &= GET_MODE_MASK (int_mode);
131 3530825 : 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 2623018 : val_signbit_known_set_p (machine_mode mode, unsigned HOST_WIDE_INT val)
138 : {
139 2623018 : unsigned int width;
140 :
141 2623018 : scalar_int_mode int_mode;
142 2623018 : if (!is_int_mode (mode, &int_mode))
143 : return false;
144 :
145 2589665 : width = GET_MODE_PRECISION (int_mode);
146 2589665 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
147 : return false;
148 :
149 2589665 : val &= HOST_WIDE_INT_1U << (width - 1);
150 2589665 : 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 7469424 : val_signbit_known_clear_p (machine_mode mode, unsigned HOST_WIDE_INT val)
157 : {
158 7469424 : unsigned int width;
159 :
160 7469424 : scalar_int_mode int_mode;
161 7469424 : if (!is_int_mode (mode, &int_mode))
162 : return false;
163 :
164 7157787 : width = GET_MODE_PRECISION (int_mode);
165 7157787 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
166 : return false;
167 :
168 7047061 : val &= HOST_WIDE_INT_1U << (width - 1);
169 7047061 : 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 113775234 : simplify_context::simplify_gen_binary (rtx_code code, machine_mode mode,
177 : rtx op0, rtx op1)
178 : {
179 113775234 : rtx tem;
180 :
181 : /* If this simplifies, do it. */
182 113775234 : tem = simplify_binary_operation (code, mode, op0, op1);
183 113775234 : if (tem)
184 : return tem;
185 :
186 : /* Put complex operands first and constants second if commutative. */
187 71711598 : if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
188 71711598 : && swap_commutative_operands_p (op0, op1))
189 : std::swap (op0, op1);
190 :
191 71711598 : 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 2756722339 : avoid_constant_pool_reference (rtx x)
198 : {
199 2756722339 : rtx c, tmp, addr;
200 2756722339 : machine_mode cmode;
201 2756722339 : poly_int64 offset = 0;
202 :
203 2756722339 : switch (GET_CODE (x))
204 : {
205 261038583 : case MEM:
206 261038583 : break;
207 :
208 915066 : case FLOAT_EXTEND:
209 : /* Handle float extensions of constant pool references. */
210 915066 : tmp = XEXP (x, 0);
211 915066 : c = avoid_constant_pool_reference (tmp);
212 915066 : if (c != tmp && CONST_DOUBLE_AS_FLOAT_P (c))
213 122393 : return const_double_from_real_value (*CONST_DOUBLE_REAL_VALUE (c),
214 122393 : GET_MODE (x));
215 : return x;
216 :
217 : default:
218 : return x;
219 : }
220 :
221 261038583 : if (GET_MODE (x) == BLKmode)
222 : return x;
223 :
224 257005809 : addr = XEXP (x, 0);
225 :
226 : /* Call target hook to avoid the effects of -fpic etc.... */
227 257005809 : addr = targetm.delegitimize_address (addr);
228 :
229 : /* Split the address into a base and integer offset. */
230 257005809 : addr = strip_offset (addr, &offset);
231 :
232 257005809 : 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 257005809 : if (GET_CODE (addr) == SYMBOL_REF
238 257005809 : && CONSTANT_POOL_ADDRESS_P (addr))
239 : {
240 5336466 : c = get_pool_constant (addr);
241 5336466 : 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 5336466 : if (known_eq (offset, 0) && cmode == GET_MODE (x))
247 : return c;
248 23210 : else if (known_in_range_p (offset, 0, GET_MODE_SIZE (cmode)))
249 : {
250 11605 : rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset);
251 11605 : if (tem && CONSTANT_P (tem))
252 : return tem;
253 : }
254 : }
255 :
256 : return x;
257 : }
258 :
259 : /* Simplify a MEM based on its attributes. This is the default
260 : delegitimize_address target hook, and it's recommended that every
261 : overrider call it. */
262 :
263 : rtx
264 3520317191 : 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 3520317191 : if (MEM_P (x)
269 62135415 : && MEM_EXPR (x)
270 3558488996 : && MEM_OFFSET_KNOWN_P (x))
271 : {
272 35269944 : tree decl = MEM_EXPR (x);
273 35269944 : machine_mode mode = GET_MODE (x);
274 35269944 : poly_int64 offset = 0;
275 :
276 35269944 : switch (TREE_CODE (decl))
277 : {
278 : default:
279 : decl = NULL;
280 : break;
281 :
282 : case VAR_DECL:
283 : break;
284 :
285 10159230 : case ARRAY_REF:
286 10159230 : case ARRAY_RANGE_REF:
287 10159230 : case COMPONENT_REF:
288 10159230 : case BIT_FIELD_REF:
289 10159230 : case REALPART_EXPR:
290 10159230 : case IMAGPART_EXPR:
291 10159230 : case VIEW_CONVERT_EXPR:
292 10159230 : {
293 10159230 : poly_int64 bitsize, bitpos, bytepos, toffset_val = 0;
294 10159230 : tree toffset;
295 10159230 : int unsignedp, reversep, volatilep = 0;
296 :
297 10159230 : decl
298 10159230 : = get_inner_reference (decl, &bitsize, &bitpos, &toffset, &mode,
299 : &unsignedp, &reversep, &volatilep);
300 20318460 : if (maybe_ne (bitsize, GET_MODE_BITSIZE (mode))
301 10445060 : || !multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
302 19881043 : || (toffset && !poly_int_tree_p (toffset, &toffset_val)))
303 : decl = NULL;
304 : else
305 9435983 : offset += bytepos + toffset_val;
306 10159230 : break;
307 : }
308 : }
309 :
310 723247 : if (decl
311 20787872 : && mode == GET_MODE (x)
312 20516772 : && VAR_P (decl)
313 13261544 : && (TREE_STATIC (decl)
314 12029941 : || DECL_THREAD_LOCAL_P (decl))
315 1267707 : && DECL_RTL_SET_P (decl)
316 10703190 : && MEM_P (DECL_RTL (decl)))
317 : {
318 1267207 : rtx newx;
319 :
320 1267207 : offset += MEM_OFFSET (x);
321 :
322 1267207 : newx = DECL_RTL (decl);
323 :
324 1267207 : if (MEM_P (newx))
325 : {
326 1267207 : rtx n = XEXP (newx, 0), o = XEXP (x, 0);
327 1267207 : 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 1267207 : n = strip_offset (n, &n_offset);
336 1267207 : o = strip_offset (o, &o_offset);
337 2506739 : if (!(known_eq (o_offset, n_offset + offset)
338 1239532 : && rtx_equal_p (o, n)))
339 211559 : 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 3520317191 : 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 5161116 : simplify_context::simplify_gen_unary (rtx_code code, machine_mode mode, rtx op,
355 : machine_mode op_mode)
356 : {
357 5161116 : rtx tem;
358 :
359 : /* If this simplifies, use it. */
360 5161116 : if ((tem = simplify_unary_operation (code, mode, op, op_mode)) != 0)
361 : return tem;
362 :
363 1976301 : return gen_rtx_fmt_e (code, mode, op);
364 : }
365 :
366 : /* Likewise for ternary operations. */
367 :
368 : rtx
369 2224695 : 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 2224695 : rtx tem;
374 :
375 : /* If this simplifies, use it. */
376 2224695 : if ((tem = simplify_ternary_operation (code, mode, op0_mode,
377 : op0, op1, op2)) != 0)
378 : return tem;
379 :
380 1979667 : 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 21667679 : simplify_context::simplify_gen_relational (rtx_code code, machine_mode mode,
388 : machine_mode cmp_mode,
389 : rtx op0, rtx op1)
390 : {
391 21667679 : rtx tem;
392 :
393 21667679 : if ((tem = simplify_relational_operation (code, mode, cmp_mode,
394 : op0, op1)) != 0)
395 : return tem;
396 :
397 19253966 : 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 485086848 : simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
407 : rtx (*fn) (rtx, const_rtx, void *), void *data)
408 : {
409 485086848 : enum rtx_code code = GET_CODE (x);
410 485086848 : machine_mode mode = GET_MODE (x);
411 485086848 : machine_mode op_mode;
412 485086848 : const char *fmt;
413 485086848 : rtx op0, op1, op2, newx, op;
414 485086848 : rtvec vec, newvec;
415 485086848 : int i, j;
416 :
417 485086848 : if (UNLIKELY (fn != NULL))
418 : {
419 421604213 : newx = fn (x, old_rtx, data);
420 421604213 : if (newx)
421 : return newx;
422 : }
423 63482635 : else if (rtx_equal_p (x, old_rtx))
424 5205360 : return copy_rtx ((rtx) data);
425 :
426 381406635 : switch (GET_RTX_CLASS (code))
427 : {
428 1981774 : case RTX_UNARY:
429 1981774 : op0 = XEXP (x, 0);
430 1981774 : op_mode = GET_MODE (op0);
431 1981774 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
432 1981774 : if (op0 == XEXP (x, 0))
433 : return x;
434 648397 : return simplify_gen_unary (code, mode, op0, op_mode);
435 :
436 74806132 : case RTX_BIN_ARITH:
437 74806132 : case RTX_COMM_ARITH:
438 74806132 : op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
439 74806132 : op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
440 74806132 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
441 : return x;
442 22952923 : return simplify_gen_binary (code, mode, op0, op1);
443 :
444 9826488 : case RTX_COMPARE:
445 9826488 : case RTX_COMM_COMPARE:
446 9826488 : op0 = XEXP (x, 0);
447 9826488 : op1 = XEXP (x, 1);
448 9826488 : op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
449 9826488 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
450 9826488 : op1 = simplify_replace_fn_rtx (op1, old_rtx, fn, data);
451 9826488 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
452 : return x;
453 2353818 : return simplify_gen_relational (code, mode, op_mode, op0, op1);
454 :
455 5743402 : case RTX_TERNARY:
456 5743402 : case RTX_BITFIELD_OPS:
457 5743402 : op0 = XEXP (x, 0);
458 5743402 : op_mode = GET_MODE (op0);
459 5743402 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
460 5743402 : op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
461 5743402 : op2 = simplify_replace_fn_rtx (XEXP (x, 2), old_rtx, fn, data);
462 5743402 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2))
463 : return x;
464 1652571 : if (op_mode == VOIDmode)
465 1631823 : op_mode = GET_MODE (op0);
466 1652571 : return simplify_gen_ternary (code, mode, op_mode, op0, op1, op2);
467 :
468 84184736 : case RTX_EXTRA:
469 84184736 : if (code == SUBREG)
470 : {
471 645171 : op0 = simplify_replace_fn_rtx (SUBREG_REG (x), old_rtx, fn, data);
472 645171 : if (op0 == SUBREG_REG (x))
473 : return x;
474 136768 : op0 = simplify_gen_subreg (GET_MODE (x), op0,
475 68384 : GET_MODE (SUBREG_REG (x)),
476 68384 : SUBREG_BYTE (x));
477 68384 : return op0 ? op0 : x;
478 : }
479 : break;
480 :
481 61502310 : case RTX_OBJ:
482 61502310 : if (code == MEM)
483 : {
484 10904889 : op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
485 10904889 : if (op0 == XEXP (x, 0))
486 : return x;
487 159849 : return replace_equiv_address_nv (x, op0);
488 : }
489 50597421 : 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 277498779 : newx = x;
515 277498779 : fmt = GET_RTX_FORMAT (code);
516 599132440 : for (i = 0; fmt[i]; i++)
517 321633661 : switch (fmt[i])
518 : {
519 3045513 : case 'E':
520 3045513 : vec = XVEC (x, i);
521 3045513 : newvec = XVEC (newx, i);
522 12527015 : for (j = 0; j < GET_NUM_ELEM (vec); j++)
523 : {
524 9481502 : op = simplify_replace_fn_rtx (RTVEC_ELT (vec, j),
525 : old_rtx, fn, data);
526 9481502 : if (op != RTVEC_ELT (vec, j))
527 : {
528 342560 : if (newvec == vec)
529 : {
530 331983 : newvec = shallow_copy_rtvec (vec);
531 331983 : if (x == newx)
532 331983 : newx = shallow_copy_rtx (x);
533 331983 : XVEC (newx, i) = newvec;
534 : }
535 342560 : RTVEC_ELT (newvec, j) = op;
536 : }
537 : }
538 : break;
539 :
540 76282573 : case 'e':
541 76282573 : if (XEXP (x, i))
542 : {
543 76282573 : op = simplify_replace_fn_rtx (XEXP (x, i), old_rtx, fn, data);
544 76282573 : if (op != XEXP (x, i))
545 : {
546 4295578 : if (x == newx)
547 4292312 : newx = shallow_copy_rtx (x);
548 4295578 : 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 13060545 : simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx)
561 : {
562 13060545 : 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 17684715 : simplify_context::simplify_truncation (machine_mode mode, rtx op,
614 : machine_mode op_mode)
615 : {
616 17684715 : unsigned int precision = GET_MODE_UNIT_PRECISION (mode);
617 17684715 : unsigned int op_precision = GET_MODE_UNIT_PRECISION (op_mode);
618 17684715 : scalar_int_mode int_mode, int_op_mode, subreg_mode;
619 :
620 17684715 : gcc_assert (precision <= op_precision);
621 :
622 : /* Optimize truncations of zero and sign extended values. */
623 17684715 : if (GET_CODE (op) == ZERO_EXTEND
624 17684715 : || 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 270202 : machine_mode origmode = GET_MODE (XEXP (op, 0));
633 270202 : if (mode == origmode)
634 : return XEXP (op, 0);
635 20546 : else if (precision <= GET_MODE_UNIT_PRECISION (origmode))
636 7495 : return simplify_gen_unary (TRUNCATE, mode,
637 7495 : XEXP (op, 0), origmode);
638 : else
639 2778 : return simplify_gen_unary (GET_CODE (op), mode,
640 2778 : 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 17414513 : if (1
647 : && (!WORD_REGISTER_OPERATIONS || precision >= BITS_PER_WORD)
648 : && (GET_CODE (op) == PLUS
649 : || GET_CODE (op) == MINUS
650 17414513 : || GET_CODE (op) == MULT))
651 : {
652 741121 : rtx op0 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0), op_mode);
653 741121 : if (op0)
654 : {
655 741121 : rtx op1 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 1), op_mode);
656 741121 : if (op1)
657 741121 : 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 16673392 : if ((GET_CODE (op) == LSHIFTRT
665 16673392 : || 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 1575785 : && 2 * precision <= op_precision
671 1575785 : && CONST_INT_P (XEXP (op, 1))
672 1480039 : && 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 16673368 : if ((GET_CODE (op) == LSHIFTRT
682 : || GET_CODE (op) == ASHIFTRT)
683 1575761 : && CONST_INT_P (XEXP (op, 1))
684 1480015 : && GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
685 771 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
686 771 : && UINTVAL (XEXP (op, 1)) < precision)
687 761 : return simplify_gen_binary (LSHIFTRT, mode,
688 761 : 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 16672607 : if (GET_CODE (op) == ASHIFT
694 443561 : && CONST_INT_P (XEXP (op, 1))
695 383712 : && (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
696 383712 : || GET_CODE (XEXP (op, 0)) == SIGN_EXTEND)
697 591 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
698 578 : && UINTVAL (XEXP (op, 1)) < precision)
699 570 : return simplify_gen_binary (ASHIFT, mode,
700 570 : 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 16672037 : if (GET_CODE (op) == AND
706 645612 : && (GET_CODE (XEXP (op, 0)) == LSHIFTRT
707 645612 : || GET_CODE (XEXP (op, 0)) == ASHIFTRT)
708 31020 : && CONST_INT_P (XEXP (XEXP (op, 0), 1))
709 30908 : && CONST_INT_P (XEXP (op, 1)))
710 : {
711 30908 : rtx op0 = (XEXP (XEXP (op, 0), 0));
712 30908 : rtx shift_op = XEXP (XEXP (op, 0), 1);
713 30908 : rtx mask_op = XEXP (op, 1);
714 30908 : unsigned HOST_WIDE_INT shift = UINTVAL (shift_op);
715 30908 : unsigned HOST_WIDE_INT mask = UINTVAL (mask_op);
716 :
717 30908 : if (shift < precision
718 : /* If doing this transform works for an X with all bits set,
719 : it works for any X. */
720 17732 : && ((GET_MODE_MASK (mode) >> shift) & mask)
721 17732 : == ((GET_MODE_MASK (op_mode) >> shift) & mask)
722 3178 : && (op0 = simplify_gen_unary (TRUNCATE, mode, op0, op_mode))
723 34086 : && (op0 = simplify_gen_binary (LSHIFTRT, mode, op0, shift_op)))
724 : {
725 3178 : mask_op = GEN_INT (trunc_int_for_mode (mask, mode));
726 3178 : return simplify_gen_binary (AND, mode, op0, mask_op);
727 : }
728 : }
729 :
730 : /* Turn (truncate:M1 (*_extract:M2 (reg:M2) (len) (pos))) into
731 : (*_extract:M1 (truncate:M1 (reg:M2)) (len) (pos')) if possible without
732 : changing len. */
733 16668859 : if ((GET_CODE (op) == ZERO_EXTRACT || GET_CODE (op) == SIGN_EXTRACT)
734 365823 : && REG_P (XEXP (op, 0))
735 252504 : && GET_MODE (XEXP (op, 0)) == GET_MODE (op)
736 251594 : && CONST_INT_P (XEXP (op, 1))
737 251594 : && CONST_INT_P (XEXP (op, 2)))
738 : {
739 219949 : rtx op0 = XEXP (op, 0);
740 219949 : unsigned HOST_WIDE_INT len = UINTVAL (XEXP (op, 1));
741 219949 : unsigned HOST_WIDE_INT pos = UINTVAL (XEXP (op, 2));
742 219949 : if (BITS_BIG_ENDIAN && pos >= op_precision - precision)
743 : {
744 : op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
745 : if (op0)
746 : {
747 : pos -= op_precision - precision;
748 : return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
749 : XEXP (op, 1), GEN_INT (pos));
750 : }
751 : }
752 219949 : else if (!BITS_BIG_ENDIAN && precision >= len + pos)
753 : {
754 7645 : op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
755 7645 : if (op0)
756 7645 : return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
757 7645 : XEXP (op, 1), XEXP (op, 2));
758 : }
759 : }
760 :
761 : /* Recognize a word extraction from a multi-word subreg. */
762 16661214 : if ((GET_CODE (op) == LSHIFTRT
763 16661214 : || GET_CODE (op) == ASHIFTRT)
764 1575000 : && SCALAR_INT_MODE_P (mode)
765 1571856 : && SCALAR_INT_MODE_P (op_mode)
766 1706981 : && precision >= BITS_PER_WORD
767 60128 : && 2 * precision <= op_precision
768 60128 : && CONST_INT_P (XEXP (op, 1))
769 51957 : && (INTVAL (XEXP (op, 1)) & (precision - 1)) == 0
770 1867 : && UINTVAL (XEXP (op, 1)) < op_precision)
771 : {
772 1867 : poly_int64 byte = subreg_lowpart_offset (mode, op_mode);
773 1867 : int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
774 1867 : return simplify_gen_subreg (mode, XEXP (op, 0), op_mode,
775 : (WORDS_BIG_ENDIAN
776 1867 : ? byte - shifted_bytes
777 1867 : : 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 16659347 : if ((GET_CODE (op) == LSHIFTRT
784 : || GET_CODE (op) == ASHIFTRT)
785 1569989 : && is_a <scalar_int_mode> (mode, &int_mode)
786 18228112 : && is_a <scalar_int_mode> (op_mode, &int_op_mode)
787 1569989 : && MEM_P (XEXP (op, 0))
788 11424 : && CONST_INT_P (XEXP (op, 1))
789 21242 : && INTVAL (XEXP (op, 1)) % GET_MODE_BITSIZE (int_mode) == 0
790 1267 : && INTVAL (XEXP (op, 1)) > 0
791 2534 : && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (int_op_mode)
792 1267 : && ! mode_dependent_address_p (XEXP (XEXP (op, 0), 0),
793 1267 : MEM_ADDR_SPACE (XEXP (op, 0)))
794 1267 : && ! MEM_VOLATILE_P (XEXP (op, 0))
795 16659347 : && (GET_MODE_SIZE (int_mode) >= UNITS_PER_WORD
796 : || WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN))
797 : {
798 1224 : poly_int64 byte = subreg_lowpart_offset (int_mode, int_op_mode);
799 1224 : int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
800 1224 : return adjust_address_nv (XEXP (op, 0), int_mode,
801 : (WORDS_BIG_ENDIAN
802 : ? byte - shifted_bytes
803 : : byte + shifted_bytes));
804 : }
805 :
806 : /* (truncate:SI (OP:DI ({sign,zero}_extend:DI foo:SI))) is
807 : (OP:SI foo:SI) if OP is NEG or ABS. */
808 16658123 : if ((GET_CODE (op) == ABS
809 16658123 : || GET_CODE (op) == NEG)
810 21369 : && (GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
811 21369 : || GET_CODE (XEXP (op, 0)) == ZERO_EXTEND)
812 18 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
813 2 : return simplify_gen_unary (GET_CODE (op), mode,
814 2 : XEXP (XEXP (op, 0), 0), mode);
815 :
816 : /* Simplifications of (truncate:A (subreg:B X 0)). */
817 16658121 : if (GET_CODE (op) == SUBREG
818 16658298 : && is_a <scalar_int_mode> (mode, &int_mode)
819 27957 : && SCALAR_INT_MODE_P (op_mode)
820 27957 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &subreg_mode)
821 16685938 : && subreg_lowpart_p (op))
822 : {
823 : /* (truncate:A (subreg:B (truncate:C X) 0)) is (truncate:A X). */
824 27814 : 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 27814 : if (is_a <scalar_int_mode> (op_mode, &int_op_mode))
841 : {
842 27814 : unsigned int int_op_prec = GET_MODE_PRECISION (int_op_mode);
843 27814 : unsigned int subreg_prec = GET_MODE_PRECISION (subreg_mode);
844 27814 : if (int_op_prec > subreg_prec)
845 : {
846 1516 : if (int_mode == subreg_mode)
847 : return SUBREG_REG (op);
848 61 : if (GET_MODE_PRECISION (int_mode) < subreg_prec)
849 27 : return simplify_gen_unary (TRUNCATE, int_mode,
850 27 : SUBREG_REG (op), subreg_mode);
851 : }
852 : /* Simplification of (truncate:A (subreg:B X:C 0)) where
853 : A is narrower than B and B is narrower than C. */
854 26298 : else if (int_op_prec < subreg_prec
855 26298 : && GET_MODE_PRECISION (int_mode) < int_op_prec)
856 26298 : return simplify_gen_unary (TRUNCATE, int_mode,
857 26298 : SUBREG_REG (op), subreg_mode);
858 : }
859 : }
860 :
861 : /* (truncate:A (truncate:B X)) is (truncate:A X). */
862 16630341 : 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 16630341 : if (GET_CODE (op) == IOR
869 34837 : && SCALAR_INT_MODE_P (mode)
870 34837 : && SCALAR_INT_MODE_P (op_mode)
871 34837 : && CONST_INT_P (XEXP (op, 1))
872 16639107 : && 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 26882806 : simplify_context::simplify_unary_operation (rtx_code code, machine_mode mode,
883 : rtx op, machine_mode op_mode)
884 : {
885 26882806 : rtx trueop, tem;
886 :
887 26882806 : trueop = avoid_constant_pool_reference (op);
888 :
889 26882806 : tem = simplify_const_unary_operation (code, mode, trueop, op_mode);
890 26882806 : if (tem)
891 : return tem;
892 :
893 21896961 : return simplify_unary_operation_1 (code, mode, op);
894 : }
895 :
896 : /* Return true if FLOAT or UNSIGNED_FLOAT operation OP is known
897 : to be exact. */
898 :
899 : static bool
900 2694 : exact_int_to_float_conversion_p (const_rtx op)
901 : {
902 2694 : machine_mode op0_mode = GET_MODE (XEXP (op, 0));
903 : /* Constants can reach here with -frounding-math, if they do then
904 : the conversion isn't exact. */
905 2694 : if (op0_mode == VOIDmode)
906 : return false;
907 5386 : int out_bits = significand_size (GET_MODE_INNER (GET_MODE (op)));
908 2693 : int in_prec = GET_MODE_UNIT_PRECISION (op0_mode);
909 2693 : int in_bits = in_prec;
910 2693 : if (HWI_COMPUTABLE_MODE_P (op0_mode))
911 : {
912 2603 : unsigned HOST_WIDE_INT nonzero = nonzero_bits (XEXP (op, 0), op0_mode);
913 2603 : if (GET_CODE (op) == FLOAT)
914 2479 : in_bits -= num_sign_bit_copies (XEXP (op, 0), op0_mode);
915 124 : else if (GET_CODE (op) == UNSIGNED_FLOAT)
916 124 : in_bits = wi::min_precision (wi::uhwi (nonzero, in_prec), UNSIGNED);
917 : else
918 0 : gcc_unreachable ();
919 2603 : in_bits -= wi::ctz (wi::uhwi (nonzero, in_prec));
920 : }
921 2693 : return in_bits <= out_bits;
922 : }
923 :
924 : /* Perform some simplifications we can do even if the operands
925 : aren't constant. */
926 : rtx
927 21896961 : simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
928 : rtx op)
929 : {
930 21896961 : enum rtx_code reversed;
931 21896961 : rtx temp, elt, base, step;
932 21896961 : scalar_int_mode inner, int_mode, op_mode, op0_mode;
933 :
934 21896961 : switch (code)
935 : {
936 1777859 : case NOT:
937 : /* (not (not X)) == X. */
938 1777859 : if (GET_CODE (op) == NOT)
939 3334 : 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 1774525 : if (COMPARISON_P (op)
944 13660 : && (mode == BImode || STORE_FLAG_VALUE == -1)
945 1774525 : && ((reversed = reversed_comparison_code (op, NULL)) != UNKNOWN))
946 0 : return simplify_gen_relational (reversed, mode, VOIDmode,
947 0 : XEXP (op, 0), XEXP (op, 1));
948 :
949 : /* (not (plus X -1)) can become (neg X). */
950 1774525 : if (GET_CODE (op) == PLUS
951 287253 : && XEXP (op, 1) == constm1_rtx)
952 4386 : return simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
953 :
954 : /* Similarly, (not (neg X)) is (plus X -1). Only do this for
955 : modes that have CONSTM1_RTX, i.e. MODE_INT, MODE_PARTIAL_INT
956 : and MODE_VECTOR_INT. */
957 1770139 : if (GET_CODE (op) == NEG && CONSTM1_RTX (mode))
958 71086 : return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
959 71086 : CONSTM1_RTX (mode));
960 :
961 : /* (not (xor X C)) for C constant is (xor X D) with D = ~C. */
962 1699053 : if (GET_CODE (op) == XOR
963 15828 : && CONST_INT_P (XEXP (op, 1))
964 1702872 : && (temp = simplify_unary_operation (NOT, mode,
965 : XEXP (op, 1), mode)) != 0)
966 3819 : return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
967 :
968 : /* (not (plus X C)) for signbit C is (xor X D) with D = ~C. */
969 1695234 : if (GET_CODE (op) == PLUS
970 282867 : && CONST_INT_P (XEXP (op, 1))
971 165533 : && mode_signbit_p (mode, XEXP (op, 1))
972 1698929 : && (temp = simplify_unary_operation (NOT, mode,
973 : XEXP (op, 1), mode)) != 0)
974 3695 : return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
975 :
976 :
977 : /* (not (ashift 1 X)) is (rotate ~1 X). We used to do this for
978 : operands other than 1, but that is not valid. We could do a
979 : similar simplification for (not (lshiftrt C X)) where C is
980 : just the sign bit, but this doesn't seem common enough to
981 : bother with. */
982 1691539 : if (GET_CODE (op) == ASHIFT
983 36731 : && XEXP (op, 0) == const1_rtx)
984 : {
985 1043 : temp = simplify_gen_unary (NOT, mode, const1_rtx, mode);
986 1043 : return simplify_gen_binary (ROTATE, mode, temp, XEXP (op, 1));
987 : }
988 :
989 : /* (not (ashiftrt foo C)) where C is the number of bits in FOO
990 : minus 1 is (ge foo (const_int 0)) if STORE_FLAG_VALUE is -1,
991 : so we can perform the above simplification. */
992 1690496 : if (STORE_FLAG_VALUE == -1
993 : && is_a <scalar_int_mode> (mode, &int_mode)
994 : && GET_CODE (op) == ASHIFTRT
995 : && CONST_INT_P (XEXP (op, 1))
996 : && INTVAL (XEXP (op, 1)) == GET_MODE_PRECISION (int_mode) - 1)
997 : return simplify_gen_relational (GE, int_mode, VOIDmode,
998 : XEXP (op, 0), const0_rtx);
999 :
1000 :
1001 1690496 : if (partial_subreg_p (op)
1002 69896 : && subreg_lowpart_p (op)
1003 69584 : && GET_CODE (SUBREG_REG (op)) == ASHIFT
1004 89476 : && XEXP (SUBREG_REG (op), 0) == const1_rtx)
1005 : {
1006 163 : machine_mode inner_mode = GET_MODE (SUBREG_REG (op));
1007 163 : rtx x;
1008 :
1009 163 : x = gen_rtx_ROTATE (inner_mode,
1010 : simplify_gen_unary (NOT, inner_mode, const1_rtx,
1011 : inner_mode),
1012 : XEXP (SUBREG_REG (op), 1));
1013 163 : temp = rtl_hooks.gen_lowpart_no_emit (mode, x);
1014 163 : if (temp)
1015 : return temp;
1016 : }
1017 :
1018 : /* Apply De Morgan's laws to reduce number of patterns for machines
1019 : with negating logical insns (and-not, nand, etc.). If result has
1020 : only one NOT, put it first, since that is how the patterns are
1021 : coded. */
1022 1690333 : if (GET_CODE (op) == IOR || GET_CODE (op) == AND)
1023 : {
1024 12155 : rtx in1 = XEXP (op, 0), in2 = XEXP (op, 1);
1025 12155 : machine_mode op_mode;
1026 :
1027 12155 : op_mode = GET_MODE (in1);
1028 12155 : in1 = simplify_gen_unary (NOT, op_mode, in1, op_mode);
1029 :
1030 12155 : op_mode = GET_MODE (in2);
1031 12155 : if (op_mode == VOIDmode)
1032 5375 : op_mode = mode;
1033 12155 : in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode);
1034 :
1035 12155 : if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT)
1036 : std::swap (in1, in2);
1037 :
1038 24310 : return gen_rtx_fmt_ee (GET_CODE (op) == IOR ? AND : IOR,
1039 : mode, in1, in2);
1040 : }
1041 :
1042 : /* (not (bswap x)) -> (bswap (not x)). */
1043 1678178 : if (GET_CODE (op) == BSWAP || GET_CODE (op) == BITREVERSE)
1044 : {
1045 0 : rtx x = simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1046 0 : return simplify_gen_unary (GET_CODE (op), mode, x, mode);
1047 : }
1048 : break;
1049 :
1050 1683012 : case NEG:
1051 : /* (neg (neg X)) == X. */
1052 1683012 : if (GET_CODE (op) == NEG)
1053 6255 : return XEXP (op, 0);
1054 :
1055 : /* (neg (x ? (neg y) : y)) == !x ? (neg y) : y.
1056 : If comparison is not reversible use
1057 : x ? y : (neg y). */
1058 1676757 : if (GET_CODE (op) == IF_THEN_ELSE)
1059 : {
1060 3171 : rtx cond = XEXP (op, 0);
1061 3171 : rtx true_rtx = XEXP (op, 1);
1062 3171 : rtx false_rtx = XEXP (op, 2);
1063 :
1064 3171 : if ((GET_CODE (true_rtx) == NEG
1065 0 : && rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
1066 3171 : || (GET_CODE (false_rtx) == NEG
1067 0 : && rtx_equal_p (XEXP (false_rtx, 0), true_rtx)))
1068 : {
1069 0 : if (reversed_comparison_code (cond, NULL) != UNKNOWN)
1070 0 : temp = reversed_comparison (cond, mode);
1071 : else
1072 : {
1073 : temp = cond;
1074 : std::swap (true_rtx, false_rtx);
1075 : }
1076 0 : return simplify_gen_ternary (IF_THEN_ELSE, mode,
1077 0 : mode, temp, true_rtx, false_rtx);
1078 : }
1079 : }
1080 :
1081 : /* (neg (plus X 1)) can become (not X). */
1082 1676757 : if (GET_CODE (op) == PLUS
1083 138487 : && XEXP (op, 1) == const1_rtx)
1084 53552 : return simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1085 :
1086 : /* Similarly, (neg (not X)) is (plus X 1). */
1087 1623205 : if (GET_CODE (op) == NOT)
1088 519 : return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
1089 519 : CONST1_RTX (mode));
1090 :
1091 : /* (neg (minus X Y)) can become (minus Y X). This transformation
1092 : isn't safe for modes with signed zeros, since if X and Y are
1093 : both +0, (minus Y X) is the same as (minus X Y). If the
1094 : rounding mode is towards +infinity (or -infinity) then the two
1095 : expressions will be rounded differently. */
1096 1622686 : if (GET_CODE (op) == MINUS
1097 23807 : && !HONOR_SIGNED_ZEROS (mode)
1098 1645115 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1099 22429 : return simplify_gen_binary (MINUS, mode, XEXP (op, 1), XEXP (op, 0));
1100 :
1101 1600257 : if (GET_CODE (op) == PLUS
1102 84935 : && !HONOR_SIGNED_ZEROS (mode)
1103 1684768 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1104 : {
1105 : /* (neg (plus A C)) is simplified to (minus -C A). */
1106 84511 : if (CONST_SCALAR_INT_P (XEXP (op, 1))
1107 4818 : || CONST_DOUBLE_AS_FLOAT_P (XEXP (op, 1)))
1108 : {
1109 79693 : temp = simplify_unary_operation (NEG, mode, XEXP (op, 1), mode);
1110 79693 : if (temp)
1111 79693 : return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 0));
1112 : }
1113 :
1114 : /* (neg (plus A B)) is canonicalized to (minus (neg A) B). */
1115 4818 : temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
1116 4818 : return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 1));
1117 : }
1118 :
1119 : /* (neg (mult A B)) becomes (mult A (neg B)).
1120 : This works even for floating-point values. */
1121 1515746 : if (GET_CODE (op) == MULT
1122 1515746 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1123 : {
1124 20051 : temp = simplify_gen_unary (NEG, mode, XEXP (op, 1), mode);
1125 20051 : return simplify_gen_binary (MULT, mode, XEXP (op, 0), temp);
1126 : }
1127 :
1128 : /* NEG commutes with ASHIFT since it is multiplication. Only do
1129 : this if we can then eliminate the NEG (e.g., if the operand
1130 : is a constant). */
1131 1495695 : if (GET_CODE (op) == ASHIFT)
1132 : {
1133 53472 : temp = simplify_unary_operation (NEG, mode, XEXP (op, 0), mode);
1134 53472 : if (temp)
1135 12462 : return simplify_gen_binary (ASHIFT, mode, temp, XEXP (op, 1));
1136 : }
1137 :
1138 : /* (neg (ashiftrt X C)) can be replaced by (lshiftrt X C) when
1139 : C is equal to the width of MODE minus 1. */
1140 1483233 : if (GET_CODE (op) == ASHIFTRT
1141 27899 : && CONST_INT_P (XEXP (op, 1))
1142 1538935 : && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1143 692 : return simplify_gen_binary (LSHIFTRT, mode,
1144 692 : XEXP (op, 0), XEXP (op, 1));
1145 :
1146 : /* (neg (lshiftrt X C)) can be replaced by (ashiftrt X C) when
1147 : C is equal to the width of MODE minus 1. */
1148 1482541 : if (GET_CODE (op) == LSHIFTRT
1149 7748 : && CONST_INT_P (XEXP (op, 1))
1150 1497869 : && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1151 2350 : return simplify_gen_binary (ASHIFTRT, mode,
1152 2350 : XEXP (op, 0), XEXP (op, 1));
1153 :
1154 : /* (neg (xor A 1)) is (plus A -1) if A is known to be either 0 or 1. */
1155 1480191 : if (GET_CODE (op) == XOR
1156 10354 : && XEXP (op, 1) == const1_rtx
1157 1480303 : && nonzero_bits (XEXP (op, 0), mode) == 1)
1158 33 : return plus_constant (mode, XEXP (op, 0), -1);
1159 :
1160 : /* (neg (lt x 0)) is (ashiftrt X C) if STORE_FLAG_VALUE is 1. */
1161 : /* (neg (lt x 0)) is (lshiftrt X C) if STORE_FLAG_VALUE is -1. */
1162 1480158 : if (GET_CODE (op) == LT
1163 2533 : && XEXP (op, 1) == const0_rtx
1164 1481903 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op, 0)), &inner))
1165 : {
1166 359 : int_mode = as_a <scalar_int_mode> (mode);
1167 359 : int isize = GET_MODE_PRECISION (inner);
1168 359 : if (STORE_FLAG_VALUE == 1)
1169 : {
1170 359 : temp = simplify_gen_binary (ASHIFTRT, inner, XEXP (op, 0),
1171 : gen_int_shift_amount (inner,
1172 359 : isize - 1));
1173 359 : if (int_mode == inner)
1174 : return temp;
1175 194 : if (GET_MODE_PRECISION (int_mode) > isize)
1176 129 : return simplify_gen_unary (SIGN_EXTEND, int_mode, temp, inner);
1177 65 : return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1178 : }
1179 : else if (STORE_FLAG_VALUE == -1)
1180 : {
1181 : temp = simplify_gen_binary (LSHIFTRT, inner, XEXP (op, 0),
1182 : gen_int_shift_amount (inner,
1183 : isize - 1));
1184 : if (int_mode == inner)
1185 : return temp;
1186 : if (GET_MODE_PRECISION (int_mode) > isize)
1187 : return simplify_gen_unary (ZERO_EXTEND, int_mode, temp, inner);
1188 : return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1189 : }
1190 : }
1191 :
1192 1479799 : if (vec_series_p (op, &base, &step))
1193 : {
1194 : /* Only create a new series if we can simplify both parts. In other
1195 : cases this isn't really a simplification, and it's not necessarily
1196 : a win to replace a vector operation with a scalar operation. */
1197 276 : scalar_mode inner_mode = GET_MODE_INNER (mode);
1198 276 : base = simplify_unary_operation (NEG, inner_mode, base, inner_mode);
1199 276 : if (base)
1200 : {
1201 276 : step = simplify_unary_operation (NEG, inner_mode,
1202 : step, inner_mode);
1203 276 : if (step)
1204 276 : return gen_vec_series (mode, base, step);
1205 : }
1206 : }
1207 : break;
1208 :
1209 1226976 : case TRUNCATE:
1210 : /* Don't optimize (lshiftrt (mult ...)) as it would interfere
1211 : with the umulXi3_highpart patterns. */
1212 1226976 : if (GET_CODE (op) == LSHIFTRT
1213 18486 : && GET_CODE (XEXP (op, 0)) == MULT)
1214 : break;
1215 :
1216 1219726 : if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
1217 : {
1218 12 : if (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
1219 : {
1220 12 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1221 12 : if (temp)
1222 : return temp;
1223 : }
1224 : /* We can't handle truncation to a partial integer mode here
1225 : because we don't know the real bitsize of the partial
1226 : integer mode. */
1227 : break;
1228 : }
1229 :
1230 1219714 : if (GET_MODE (op) != VOIDmode)
1231 : {
1232 1219714 : temp = simplify_truncation (mode, op, GET_MODE (op));
1233 1219714 : if (temp)
1234 : return temp;
1235 : }
1236 :
1237 : /* If we know that the value is already truncated, we can
1238 : replace the TRUNCATE with a SUBREG. */
1239 1101585 : if (known_eq (GET_MODE_NUNITS (mode), 1)
1240 1101585 : && (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op))
1241 0 : || truncated_to_mode (mode, op)))
1242 : {
1243 1088922 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1244 1088922 : if (temp)
1245 : return temp;
1246 : }
1247 :
1248 : /* A truncate of a comparison can be replaced with a subreg if
1249 : STORE_FLAG_VALUE permits. This is like the previous test,
1250 : but it works even if the comparison is done in a mode larger
1251 : than HOST_BITS_PER_WIDE_INT. */
1252 12854 : if (HWI_COMPUTABLE_MODE_P (mode)
1253 191 : && COMPARISON_P (op)
1254 0 : && (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0
1255 12854 : && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
1256 : {
1257 0 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1258 0 : if (temp)
1259 : return temp;
1260 : }
1261 :
1262 : /* A truncate of a memory is just loading the low part of the memory
1263 : if we are not changing the meaning of the address. */
1264 12854 : if (GET_CODE (op) == MEM
1265 314 : && !VECTOR_MODE_P (mode)
1266 189 : && !MEM_VOLATILE_P (op)
1267 13037 : && !mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op)))
1268 : {
1269 183 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1270 183 : if (temp)
1271 : return temp;
1272 : }
1273 :
1274 : /* Check for useless truncation. */
1275 12854 : if (GET_MODE (op) == mode)
1276 : return op;
1277 : break;
1278 :
1279 172533 : case FLOAT_TRUNCATE:
1280 : /* Check for useless truncation. */
1281 172533 : if (GET_MODE (op) == mode)
1282 : return op;
1283 :
1284 172533 : if (DECIMAL_FLOAT_MODE_P (mode))
1285 : break;
1286 :
1287 : /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF. */
1288 172379 : if (GET_CODE (op) == FLOAT_EXTEND
1289 5 : && GET_MODE (XEXP (op, 0)) == mode)
1290 : return XEXP (op, 0);
1291 :
1292 : /* (float_truncate:SF (float_truncate:DF foo:XF))
1293 : = (float_truncate:SF foo:XF).
1294 : This may eliminate double rounding, so it is unsafe.
1295 :
1296 : (float_truncate:SF (float_extend:XF foo:DF))
1297 : = (float_truncate:SF foo:DF).
1298 :
1299 : (float_truncate:DF (float_extend:XF foo:SF))
1300 : = (float_extend:DF foo:SF). */
1301 172377 : if ((GET_CODE (op) == FLOAT_TRUNCATE
1302 145 : && flag_unsafe_math_optimizations)
1303 172373 : || GET_CODE (op) == FLOAT_EXTEND)
1304 14 : return simplify_gen_unary (GET_MODE_UNIT_SIZE (GET_MODE (XEXP (op, 0)))
1305 7 : > GET_MODE_UNIT_SIZE (mode)
1306 : ? FLOAT_TRUNCATE : FLOAT_EXTEND,
1307 : mode,
1308 14 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1309 :
1310 : /* (float_truncate (float x)) is (float x) */
1311 172370 : if ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1312 172370 : && (flag_unsafe_math_optimizations
1313 1413 : || exact_int_to_float_conversion_p (op)))
1314 1412 : return simplify_gen_unary (GET_CODE (op), mode,
1315 : XEXP (op, 0),
1316 1412 : GET_MODE (XEXP (op, 0)));
1317 :
1318 : /* (float_truncate:SF (OP:DF (float_extend:DF foo:sf))) is
1319 : (OP:SF foo:SF) if OP is NEG or ABS. */
1320 170958 : if ((GET_CODE (op) == ABS
1321 170958 : || GET_CODE (op) == NEG)
1322 209 : && GET_CODE (XEXP (op, 0)) == FLOAT_EXTEND
1323 28 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
1324 28 : return simplify_gen_unary (GET_CODE (op), mode,
1325 28 : XEXP (XEXP (op, 0), 0), mode);
1326 :
1327 : /* (float_truncate:SF (subreg:DF (float_truncate:SF X) 0))
1328 : is (float_truncate:SF x). */
1329 170930 : if (GET_CODE (op) == SUBREG
1330 317 : && subreg_lowpart_p (op)
1331 171244 : && GET_CODE (SUBREG_REG (op)) == FLOAT_TRUNCATE)
1332 : return SUBREG_REG (op);
1333 : break;
1334 :
1335 592676 : case FLOAT_EXTEND:
1336 : /* Check for useless extension. */
1337 592676 : if (GET_MODE (op) == mode)
1338 : return op;
1339 :
1340 592676 : if (DECIMAL_FLOAT_MODE_P (mode))
1341 : break;
1342 :
1343 : /* (float_extend (float_extend x)) is (float_extend x)
1344 :
1345 : (float_extend (float x)) is (float x) assuming that double
1346 : rounding can't happen.
1347 : */
1348 592573 : if (GET_CODE (op) == FLOAT_EXTEND
1349 592573 : || ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1350 1281 : && exact_int_to_float_conversion_p (op)))
1351 563 : return simplify_gen_unary (GET_CODE (op), mode,
1352 : XEXP (op, 0),
1353 563 : GET_MODE (XEXP (op, 0)));
1354 :
1355 : break;
1356 :
1357 266093 : case ABS:
1358 : /* (abs (neg <foo>)) -> (abs <foo>) */
1359 266093 : if (GET_CODE (op) == NEG)
1360 29 : return simplify_gen_unary (ABS, mode, XEXP (op, 0),
1361 29 : GET_MODE (XEXP (op, 0)));
1362 :
1363 : /* If the mode of the operand is VOIDmode (i.e. if it is ASM_OPERANDS),
1364 : do nothing. */
1365 266064 : if (GET_MODE (op) == VOIDmode)
1366 : break;
1367 :
1368 : /* If operand is something known to be positive, ignore the ABS. */
1369 266064 : if (val_signbit_known_clear_p (GET_MODE (op),
1370 : nonzero_bits (op, GET_MODE (op))))
1371 : return op;
1372 :
1373 : /* Using nonzero_bits doesn't (currently) work for modes wider than
1374 : HOST_WIDE_INT, so the following transformations help simplify
1375 : ABS for TImode and wider. */
1376 265846 : switch (GET_CODE (op))
1377 : {
1378 : case ABS:
1379 : case CLRSB:
1380 : case FFS:
1381 : case PARITY:
1382 : case POPCOUNT:
1383 : case SS_ABS:
1384 : return op;
1385 :
1386 0 : case LSHIFTRT:
1387 0 : if (CONST_INT_P (XEXP (op, 1))
1388 0 : && INTVAL (XEXP (op, 1)) > 0
1389 265846 : && is_a <scalar_int_mode> (mode, &int_mode)
1390 0 : && INTVAL (XEXP (op, 1)) < GET_MODE_PRECISION (int_mode))
1391 : return op;
1392 : break;
1393 :
1394 : default:
1395 : break;
1396 : }
1397 :
1398 : /* If operand is known to be only -1 or 0, convert ABS to NEG. */
1399 265846 : if (is_a <scalar_int_mode> (mode, &int_mode)
1400 35540 : && (num_sign_bit_copies (op, int_mode)
1401 35540 : == GET_MODE_PRECISION (int_mode)))
1402 74 : return gen_rtx_NEG (int_mode, op);
1403 :
1404 : break;
1405 :
1406 0 : case FFS:
1407 : /* (ffs (*_extend <X>)) = (*_extend (ffs <X>)). */
1408 0 : if (GET_CODE (op) == SIGN_EXTEND
1409 0 : || GET_CODE (op) == ZERO_EXTEND)
1410 : {
1411 0 : temp = simplify_gen_unary (FFS, GET_MODE (XEXP (op, 0)),
1412 0 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1413 0 : return simplify_gen_unary (GET_CODE (op), mode, temp,
1414 0 : GET_MODE (temp));
1415 : }
1416 : break;
1417 :
1418 3449 : case POPCOUNT:
1419 3449 : switch (GET_CODE (op))
1420 : {
1421 0 : case BSWAP:
1422 0 : case BITREVERSE:
1423 : /* (popcount (bswap <X>)) = (popcount <X>). */
1424 0 : return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1425 0 : GET_MODE (XEXP (op, 0)));
1426 :
1427 44 : case ZERO_EXTEND:
1428 : /* (popcount (zero_extend <X>)) = (zero_extend (popcount <X>)). */
1429 88 : temp = simplify_gen_unary (POPCOUNT, GET_MODE (XEXP (op, 0)),
1430 44 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1431 44 : return simplify_gen_unary (ZERO_EXTEND, mode, temp,
1432 44 : GET_MODE (temp));
1433 :
1434 0 : case ROTATE:
1435 0 : case ROTATERT:
1436 : /* Rotations don't affect popcount. */
1437 0 : if (!side_effects_p (XEXP (op, 1)))
1438 0 : return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1439 0 : GET_MODE (XEXP (op, 0)));
1440 : break;
1441 :
1442 : default:
1443 : break;
1444 : }
1445 : break;
1446 :
1447 0 : case PARITY:
1448 0 : switch (GET_CODE (op))
1449 : {
1450 0 : case NOT:
1451 0 : case BSWAP:
1452 0 : case BITREVERSE:
1453 0 : return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1454 0 : GET_MODE (XEXP (op, 0)));
1455 :
1456 0 : case ZERO_EXTEND:
1457 0 : case SIGN_EXTEND:
1458 0 : temp = simplify_gen_unary (PARITY, GET_MODE (XEXP (op, 0)),
1459 0 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1460 0 : return simplify_gen_unary (GET_CODE (op), mode, temp,
1461 0 : GET_MODE (temp));
1462 :
1463 0 : case ROTATE:
1464 0 : case ROTATERT:
1465 : /* Rotations don't affect parity. */
1466 0 : if (!side_effects_p (XEXP (op, 1)))
1467 0 : return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1468 0 : GET_MODE (XEXP (op, 0)));
1469 : break;
1470 :
1471 : case PARITY:
1472 : /* (parity (parity x)) -> parity (x). */
1473 : return op;
1474 :
1475 : default:
1476 : break;
1477 : }
1478 : break;
1479 :
1480 31169 : case BSWAP:
1481 : /* (bswap (bswap x)) -> x. */
1482 31169 : if (GET_CODE (op) == BSWAP)
1483 184 : return XEXP (op, 0);
1484 : break;
1485 :
1486 0 : case BITREVERSE:
1487 : /* (bitreverse (bitreverse x)) -> x. */
1488 0 : if (GET_CODE (op) == BITREVERSE)
1489 0 : return XEXP (op, 0);
1490 : break;
1491 :
1492 899094 : case FLOAT:
1493 : /* (float (sign_extend <X>)) = (float <X>). */
1494 899094 : if (GET_CODE (op) == SIGN_EXTEND)
1495 9352 : return simplify_gen_unary (FLOAT, mode, XEXP (op, 0),
1496 9352 : GET_MODE (XEXP (op, 0)));
1497 : break;
1498 :
1499 3006531 : case SIGN_EXTEND:
1500 : /* Check for useless extension. */
1501 3006531 : if (GET_MODE (op) == mode)
1502 : return op;
1503 :
1504 : /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
1505 : becomes just the MINUS if its mode is MODE. This allows
1506 : folding switch statements on machines using casesi (such as
1507 : the VAX). */
1508 3006491 : if (GET_CODE (op) == TRUNCATE
1509 62 : && GET_MODE (XEXP (op, 0)) == mode
1510 62 : && GET_CODE (XEXP (op, 0)) == MINUS
1511 0 : && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
1512 0 : && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
1513 : return XEXP (op, 0);
1514 :
1515 : /* Extending a widening multiplication should be canonicalized to
1516 : a wider widening multiplication. */
1517 3006491 : if (GET_CODE (op) == MULT)
1518 : {
1519 67113 : rtx lhs = XEXP (op, 0);
1520 67113 : rtx rhs = XEXP (op, 1);
1521 67113 : enum rtx_code lcode = GET_CODE (lhs);
1522 67113 : enum rtx_code rcode = GET_CODE (rhs);
1523 :
1524 : /* Widening multiplies usually extend both operands, but sometimes
1525 : they use a shift to extract a portion of a register. */
1526 67113 : if ((lcode == SIGN_EXTEND
1527 66964 : || (lcode == ASHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1528 881 : && (rcode == SIGN_EXTEND
1529 837 : || (rcode == ASHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1530 : {
1531 165 : machine_mode lmode = GET_MODE (lhs);
1532 165 : machine_mode rmode = GET_MODE (rhs);
1533 165 : int bits;
1534 :
1535 165 : if (lcode == ASHIFTRT)
1536 : /* Number of bits not shifted off the end. */
1537 125 : bits = (GET_MODE_UNIT_PRECISION (lmode)
1538 125 : - INTVAL (XEXP (lhs, 1)));
1539 : else /* lcode == SIGN_EXTEND */
1540 : /* Size of inner mode. */
1541 80 : bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1542 :
1543 165 : if (rcode == ASHIFTRT)
1544 121 : bits += (GET_MODE_UNIT_PRECISION (rmode)
1545 121 : - INTVAL (XEXP (rhs, 1)));
1546 : else /* rcode == SIGN_EXTEND */
1547 88 : bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1548 :
1549 : /* We can only widen multiplies if the result is mathematiclly
1550 : equivalent. I.e. if overflow was impossible. */
1551 330 : if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1552 108 : return simplify_gen_binary
1553 108 : (MULT, mode,
1554 : simplify_gen_unary (SIGN_EXTEND, mode, lhs, lmode),
1555 108 : simplify_gen_unary (SIGN_EXTEND, mode, rhs, rmode));
1556 : }
1557 : }
1558 :
1559 : /* Check for a sign extension of a subreg of a promoted
1560 : variable, where the promotion is sign-extended, and the
1561 : target mode is the same as the variable's promotion. */
1562 3006383 : if (GET_CODE (op) == SUBREG
1563 149337 : && SUBREG_PROMOTED_VAR_P (op)
1564 3012050 : && SUBREG_PROMOTED_SIGNED_P (op))
1565 : {
1566 0 : rtx subreg = SUBREG_REG (op);
1567 0 : machine_mode subreg_mode = GET_MODE (subreg);
1568 0 : if (!paradoxical_subreg_p (mode, subreg_mode))
1569 : {
1570 0 : temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
1571 0 : if (temp)
1572 : {
1573 : /* Preserve SUBREG_PROMOTED_VAR_P. */
1574 0 : if (partial_subreg_p (temp))
1575 : {
1576 0 : SUBREG_PROMOTED_VAR_P (temp) = 1;
1577 0 : SUBREG_PROMOTED_SET (temp, SRP_SIGNED);
1578 : }
1579 0 : return temp;
1580 : }
1581 : }
1582 : else
1583 : /* Sign-extending a sign-extended subreg. */
1584 0 : return simplify_gen_unary (SIGN_EXTEND, mode,
1585 0 : subreg, subreg_mode);
1586 : }
1587 :
1588 : /* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
1589 : (sign_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1590 3006383 : if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND)
1591 : {
1592 19908 : gcc_assert (GET_MODE_UNIT_PRECISION (mode)
1593 : > GET_MODE_UNIT_PRECISION (GET_MODE (op)));
1594 6636 : return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0),
1595 6636 : GET_MODE (XEXP (op, 0)));
1596 : }
1597 :
1598 : /* (sign_extend:M (ashiftrt:N (ashift <X> (const_int I)) (const_int I)))
1599 : is (sign_extend:M (subreg:O <X>)) if there is mode with
1600 : GET_MODE_BITSIZE (N) - I bits.
1601 : (sign_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1602 : is similarly (zero_extend:M (subreg:O <X>)). */
1603 2999747 : if ((GET_CODE (op) == ASHIFTRT || GET_CODE (op) == LSHIFTRT)
1604 89642 : && GET_CODE (XEXP (op, 0)) == ASHIFT
1605 3002241 : && is_a <scalar_int_mode> (mode, &int_mode)
1606 5151 : && CONST_INT_P (XEXP (op, 1))
1607 5151 : && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1608 3004774 : && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1609 5027 : GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1610 : {
1611 5027 : scalar_int_mode tmode;
1612 5027 : gcc_assert (GET_MODE_PRECISION (int_mode)
1613 : > GET_MODE_PRECISION (op_mode));
1614 5027 : if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1615 7397 : - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1616 : {
1617 2657 : rtx inner =
1618 2657 : rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1619 2657 : if (inner)
1620 2657 : return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
1621 : ? SIGN_EXTEND : ZERO_EXTEND,
1622 2657 : int_mode, inner, tmode);
1623 : }
1624 : }
1625 :
1626 : /* (sign_extend:M (lshiftrt:N <X> (const_int I))) is better as
1627 : (zero_extend:M (lshiftrt:N <X> (const_int I))) if I is not 0. */
1628 2997090 : if (GET_CODE (op) == LSHIFTRT
1629 183 : && CONST_INT_P (XEXP (op, 1))
1630 183 : && XEXP (op, 1) != const0_rtx)
1631 183 : return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1632 :
1633 : /* (sign_extend:M (truncate:N (lshiftrt:O <X> (const_int I)))) where
1634 : I is GET_MODE_PRECISION(O) - GET_MODE_PRECISION(N), simplifies to
1635 : (ashiftrt:M <X> (const_int I)) if modes M and O are the same, and
1636 : (truncate:M (ashiftrt:O <X> (const_int I))) if M is narrower than
1637 : O, and (sign_extend:M (ashiftrt:O <X> (const_int I))) if M is
1638 : wider than O. */
1639 2996907 : if (GET_CODE (op) == TRUNCATE
1640 62 : && GET_CODE (XEXP (op, 0)) == LSHIFTRT
1641 0 : && CONST_INT_P (XEXP (XEXP (op, 0), 1)))
1642 : {
1643 0 : scalar_int_mode m_mode, n_mode, o_mode;
1644 0 : rtx old_shift = XEXP (op, 0);
1645 0 : if (is_a <scalar_int_mode> (mode, &m_mode)
1646 0 : && is_a <scalar_int_mode> (GET_MODE (op), &n_mode)
1647 0 : && is_a <scalar_int_mode> (GET_MODE (old_shift), &o_mode)
1648 0 : && GET_MODE_PRECISION (o_mode) - GET_MODE_PRECISION (n_mode)
1649 0 : == INTVAL (XEXP (old_shift, 1)))
1650 : {
1651 0 : rtx new_shift = simplify_gen_binary (ASHIFTRT,
1652 : GET_MODE (old_shift),
1653 : XEXP (old_shift, 0),
1654 : XEXP (old_shift, 1));
1655 0 : if (GET_MODE_PRECISION (m_mode) > GET_MODE_PRECISION (o_mode))
1656 0 : return simplify_gen_unary (SIGN_EXTEND, mode, new_shift,
1657 0 : GET_MODE (new_shift));
1658 0 : if (mode != GET_MODE (new_shift))
1659 0 : return simplify_gen_unary (TRUNCATE, mode, new_shift,
1660 0 : GET_MODE (new_shift));
1661 : return new_shift;
1662 : }
1663 : }
1664 :
1665 : /* We can canonicalize SIGN_EXTEND (op) as ZERO_EXTEND (op) when
1666 : we know the sign bit of OP must be clear. */
1667 2996907 : if (val_signbit_known_clear_p (GET_MODE (op),
1668 2996907 : nonzero_bits (op, GET_MODE (op))))
1669 37643 : return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1670 :
1671 : /* (sign_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1672 2959264 : if (GET_CODE (op) == SUBREG
1673 149123 : && subreg_lowpart_p (op)
1674 149026 : && GET_MODE (SUBREG_REG (op)) == mode
1675 3088062 : && is_a <scalar_int_mode> (mode, &int_mode)
1676 135576 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1677 135576 : && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
1678 133769 : && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
1679 3093033 : && (nonzero_bits (SUBREG_REG (op), mode)
1680 133769 : & ~(GET_MODE_MASK (op_mode) >> 1)) == 0)
1681 6778 : return SUBREG_REG (op);
1682 :
1683 : #if defined(POINTERS_EXTEND_UNSIGNED)
1684 : /* As we do not know which address space the pointer is referring to,
1685 : we can do this only if the target does not support different pointer
1686 : or address modes depending on the address space. */
1687 2952486 : if (target_default_pointer_address_modes_p ()
1688 : && ! POINTERS_EXTEND_UNSIGNED
1689 : && mode == Pmode && GET_MODE (op) == ptr_mode
1690 : && (CONSTANT_P (op)
1691 : || (GET_CODE (op) == SUBREG
1692 : && REG_P (SUBREG_REG (op))
1693 : && REG_POINTER (SUBREG_REG (op))
1694 : && GET_MODE (SUBREG_REG (op)) == Pmode))
1695 : && !targetm.have_ptr_extend ())
1696 : {
1697 : temp
1698 : = convert_memory_address_addr_space_1 (Pmode, op,
1699 : ADDR_SPACE_GENERIC, false,
1700 : true);
1701 : if (temp)
1702 : return temp;
1703 : }
1704 : #endif
1705 : break;
1706 :
1707 11362938 : case ZERO_EXTEND:
1708 : /* Check for useless extension. */
1709 11362938 : if (GET_MODE (op) == mode)
1710 : return op;
1711 :
1712 : /* (zero_extend:SI (and:QI X (const))) -> (and:SI (lowpart:SI X) const)
1713 : where const does not sign bit set. */
1714 11362898 : if (GET_CODE (op) == AND
1715 112182 : && CONST_INT_P (XEXP (op, 1))
1716 89506 : && INTVAL (XEXP (op, 1)) > 0)
1717 : {
1718 84723 : rtx tem = rtl_hooks.gen_lowpart_no_emit (mode, XEXP (op, 0));
1719 84723 : if (tem)
1720 68593 : return simplify_gen_binary (AND, mode, tem, XEXP (op, 1));
1721 : }
1722 :
1723 : /* Check for a zero extension of a subreg of a promoted
1724 : variable, where the promotion is zero-extended, and the
1725 : target mode is the same as the variable's promotion. */
1726 11294305 : if (GET_CODE (op) == SUBREG
1727 1551109 : && SUBREG_PROMOTED_VAR_P (op)
1728 11294762 : && SUBREG_PROMOTED_UNSIGNED_P (op))
1729 : {
1730 457 : rtx subreg = SUBREG_REG (op);
1731 457 : machine_mode subreg_mode = GET_MODE (subreg);
1732 457 : if (!paradoxical_subreg_p (mode, subreg_mode))
1733 : {
1734 299 : temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
1735 299 : if (temp)
1736 : {
1737 : /* Preserve SUBREG_PROMOTED_VAR_P. */
1738 299 : if (partial_subreg_p (temp))
1739 : {
1740 129 : SUBREG_PROMOTED_VAR_P (temp) = 1;
1741 129 : SUBREG_PROMOTED_SET (temp, SRP_UNSIGNED);
1742 : }
1743 299 : return temp;
1744 : }
1745 : }
1746 : else
1747 : /* Zero-extending a zero-extended subreg. */
1748 158 : return simplify_gen_unary (ZERO_EXTEND, mode,
1749 158 : subreg, subreg_mode);
1750 : }
1751 :
1752 : /* Extending a widening multiplication should be canonicalized to
1753 : a wider widening multiplication. */
1754 11293848 : if (GET_CODE (op) == MULT)
1755 : {
1756 165441 : rtx lhs = XEXP (op, 0);
1757 165441 : rtx rhs = XEXP (op, 1);
1758 165441 : enum rtx_code lcode = GET_CODE (lhs);
1759 165441 : enum rtx_code rcode = GET_CODE (rhs);
1760 :
1761 : /* Widening multiplies usually extend both operands, but sometimes
1762 : they use a shift to extract a portion of a register. */
1763 165441 : if ((lcode == ZERO_EXTEND
1764 164669 : || (lcode == LSHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1765 862 : && (rcode == ZERO_EXTEND
1766 750 : || (rcode == LSHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1767 : {
1768 112 : machine_mode lmode = GET_MODE (lhs);
1769 112 : machine_mode rmode = GET_MODE (rhs);
1770 112 : int bits;
1771 :
1772 112 : if (lcode == LSHIFTRT)
1773 : /* Number of bits not shifted off the end. */
1774 0 : bits = (GET_MODE_UNIT_PRECISION (lmode)
1775 0 : - INTVAL (XEXP (lhs, 1)));
1776 : else /* lcode == ZERO_EXTEND */
1777 : /* Size of inner mode. */
1778 224 : bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1779 :
1780 112 : if (rcode == LSHIFTRT)
1781 0 : bits += (GET_MODE_UNIT_PRECISION (rmode)
1782 0 : - INTVAL (XEXP (rhs, 1)));
1783 : else /* rcode == ZERO_EXTEND */
1784 224 : bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1785 :
1786 : /* We can only widen multiplies if the result is mathematiclly
1787 : equivalent. I.e. if overflow was impossible. */
1788 224 : if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1789 112 : return simplify_gen_binary
1790 112 : (MULT, mode,
1791 : simplify_gen_unary (ZERO_EXTEND, mode, lhs, lmode),
1792 112 : simplify_gen_unary (ZERO_EXTEND, mode, rhs, rmode));
1793 : }
1794 : }
1795 :
1796 : /* (zero_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1797 11293736 : if (GET_CODE (op) == ZERO_EXTEND)
1798 21709 : return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0),
1799 21709 : GET_MODE (XEXP (op, 0)));
1800 :
1801 : /* (zero_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1802 : is (zero_extend:M (subreg:O <X>)) if there is mode with
1803 : GET_MODE_PRECISION (N) - I bits. */
1804 11272027 : if (GET_CODE (op) == LSHIFTRT
1805 70340 : && GET_CODE (XEXP (op, 0)) == ASHIFT
1806 11272050 : && is_a <scalar_int_mode> (mode, &int_mode)
1807 23 : && CONST_INT_P (XEXP (op, 1))
1808 18 : && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1809 11272027 : && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1810 0 : GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1811 : {
1812 0 : scalar_int_mode tmode;
1813 0 : if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1814 0 : - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1815 : {
1816 0 : rtx inner =
1817 0 : rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1818 0 : if (inner)
1819 0 : return simplify_gen_unary (ZERO_EXTEND, int_mode,
1820 0 : inner, tmode);
1821 : }
1822 : }
1823 :
1824 : /* (zero_extend:M (subreg:N <X:O>)) is <X:O> (for M == O) or
1825 : (zero_extend:M <X:O>), if X doesn't have any non-zero bits outside
1826 : of mode N. E.g.
1827 : (zero_extend:SI (subreg:QI (and:SI (reg:SI) (const_int 63)) 0)) is
1828 : (and:SI (reg:SI) (const_int 63)). */
1829 11272027 : if (partial_subreg_p (op)
1830 12785106 : && is_a <scalar_int_mode> (mode, &int_mode)
1831 1532010 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &op0_mode)
1832 1531424 : && GET_MODE_PRECISION (op0_mode) <= HOST_BITS_PER_WIDE_INT
1833 1213765 : && GET_MODE_PRECISION (int_mode) >= GET_MODE_PRECISION (op0_mode)
1834 1191978 : && subreg_lowpart_p (op)
1835 2406357 : && (nonzero_bits (SUBREG_REG (op), op0_mode)
1836 855705 : & ~GET_MODE_MASK (GET_MODE (op))) == 0)
1837 : {
1838 18931 : if (GET_MODE_PRECISION (int_mode) == GET_MODE_PRECISION (op0_mode))
1839 11856 : return SUBREG_REG (op);
1840 7075 : return simplify_gen_unary (ZERO_EXTEND, int_mode, SUBREG_REG (op),
1841 7075 : op0_mode);
1842 : }
1843 :
1844 : /* (zero_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1845 11253096 : if (GET_CODE (op) == SUBREG
1846 1531721 : && subreg_lowpart_p (op)
1847 939918 : && GET_MODE (SUBREG_REG (op)) == mode
1848 12103174 : && is_a <scalar_int_mode> (mode, &int_mode)
1849 850078 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1850 850078 : && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
1851 788745 : && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
1852 12041841 : && (nonzero_bits (SUBREG_REG (op), mode)
1853 788745 : & ~GET_MODE_MASK (op_mode)) == 0)
1854 0 : return SUBREG_REG (op);
1855 :
1856 : /* Trying to optimize:
1857 : (zero_extend:M (subreg:N (not:M (X:M)))) ->
1858 : (xor:M (zero_extend:M (subreg:N (X:M)), mask))
1859 : where the mask is GET_MODE_MASK (N).
1860 : For the cases when X:M doesn't have any non-zero bits
1861 : outside of mode N, (zero_extend:M (subreg:N (X:M))
1862 : will be simplified to just (X:M)
1863 : and whole optimization will be -> (xor:M (X:M, mask)). */
1864 11253096 : if (partial_subreg_p (op)
1865 1513079 : && GET_CODE (XEXP (op, 0)) == NOT
1866 1446 : && GET_MODE (XEXP (op, 0)) == mode
1867 1425 : && subreg_lowpart_p (op)
1868 11253500 : && HWI_COMPUTABLE_MODE_P (mode)
1869 411 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1870 1532132 : && (nonzero_bits (XEXP (XEXP (op, 0), 0), mode)
1871 411 : & ~GET_MODE_MASK (op_mode)) == 0)
1872 : {
1873 7 : unsigned HOST_WIDE_INT mask = GET_MODE_MASK (op_mode);
1874 14 : return simplify_gen_binary (XOR, mode,
1875 7 : XEXP (XEXP (op, 0), 0),
1876 7 : gen_int_mode (mask, mode));
1877 : }
1878 :
1879 : #if defined(POINTERS_EXTEND_UNSIGNED)
1880 : /* As we do not know which address space the pointer is referring to,
1881 : we can do this only if the target does not support different pointer
1882 : or address modes depending on the address space. */
1883 11253089 : if (target_default_pointer_address_modes_p ()
1884 : && POINTERS_EXTEND_UNSIGNED > 0
1885 12673491 : && mode == Pmode && GET_MODE (op) == ptr_mode
1886 687 : && (CONSTANT_P (op)
1887 666 : || (GET_CODE (op) == SUBREG
1888 0 : && REG_P (SUBREG_REG (op))
1889 0 : && REG_POINTER (SUBREG_REG (op))
1890 0 : && GET_MODE (SUBREG_REG (op)) == Pmode))
1891 11253110 : && !targetm.have_ptr_extend ())
1892 : {
1893 21 : temp
1894 21 : = convert_memory_address_addr_space_1 (Pmode, op,
1895 : ADDR_SPACE_GENERIC, false,
1896 : true);
1897 21 : if (temp)
1898 : return temp;
1899 : }
1900 : #endif
1901 : break;
1902 :
1903 : default:
1904 : break;
1905 : }
1906 :
1907 18695515 : if (VECTOR_MODE_P (mode)
1908 1515576 : && vec_duplicate_p (op, &elt)
1909 20216848 : && code != VEC_DUPLICATE)
1910 : {
1911 5753 : if (code == SIGN_EXTEND || code == ZERO_EXTEND)
1912 : /* Enforce a canonical order of VEC_DUPLICATE wrt other unary
1913 : operations by promoting VEC_DUPLICATE to the root of the expression
1914 : (as far as possible). */
1915 4696 : temp = simplify_gen_unary (code, GET_MODE_INNER (mode),
1916 9392 : elt, GET_MODE_INNER (GET_MODE (op)));
1917 : else
1918 : /* Try applying the operator to ELT and see if that simplifies.
1919 : We can duplicate the result if so.
1920 :
1921 : The reason we traditionally haven't used simplify_gen_unary
1922 : for these codes is that it didn't necessarily seem to be a
1923 : win to convert things like:
1924 :
1925 : (neg:V (vec_duplicate:V (reg:S R)))
1926 :
1927 : to:
1928 :
1929 : (vec_duplicate:V (neg:S (reg:S R)))
1930 :
1931 : The first might be done entirely in vector registers while the
1932 : second might need a move between register files.
1933 :
1934 : However, there also cases where promoting the vec_duplicate is
1935 : more efficient, and there is definite value in having a canonical
1936 : form when matching instruction patterns. We should consider
1937 : extending the simplify_gen_unary code above to more cases. */
1938 1057 : temp = simplify_unary_operation (code, GET_MODE_INNER (mode),
1939 2114 : elt, GET_MODE_INNER (GET_MODE (op)));
1940 5753 : if (temp)
1941 5276 : return gen_vec_duplicate (mode, temp);
1942 : }
1943 :
1944 : return 0;
1945 : }
1946 :
1947 : /* Try to compute the value of a unary operation CODE whose output mode is to
1948 : be MODE with input operand OP whose mode was originally OP_MODE.
1949 : Return zero if the value cannot be computed. */
1950 : rtx
1951 26883693 : simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
1952 : rtx op, machine_mode op_mode)
1953 : {
1954 26883693 : scalar_int_mode result_mode;
1955 :
1956 26883693 : if (code == VEC_DUPLICATE)
1957 : {
1958 1621441 : gcc_assert (VECTOR_MODE_P (mode));
1959 1621441 : if (GET_MODE (op) != VOIDmode)
1960 : {
1961 542907 : if (!VECTOR_MODE_P (GET_MODE (op)))
1962 1072526 : gcc_assert (GET_MODE_INNER (mode) == GET_MODE (op));
1963 : else
1964 19932 : gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER
1965 : (GET_MODE (op)));
1966 : }
1967 1621441 : if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op))
1968 1116002 : return gen_const_vec_duplicate (mode, op);
1969 505439 : if (GET_CODE (op) == CONST_VECTOR
1970 505439 : && (CONST_VECTOR_DUPLICATE_P (op)
1971 : || CONST_VECTOR_NUNITS (op).is_constant ()))
1972 : {
1973 755 : unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op)
1974 755 : ? CONST_VECTOR_NPATTERNS (op)
1975 1509 : : CONST_VECTOR_NUNITS (op).to_constant ());
1976 2265 : gcc_assert (multiple_p (GET_MODE_NUNITS (mode), npatterns));
1977 755 : rtx_vector_builder builder (mode, npatterns, 1);
1978 3130 : for (unsigned i = 0; i < npatterns; i++)
1979 2375 : builder.quick_push (CONST_VECTOR_ELT (op, i));
1980 755 : return builder.build ();
1981 755 : }
1982 : }
1983 :
1984 24527550 : if (VECTOR_MODE_P (mode)
1985 1556323 : && GET_CODE (op) == CONST_VECTOR
1986 25867130 : && known_eq (GET_MODE_NUNITS (mode), CONST_VECTOR_NUNITS (op)))
1987 : {
1988 33398 : gcc_assert (GET_MODE (op) == op_mode);
1989 :
1990 33398 : rtx_vector_builder builder;
1991 33398 : if (!builder.new_unary_operation (mode, op, false))
1992 : return 0;
1993 :
1994 33398 : unsigned int count = builder.encoded_nelts ();
1995 148690 : for (unsigned int i = 0; i < count; i++)
1996 : {
1997 231622 : rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
1998 : CONST_VECTOR_ELT (op, i),
1999 231622 : GET_MODE_INNER (op_mode));
2000 115811 : if (!x || !valid_for_const_vector_p (mode, x))
2001 519 : return 0;
2002 115292 : builder.quick_push (x);
2003 : }
2004 32879 : return builder.build ();
2005 33398 : }
2006 :
2007 : /* The order of these tests is critical so that, for example, we don't
2008 : check the wrong mode (input vs. output) for a conversion operation,
2009 : such as FIX. At some point, this should be simplified. */
2010 :
2011 25733538 : if (code == FLOAT && CONST_SCALAR_INT_P (op))
2012 : {
2013 7354 : REAL_VALUE_TYPE d;
2014 :
2015 7354 : if (op_mode == VOIDmode)
2016 : {
2017 : /* CONST_INT have VOIDmode as the mode. We assume that all
2018 : the bits of the constant are significant, though, this is
2019 : a dangerous assumption as many times CONST_INTs are
2020 : created and used with garbage in the bits outside of the
2021 : precision of the implied mode of the const_int. */
2022 64 : op_mode = MAX_MODE_INT;
2023 : }
2024 :
2025 7354 : real_from_integer (&d, mode, rtx_mode_t (op, op_mode), SIGNED);
2026 :
2027 : /* Avoid the folding if flag_signaling_nans is on and
2028 : operand is a signaling NaN. */
2029 7354 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2030 : return 0;
2031 :
2032 7354 : d = real_value_truncate (mode, d);
2033 :
2034 : /* Avoid the folding if flag_rounding_math is on and the
2035 : conversion is not exact. */
2036 7354 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2037 : {
2038 1011 : bool fail = false;
2039 1011 : wide_int w = real_to_integer (&d, &fail,
2040 : GET_MODE_PRECISION
2041 1011 : (as_a <scalar_int_mode> (op_mode)));
2042 2022 : if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
2043 905 : return 0;
2044 1011 : }
2045 :
2046 6449 : return const_double_from_real_value (d, mode);
2047 : }
2048 25726184 : else if (code == UNSIGNED_FLOAT && CONST_SCALAR_INT_P (op))
2049 : {
2050 2139 : REAL_VALUE_TYPE d;
2051 :
2052 2139 : if (op_mode == VOIDmode)
2053 : {
2054 : /* CONST_INT have VOIDmode as the mode. We assume that all
2055 : the bits of the constant are significant, though, this is
2056 : a dangerous assumption as many times CONST_INTs are
2057 : created and used with garbage in the bits outside of the
2058 : precision of the implied mode of the const_int. */
2059 8 : op_mode = MAX_MODE_INT;
2060 : }
2061 :
2062 2139 : real_from_integer (&d, mode, rtx_mode_t (op, op_mode), UNSIGNED);
2063 :
2064 : /* Avoid the folding if flag_signaling_nans is on and
2065 : operand is a signaling NaN. */
2066 2139 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2067 : return 0;
2068 :
2069 2139 : d = real_value_truncate (mode, d);
2070 :
2071 : /* Avoid the folding if flag_rounding_math is on and the
2072 : conversion is not exact. */
2073 2139 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2074 : {
2075 16 : bool fail = false;
2076 16 : wide_int w = real_to_integer (&d, &fail,
2077 : GET_MODE_PRECISION
2078 16 : (as_a <scalar_int_mode> (op_mode)));
2079 28 : if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
2080 16 : return 0;
2081 16 : }
2082 :
2083 2123 : return const_double_from_real_value (d, mode);
2084 : }
2085 :
2086 25724045 : if (CONST_SCALAR_INT_P (op) && is_a <scalar_int_mode> (mode, &result_mode))
2087 : {
2088 3410443 : unsigned int width = GET_MODE_PRECISION (result_mode);
2089 3410443 : if (width > MAX_BITSIZE_MODE_ANY_INT)
2090 : return 0;
2091 :
2092 3410443 : wide_int result;
2093 3410443 : scalar_int_mode imode = (op_mode == VOIDmode
2094 3410443 : ? result_mode
2095 3410226 : : as_a <scalar_int_mode> (op_mode));
2096 3410443 : rtx_mode_t op0 = rtx_mode_t (op, imode);
2097 3410443 : int int_value;
2098 :
2099 : #if TARGET_SUPPORTS_WIDE_INT == 0
2100 : /* This assert keeps the simplification from producing a result
2101 : that cannot be represented in a CONST_DOUBLE but a lot of
2102 : upstream callers expect that this function never fails to
2103 : simplify something and so you if you added this to the test
2104 : above the code would die later anyway. If this assert
2105 : happens, you just need to make the port support wide int. */
2106 : gcc_assert (width <= HOST_BITS_PER_DOUBLE_INT);
2107 : #endif
2108 :
2109 3410443 : switch (code)
2110 : {
2111 179426 : case NOT:
2112 179426 : result = wi::bit_not (op0);
2113 179426 : break;
2114 :
2115 1964376 : case NEG:
2116 1964376 : result = wi::neg (op0);
2117 1964376 : break;
2118 :
2119 7435 : case ABS:
2120 7435 : result = wi::abs (op0);
2121 7435 : break;
2122 :
2123 0 : case FFS:
2124 0 : result = wi::shwi (wi::ffs (op0), result_mode);
2125 0 : break;
2126 :
2127 168 : case CLZ:
2128 168 : if (wi::ne_p (op0, 0))
2129 38 : int_value = wi::clz (op0);
2130 260 : else if (! CLZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2131 : return NULL_RTX;
2132 38 : result = wi::shwi (int_value, result_mode);
2133 38 : break;
2134 :
2135 0 : case CLRSB:
2136 0 : result = wi::shwi (wi::clrsb (op0), result_mode);
2137 0 : break;
2138 :
2139 0 : case CTZ:
2140 0 : if (wi::ne_p (op0, 0))
2141 0 : int_value = wi::ctz (op0);
2142 0 : else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2143 : return NULL_RTX;
2144 0 : result = wi::shwi (int_value, result_mode);
2145 0 : break;
2146 :
2147 160 : case POPCOUNT:
2148 160 : result = wi::shwi (wi::popcount (op0), result_mode);
2149 160 : break;
2150 :
2151 0 : case PARITY:
2152 0 : result = wi::shwi (wi::parity (op0), result_mode);
2153 0 : break;
2154 :
2155 2017 : case BSWAP:
2156 2017 : result = wi::bswap (op0);
2157 2017 : break;
2158 :
2159 0 : case BITREVERSE:
2160 0 : result = wi::bitreverse (op0);
2161 0 : break;
2162 :
2163 1079112 : case TRUNCATE:
2164 1079112 : case ZERO_EXTEND:
2165 1079112 : result = wide_int::from (op0, width, UNSIGNED);
2166 1079112 : break;
2167 :
2168 14342 : case US_TRUNCATE:
2169 14342 : case SS_TRUNCATE:
2170 14342 : {
2171 14342 : signop sgn = code == US_TRUNCATE ? UNSIGNED : SIGNED;
2172 14342 : wide_int nmax
2173 14342 : = wide_int::from (wi::max_value (width, sgn),
2174 28684 : GET_MODE_PRECISION (imode), sgn);
2175 14342 : wide_int nmin
2176 14342 : = wide_int::from (wi::min_value (width, sgn),
2177 28684 : GET_MODE_PRECISION (imode), sgn);
2178 14342 : result = wi::min (wi::max (op0, nmin, sgn), nmax, sgn);
2179 14342 : result = wide_int::from (result, width, sgn);
2180 14342 : break;
2181 14342 : }
2182 163407 : case SIGN_EXTEND:
2183 163407 : result = wide_int::from (op0, width, SIGNED);
2184 163407 : break;
2185 :
2186 0 : case SS_NEG:
2187 0 : if (wi::only_sign_bit_p (op0))
2188 0 : result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
2189 : else
2190 0 : result = wi::neg (op0);
2191 : break;
2192 :
2193 0 : case SS_ABS:
2194 0 : if (wi::only_sign_bit_p (op0))
2195 0 : result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
2196 : else
2197 0 : result = wi::abs (op0);
2198 : break;
2199 :
2200 : case SQRT:
2201 : default:
2202 : return 0;
2203 : }
2204 :
2205 3410313 : return immed_wide_int_const (result, result_mode);
2206 3410443 : }
2207 :
2208 22313602 : else if (CONST_DOUBLE_AS_FLOAT_P (op)
2209 420974 : && SCALAR_FLOAT_MODE_P (mode)
2210 418946 : && SCALAR_FLOAT_MODE_P (GET_MODE (op)))
2211 : {
2212 418946 : REAL_VALUE_TYPE d = *CONST_DOUBLE_REAL_VALUE (op);
2213 418946 : switch (code)
2214 : {
2215 : case SQRT:
2216 : return 0;
2217 350 : case ABS:
2218 350 : d = real_value_abs (&d);
2219 350 : break;
2220 15712 : case NEG:
2221 15712 : d = real_value_negate (&d);
2222 15712 : break;
2223 2286 : case FLOAT_TRUNCATE:
2224 : /* Don't perform the operation if flag_signaling_nans is on
2225 : and the operand is a signaling NaN. */
2226 2286 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2227 : return NULL_RTX;
2228 : /* Or if flag_rounding_math is on and the truncation is not
2229 : exact. */
2230 2286 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2231 2286 : && !exact_real_truncate (mode, &d))
2232 231 : return NULL_RTX;
2233 2055 : d = real_value_truncate (mode, d);
2234 2055 : break;
2235 394073 : case FLOAT_EXTEND:
2236 : /* Don't perform the operation if flag_signaling_nans is on
2237 : and the operand is a signaling NaN. */
2238 394073 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2239 : return NULL_RTX;
2240 : /* All this does is change the mode, unless changing
2241 : mode class. */
2242 394071 : if (GET_MODE_CLASS (mode) != GET_MODE_CLASS (GET_MODE (op)))
2243 0 : real_convert (&d, mode, &d);
2244 : break;
2245 0 : case FIX:
2246 : /* Don't perform the operation if flag_signaling_nans is on
2247 : and the operand is a signaling NaN. */
2248 0 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2249 : return NULL_RTX;
2250 0 : real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
2251 0 : break;
2252 5920 : case NOT:
2253 5920 : {
2254 5920 : long tmp[4];
2255 5920 : int i;
2256 :
2257 5920 : real_to_target (tmp, &d, GET_MODE (op));
2258 29600 : for (i = 0; i < 4; i++)
2259 23680 : tmp[i] = ~tmp[i];
2260 5920 : real_from_target (&d, tmp, mode);
2261 5920 : break;
2262 : }
2263 0 : default:
2264 0 : gcc_unreachable ();
2265 : }
2266 418108 : return const_double_from_real_value (d, mode);
2267 : }
2268 2028 : else if (CONST_DOUBLE_AS_FLOAT_P (op)
2269 2028 : && SCALAR_FLOAT_MODE_P (GET_MODE (op))
2270 21896684 : && is_int_mode (mode, &result_mode))
2271 : {
2272 2028 : unsigned int width = GET_MODE_PRECISION (result_mode);
2273 2028 : if (width > MAX_BITSIZE_MODE_ANY_INT)
2274 : return 0;
2275 :
2276 : /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
2277 : operators are intentionally left unspecified (to ease implementation
2278 : by target backends), for consistency, this routine implements the
2279 : same semantics for constant folding as used by the middle-end. */
2280 :
2281 : /* This was formerly used only for non-IEEE float.
2282 : eggert@twinsun.com says it is safe for IEEE also. */
2283 2028 : REAL_VALUE_TYPE t;
2284 2028 : const REAL_VALUE_TYPE *x = CONST_DOUBLE_REAL_VALUE (op);
2285 2028 : wide_int wmax, wmin;
2286 : /* This is part of the abi to real_to_integer, but we check
2287 : things before making this call. */
2288 2028 : bool fail;
2289 :
2290 2028 : switch (code)
2291 : {
2292 2020 : case FIX:
2293 : /* According to IEEE standard, for conversions from floating point to
2294 : integer. When a NaN or infinite operand cannot be represented in
2295 : the destination format and this cannot otherwise be indicated, the
2296 : invalid operation exception shall be signaled. When a numeric
2297 : operand would convert to an integer outside the range of the
2298 : destination format, the invalid operation exception shall be
2299 : signaled if this situation cannot otherwise be indicated. */
2300 2020 : if (REAL_VALUE_ISNAN (*x))
2301 955 : return flag_trapping_math ? NULL_RTX : const0_rtx;
2302 :
2303 1065 : if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
2304 : return NULL_RTX;
2305 :
2306 : /* Test against the signed upper bound. */
2307 105 : wmax = wi::max_value (width, SIGNED);
2308 105 : real_from_integer (&t, VOIDmode, wmax, SIGNED);
2309 105 : if (real_less (&t, x))
2310 3 : return (flag_trapping_math
2311 3 : ? NULL_RTX : immed_wide_int_const (wmax, mode));
2312 :
2313 : /* Test against the signed lower bound. */
2314 102 : wmin = wi::min_value (width, SIGNED);
2315 102 : real_from_integer (&t, VOIDmode, wmin, SIGNED);
2316 102 : if (real_less (x, &t))
2317 8 : return immed_wide_int_const (wmin, mode);
2318 :
2319 94 : return immed_wide_int_const (real_to_integer (x, &fail, width),
2320 : mode);
2321 :
2322 8 : case UNSIGNED_FIX:
2323 8 : if (REAL_VALUE_ISNAN (*x) || REAL_VALUE_NEGATIVE (*x))
2324 6 : return flag_trapping_math ? NULL_RTX : const0_rtx;
2325 :
2326 2 : if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
2327 : return NULL_RTX;
2328 :
2329 : /* Test against the unsigned upper bound. */
2330 0 : wmax = wi::max_value (width, UNSIGNED);
2331 0 : real_from_integer (&t, VOIDmode, wmax, UNSIGNED);
2332 0 : if (real_less (&t, x))
2333 0 : return (flag_trapping_math
2334 0 : ? NULL_RTX : immed_wide_int_const (wmax, mode));
2335 :
2336 0 : return immed_wide_int_const (real_to_integer (x, &fail, width),
2337 : mode);
2338 :
2339 0 : default:
2340 0 : gcc_unreachable ();
2341 : }
2342 2028 : }
2343 :
2344 : /* Handle polynomial integers. */
2345 : else if (CONST_POLY_INT_P (op))
2346 : {
2347 : poly_wide_int result;
2348 : switch (code)
2349 : {
2350 : case NEG:
2351 : result = -const_poly_int_value (op);
2352 : break;
2353 :
2354 : case NOT:
2355 : result = ~const_poly_int_value (op);
2356 : break;
2357 :
2358 : default:
2359 : return NULL_RTX;
2360 : }
2361 : return immed_wide_int_const (result, mode);
2362 : }
2363 :
2364 : return NULL_RTX;
2365 : }
2366 :
2367 : /* Subroutine of simplify_binary_operation to simplify a binary operation
2368 : CODE that can commute with byte swapping, with result mode MODE and
2369 : operating on OP0 and OP1. CODE is currently one of AND, IOR or XOR.
2370 : Return zero if no simplification or canonicalization is possible. */
2371 :
2372 : rtx
2373 36366413 : simplify_context::simplify_byte_swapping_operation (rtx_code code,
2374 : machine_mode mode,
2375 : rtx op0, rtx op1)
2376 : {
2377 36366413 : rtx tem;
2378 :
2379 : /* (op (bswap x) C1)) -> (bswap (op x C2)) with C2 swapped. */
2380 36366413 : if (GET_CODE (op0) == BSWAP && CONST_SCALAR_INT_P (op1))
2381 : {
2382 506 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0),
2383 : simplify_gen_unary (BSWAP, mode, op1, mode));
2384 506 : return simplify_gen_unary (BSWAP, mode, tem, mode);
2385 : }
2386 :
2387 : /* (op (bswap x) (bswap y)) -> (bswap (op x y)). */
2388 36365907 : if (GET_CODE (op0) == BSWAP && GET_CODE (op1) == BSWAP)
2389 : {
2390 0 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0), XEXP (op1, 0));
2391 0 : return simplify_gen_unary (BSWAP, mode, tem, mode);
2392 : }
2393 :
2394 : return NULL_RTX;
2395 : }
2396 :
2397 : /* Subroutine of simplify_binary_operation to simplify a commutative,
2398 : associative binary operation CODE with result mode MODE, operating
2399 : on OP0 and OP1. CODE is currently one of PLUS, MULT, AND, IOR, XOR,
2400 : SMIN, SMAX, UMIN or UMAX. Return zero if no simplification or
2401 : canonicalization is possible. */
2402 :
2403 : rtx
2404 46221411 : simplify_context::simplify_associative_operation (rtx_code code,
2405 : machine_mode mode,
2406 : rtx op0, rtx op1)
2407 : {
2408 46221411 : rtx tem;
2409 :
2410 : /* Normally expressions simplified by simplify-rtx.cc are combined
2411 : at most from a few machine instructions and therefore the
2412 : expressions should be fairly small. During var-tracking
2413 : we can see arbitrarily large expressions though and reassociating
2414 : those can be quadratic, so punt after encountering max_assoc_count
2415 : simplify_associative_operation calls during outermost simplify_*
2416 : call. */
2417 46221411 : if (++assoc_count >= max_assoc_count)
2418 : return NULL_RTX;
2419 :
2420 : /* Linearize the operator to the left. */
2421 46217618 : if (GET_CODE (op1) == code)
2422 : {
2423 : /* "(a op b) op (c op d)" becomes "((a op b) op c) op d)". */
2424 18457 : if (GET_CODE (op0) == code)
2425 : {
2426 4808 : tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
2427 4808 : return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
2428 : }
2429 :
2430 : /* "a op (b op c)" becomes "(b op c) op a". */
2431 13649 : if (! swap_commutative_operands_p (op1, op0))
2432 13649 : return simplify_gen_binary (code, mode, op1, op0);
2433 :
2434 : std::swap (op0, op1);
2435 : }
2436 :
2437 46199161 : if (GET_CODE (op0) == code)
2438 : {
2439 : /* Canonicalize "(x op c) op y" as "(x op y) op c". */
2440 1281649 : if (swap_commutative_operands_p (XEXP (op0, 1), op1))
2441 : {
2442 261166 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
2443 261166 : return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2444 : }
2445 :
2446 : /* Attempt to simplify "(a op b) op c" as "a op (b op c)". */
2447 1020483 : tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
2448 1020483 : if (tem != 0)
2449 76927 : return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
2450 :
2451 : /* Attempt to simplify "(a op b) op c" as "(a op c) op b". */
2452 943556 : tem = simplify_binary_operation (code, mode, XEXP (op0, 0), op1);
2453 943556 : if (tem != 0)
2454 29919 : return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2455 : }
2456 :
2457 : return 0;
2458 : }
2459 :
2460 : /* If COMPARISON can be treated as an unsigned comparison, return a mask
2461 : that represents it (8 if it includes <, 4 if it includes > and 2
2462 : if it includes ==). Return 0 otherwise. */
2463 : static int
2464 18866 : unsigned_comparison_to_mask (rtx_code comparison)
2465 : {
2466 0 : switch (comparison)
2467 : {
2468 : case LTU:
2469 : return 8;
2470 : case GTU:
2471 : return 4;
2472 : case EQ:
2473 : return 2;
2474 :
2475 : case LEU:
2476 : return 10;
2477 : case GEU:
2478 : return 6;
2479 :
2480 : case NE:
2481 : return 12;
2482 :
2483 : default:
2484 : return 0;
2485 : }
2486 : }
2487 :
2488 : /* Reverse the mapping in unsigned_comparison_to_mask, going from masks
2489 : to comparisons. */
2490 : static rtx_code
2491 6596 : mask_to_unsigned_comparison (int mask)
2492 : {
2493 6596 : switch (mask)
2494 : {
2495 : case 8:
2496 : return LTU;
2497 160 : case 4:
2498 160 : return GTU;
2499 2594 : case 2:
2500 2594 : return EQ;
2501 :
2502 160 : case 10:
2503 160 : return LEU;
2504 160 : case 6:
2505 160 : return GEU;
2506 :
2507 3362 : case 12:
2508 3362 : return NE;
2509 :
2510 0 : default:
2511 0 : gcc_unreachable ();
2512 : }
2513 : }
2514 :
2515 : /* Return a mask describing the COMPARISON. */
2516 : static int
2517 2666 : comparison_to_mask (enum rtx_code comparison)
2518 : {
2519 2666 : switch (comparison)
2520 : {
2521 : case LT:
2522 : return 8;
2523 472 : case GT:
2524 472 : return 4;
2525 419 : case EQ:
2526 419 : return 2;
2527 19 : case UNORDERED:
2528 19 : return 1;
2529 :
2530 0 : case LTGT:
2531 0 : return 12;
2532 441 : case LE:
2533 441 : return 10;
2534 441 : case GE:
2535 441 : return 6;
2536 0 : case UNLT:
2537 0 : return 9;
2538 0 : case UNGT:
2539 0 : return 5;
2540 0 : case UNEQ:
2541 0 : return 3;
2542 :
2543 0 : case ORDERED:
2544 0 : return 14;
2545 400 : case NE:
2546 400 : return 13;
2547 0 : case UNLE:
2548 0 : return 11;
2549 0 : case UNGE:
2550 0 : return 7;
2551 :
2552 0 : default:
2553 0 : gcc_unreachable ();
2554 : }
2555 : }
2556 :
2557 : /* Return a comparison corresponding to the MASK. */
2558 : static enum rtx_code
2559 1014 : mask_to_comparison (int mask)
2560 : {
2561 1014 : switch (mask)
2562 : {
2563 : case 8:
2564 : return LT;
2565 : case 4:
2566 : return GT;
2567 : case 2:
2568 : return EQ;
2569 : case 1:
2570 : return UNORDERED;
2571 :
2572 : case 12:
2573 : return LTGT;
2574 : case 10:
2575 : return LE;
2576 : case 6:
2577 : return GE;
2578 : case 9:
2579 : return UNLT;
2580 : case 5:
2581 : return UNGT;
2582 : case 3:
2583 : return UNEQ;
2584 :
2585 : case 14:
2586 : return ORDERED;
2587 : case 13:
2588 : return NE;
2589 : case 11:
2590 : return UNLE;
2591 : case 7:
2592 : return UNGE;
2593 :
2594 0 : default:
2595 0 : gcc_unreachable ();
2596 : }
2597 : }
2598 :
2599 : /* Canonicalize RES, a scalar const0_rtx/const_true_rtx to the right
2600 : false/true value of comparison with MODE where comparison operands
2601 : have CMP_MODE. */
2602 :
2603 : static rtx
2604 884015 : relational_result (machine_mode mode, machine_mode cmp_mode, rtx res)
2605 : {
2606 884015 : if (SCALAR_FLOAT_MODE_P (mode))
2607 : {
2608 197 : if (res == const0_rtx)
2609 193 : return CONST0_RTX (mode);
2610 : #ifdef FLOAT_STORE_FLAG_VALUE
2611 : REAL_VALUE_TYPE val = FLOAT_STORE_FLAG_VALUE (mode);
2612 : return const_double_from_real_value (val, mode);
2613 : #else
2614 : return NULL_RTX;
2615 : #endif
2616 : }
2617 883818 : if (VECTOR_MODE_P (mode))
2618 : {
2619 378 : if (res == const0_rtx)
2620 63 : return CONST0_RTX (mode);
2621 : #ifdef VECTOR_STORE_FLAG_VALUE
2622 315 : rtx val = VECTOR_STORE_FLAG_VALUE (mode);
2623 305 : if (val == NULL_RTX)
2624 : return NULL_RTX;
2625 305 : if (val == const1_rtx)
2626 0 : return CONST1_RTX (mode);
2627 :
2628 305 : return gen_const_vec_duplicate (mode, val);
2629 : #else
2630 : return NULL_RTX;
2631 : #endif
2632 : }
2633 : /* For vector comparison with scalar int result, it is unknown
2634 : if the target means here a comparison into an integral bitmask,
2635 : or comparison where all comparisons true mean const_true_rtx
2636 : whole result, or where any comparisons true mean const_true_rtx
2637 : whole result. For const0_rtx all the cases are the same. */
2638 883440 : if (VECTOR_MODE_P (cmp_mode)
2639 0 : && SCALAR_INT_MODE_P (mode)
2640 0 : && res == const_true_rtx)
2641 0 : return NULL_RTX;
2642 :
2643 : return res;
2644 : }
2645 :
2646 : /* Simplify a logical operation CODE with result mode MODE, operating on OP0
2647 : and OP1, in the case where both are relational operations. Assume that
2648 : OP0 is inverted if INVERT0_P is true.
2649 :
2650 : Return 0 if no such simplification is possible. */
2651 : rtx
2652 13186257 : simplify_context::simplify_logical_relational_operation (rtx_code code,
2653 : machine_mode mode,
2654 : rtx op0, rtx op1,
2655 : bool invert0_p)
2656 : {
2657 13186257 : if (!(COMPARISON_P (op0) && COMPARISON_P (op1)))
2658 : return 0;
2659 :
2660 21422 : if (!(rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2661 9859 : && rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))))
2662 2130 : return 0;
2663 :
2664 9433 : if (side_effects_p (op0))
2665 : return 0;
2666 :
2667 9433 : enum rtx_code code0 = GET_CODE (op0);
2668 9433 : enum rtx_code code1 = GET_CODE (op1);
2669 9433 : machine_mode cmp_mode = GET_MODE (XEXP (op0, 0));
2670 9433 : if (cmp_mode == VOIDmode)
2671 0 : cmp_mode = GET_MODE (XEXP (op0, 1));
2672 :
2673 : /* Assume at first that the comparisons are on integers, and that the
2674 : operands are therefore ordered. */
2675 9433 : int all = 14;
2676 9433 : int mask0 = unsigned_comparison_to_mask (code0);
2677 9433 : int mask1 = unsigned_comparison_to_mask (code1);
2678 18866 : bool unsigned_p = (IN_RANGE (mask0 & 12, 4, 8)
2679 9433 : || IN_RANGE (mask1 & 12, 4, 8));
2680 1333 : if (unsigned_p)
2681 : {
2682 : /* We only reach here when comparing integers. Reject mixtures of signed
2683 : and unsigned comparisons. */
2684 8100 : if (mask0 == 0 || mask1 == 0)
2685 : return 0;
2686 : }
2687 : else
2688 : {
2689 : /* See whether the operands might be unordered. Assume that all
2690 : results are possible for CC modes, and punt later if we don't get an
2691 : always-true or always-false answer. */
2692 1333 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC || HONOR_NANS (cmp_mode))
2693 : all = 15;
2694 1333 : mask0 = comparison_to_mask (code0) & all;
2695 1333 : mask1 = comparison_to_mask (code1) & all;
2696 : }
2697 :
2698 8153 : if (invert0_p)
2699 4662 : mask0 = mask0 ^ all;
2700 :
2701 8153 : int mask;
2702 8153 : if (code == AND)
2703 960 : mask = mask0 & mask1;
2704 7193 : else if (code == IOR)
2705 948 : mask = mask0 | mask1;
2706 6245 : else if (code == XOR)
2707 6245 : mask = mask0 ^ mask1;
2708 : else
2709 : return 0;
2710 :
2711 8153 : if (mask == all)
2712 232 : return relational_result (mode, GET_MODE (op0), const_true_rtx);
2713 :
2714 7921 : if (mask == 0)
2715 232 : return relational_result (mode, GET_MODE (op0), const0_rtx);
2716 :
2717 7689 : if (unsigned_p)
2718 6596 : code = mask_to_unsigned_comparison (mask);
2719 : else
2720 : {
2721 1093 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
2722 : return 0;
2723 :
2724 1014 : code = mask_to_comparison (mask);
2725 : /* LTGT and NE are arithmetically equivalent for ordered operands,
2726 : with NE being the canonical choice. */
2727 1014 : if (code == LTGT && all == 14)
2728 184 : code = NE;
2729 : }
2730 :
2731 7610 : op0 = XEXP (op1, 0);
2732 7610 : op1 = XEXP (op1, 1);
2733 :
2734 7610 : return simplify_gen_relational (code, mode, VOIDmode, op0, op1);
2735 : }
2736 :
2737 : /* Simplify a binary operation CODE with result mode MODE, operating on OP0
2738 : and OP1. Return 0 if no simplification is possible.
2739 :
2740 : Don't use this for relational operations such as EQ or LT.
2741 : Use simplify_relational_operation instead. */
2742 : rtx
2743 471276944 : simplify_context::simplify_binary_operation (rtx_code code, machine_mode mode,
2744 : rtx op0, rtx op1)
2745 : {
2746 471276944 : rtx trueop0, trueop1;
2747 471276944 : rtx tem;
2748 :
2749 : /* Relational operations don't work here. We must know the mode
2750 : of the operands in order to do the comparison correctly.
2751 : Assuming a full word can give incorrect results.
2752 : Consider comparing 128 with -128 in QImode. */
2753 471276944 : gcc_assert (GET_RTX_CLASS (code) != RTX_COMPARE);
2754 471276944 : gcc_assert (GET_RTX_CLASS (code) != RTX_COMM_COMPARE);
2755 :
2756 : /* Make sure the constant is second. */
2757 471276944 : if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
2758 471276944 : && swap_commutative_operands_p (op0, op1))
2759 : std::swap (op0, op1);
2760 :
2761 471276944 : trueop0 = avoid_constant_pool_reference (op0);
2762 471276944 : trueop1 = avoid_constant_pool_reference (op1);
2763 :
2764 471276944 : tem = simplify_const_binary_operation (code, mode, trueop0, trueop1);
2765 471276944 : if (tem)
2766 : return tem;
2767 441528315 : tem = simplify_binary_operation_1 (code, mode, op0, op1, trueop0, trueop1);
2768 :
2769 441528315 : if (tem)
2770 : return tem;
2771 :
2772 : /* If the above steps did not result in a simplification and op0 or op1
2773 : were constant pool references, use the referenced constants directly. */
2774 379487212 : if (trueop0 != op0 || trueop1 != op1)
2775 579355 : return simplify_gen_binary (code, mode, trueop0, trueop1);
2776 :
2777 : return NULL_RTX;
2778 : }
2779 :
2780 : /* Subroutine of simplify_binary_operation_1 that looks for cases in
2781 : which OP0 and OP1 are both vector series or vector duplicates
2782 : (which are really just series with a step of 0). If so, try to
2783 : form a new series by applying CODE to the bases and to the steps.
2784 : Return null if no simplification is possible.
2785 :
2786 : MODE is the mode of the operation and is known to be a vector
2787 : integer mode. */
2788 :
2789 : rtx
2790 2343725 : simplify_context::simplify_binary_operation_series (rtx_code code,
2791 : machine_mode mode,
2792 : rtx op0, rtx op1)
2793 : {
2794 2343725 : rtx base0, step0;
2795 2343725 : if (vec_duplicate_p (op0, &base0))
2796 64500 : step0 = const0_rtx;
2797 2279225 : else if (!vec_series_p (op0, &base0, &step0))
2798 : return NULL_RTX;
2799 :
2800 65011 : rtx base1, step1;
2801 65011 : if (vec_duplicate_p (op1, &base1))
2802 418 : step1 = const0_rtx;
2803 64593 : else if (!vec_series_p (op1, &base1, &step1))
2804 : return NULL_RTX;
2805 :
2806 : /* Only create a new series if we can simplify both parts. In other
2807 : cases this isn't really a simplification, and it's not necessarily
2808 : a win to replace a vector operation with a scalar operation. */
2809 3075 : scalar_mode inner_mode = GET_MODE_INNER (mode);
2810 3075 : rtx new_base = simplify_binary_operation (code, inner_mode, base0, base1);
2811 3075 : if (!new_base)
2812 : return NULL_RTX;
2813 :
2814 2773 : rtx new_step = simplify_binary_operation (code, inner_mode, step0, step1);
2815 2773 : if (!new_step)
2816 : return NULL_RTX;
2817 :
2818 2773 : return gen_vec_series (mode, new_base, new_step);
2819 : }
2820 :
2821 : /* Subroutine of simplify_binary_operation_1. Un-distribute a binary
2822 : operation CODE with result mode MODE, operating on OP0 and OP1.
2823 : e.g. simplify (xor (and A C) (and (B C)) to (and (xor (A B) C).
2824 : Returns NULL_RTX if no simplification is possible. */
2825 :
2826 : rtx
2827 1350708 : simplify_context::simplify_distributive_operation (rtx_code code,
2828 : machine_mode mode,
2829 : rtx op0, rtx op1)
2830 : {
2831 1350708 : enum rtx_code op = GET_CODE (op0);
2832 1350708 : gcc_assert (GET_CODE (op1) == op);
2833 :
2834 1350708 : if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))
2835 1350708 : && ! side_effects_p (XEXP (op0, 1)))
2836 335953 : return simplify_gen_binary (op, mode,
2837 : simplify_gen_binary (code, mode,
2838 : XEXP (op0, 0),
2839 : XEXP (op1, 0)),
2840 335953 : XEXP (op0, 1));
2841 :
2842 1014755 : if (GET_RTX_CLASS (op) == RTX_COMM_ARITH)
2843 : {
2844 996019 : if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2845 996019 : && ! side_effects_p (XEXP (op0, 0)))
2846 477514 : return simplify_gen_binary (op, mode,
2847 : simplify_gen_binary (code, mode,
2848 : XEXP (op0, 1),
2849 : XEXP (op1, 1)),
2850 477514 : XEXP (op0, 0));
2851 518505 : if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 1))
2852 518505 : && ! side_effects_p (XEXP (op0, 0)))
2853 55 : return simplify_gen_binary (op, mode,
2854 : simplify_gen_binary (code, mode,
2855 : XEXP (op0, 1),
2856 : XEXP (op1, 0)),
2857 55 : XEXP (op0, 0));
2858 518450 : if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 0))
2859 518450 : && ! side_effects_p (XEXP (op0, 1)))
2860 251528 : return simplify_gen_binary (op, mode,
2861 : simplify_gen_binary (code, mode,
2862 : XEXP (op0, 0),
2863 : XEXP (op1, 1)),
2864 251528 : XEXP (op0, 1));
2865 : }
2866 :
2867 : return NULL_RTX;
2868 : }
2869 :
2870 : /* Return TRUE if a rotate in mode MODE with a constant count in OP1
2871 : should be reversed.
2872 :
2873 : If the rotate should not be reversed, return FALSE.
2874 :
2875 : LEFT indicates if this is a rotate left or a rotate right. */
2876 :
2877 : bool
2878 145565 : reverse_rotate_by_imm_p (machine_mode mode, unsigned int left, rtx op1)
2879 : {
2880 145565 : if (!CONST_INT_P (op1))
2881 : return false;
2882 :
2883 : /* Some targets may only be able to rotate by a constant
2884 : in one direction. So we need to query the optab interface
2885 : to see what is possible. */
2886 113670 : optab binoptab = left ? rotl_optab : rotr_optab;
2887 47572 : optab re_binoptab = left ? rotr_optab : rotl_optab;
2888 113670 : enum insn_code icode = optab_handler (binoptab, mode);
2889 113670 : enum insn_code re_icode = optab_handler (re_binoptab, mode);
2890 :
2891 : /* If the target can not support the reversed optab, then there
2892 : is nothing to do. */
2893 113670 : if (re_icode == CODE_FOR_nothing)
2894 : return false;
2895 :
2896 : /* If the target does not support the requested rotate-by-immediate,
2897 : then we want to try reversing the rotate. We also want to try
2898 : reversing to minimize the count. */
2899 111212 : if ((icode == CODE_FOR_nothing)
2900 111212 : || (!insn_operand_matches (icode, 2, op1))
2901 556060 : || (IN_RANGE (INTVAL (op1),
2902 : GET_MODE_UNIT_PRECISION (mode) / 2 + left,
2903 : GET_MODE_UNIT_PRECISION (mode) - 1)))
2904 14770 : return (insn_operand_matches (re_icode, 2, op1));
2905 : return false;
2906 : }
2907 :
2908 : /* Analyse argument X to see if it represents an (ASHIFT X Y) operation
2909 : and return the expression to be shifted in SHIFT_OPND and the shift amount
2910 : in SHIFT_AMNT. This is primarily used to group handling of ASHIFT (X, CST)
2911 : and (PLUS (X, X)) in one place. If the expression is not equivalent to an
2912 : ASHIFT then return FALSE and set SHIFT_OPND and SHIFT_AMNT to NULL. */
2913 :
2914 : static bool
2915 522920497 : extract_ashift_operands_p (rtx x, rtx *shift_opnd, rtx *shift_amnt)
2916 : {
2917 522920497 : if (GET_CODE (x) == ASHIFT)
2918 : {
2919 13563190 : *shift_opnd = XEXP (x, 0);
2920 13563190 : *shift_amnt = XEXP (x, 1);
2921 13563190 : return true;
2922 : }
2923 509357307 : if (GET_CODE (x) == PLUS && rtx_equal_p (XEXP (x, 0), XEXP (x, 1)))
2924 : {
2925 13244 : *shift_opnd = XEXP (x, 0);
2926 13244 : *shift_amnt = CONST1_RTX (GET_MODE (x));
2927 13244 : return true;
2928 : }
2929 509344063 : *shift_opnd = NULL_RTX;
2930 509344063 : *shift_amnt = NULL_RTX;
2931 509344063 : return false;
2932 : }
2933 :
2934 : /* OP0 and OP1 are combined under an operation of mode MODE that can
2935 : potentially result in a ROTATE expression. Analyze the OP0 and OP1
2936 : and return the resulting ROTATE expression if so. Return NULL otherwise.
2937 : This is used in detecting the patterns (X << C1) [+,|,^] (X >> C2) where
2938 : C1 + C2 == GET_MODE_UNIT_PRECISION (mode).
2939 : (X << C1) and (C >> C2) would be OP0 and OP1. */
2940 :
2941 : static rtx
2942 263534137 : simplify_rotate_op (rtx op0, rtx op1, machine_mode mode)
2943 : {
2944 : /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
2945 : mode size to (rotate A CX). */
2946 :
2947 263534137 : rtx opleft = op0;
2948 263534137 : rtx opright = op1;
2949 263534137 : rtx ashift_opnd, ashift_amnt;
2950 : /* In some cases the ASHIFT is not a direct ASHIFT. Look deeper and extract
2951 : the relevant operands here. */
2952 263534137 : bool ashift_op_p
2953 263534137 : = extract_ashift_operands_p (op1, &ashift_opnd, &ashift_amnt);
2954 :
2955 263534137 : if (ashift_op_p
2956 261930320 : || GET_CODE (op1) == SUBREG)
2957 : {
2958 : opleft = op1;
2959 : opright = op0;
2960 : }
2961 : else
2962 : {
2963 259386360 : opright = op1;
2964 259386360 : opleft = op0;
2965 259386360 : ashift_op_p
2966 259386360 : = extract_ashift_operands_p (opleft, &ashift_opnd, &ashift_amnt);
2967 : }
2968 :
2969 13576434 : if (ashift_op_p && GET_CODE (opright) == LSHIFTRT
2970 261973675 : && rtx_equal_p (ashift_opnd, XEXP (opright, 0)))
2971 : {
2972 9707 : rtx leftcst = unwrap_const_vec_duplicate (ashift_amnt);
2973 9707 : rtx rightcst = unwrap_const_vec_duplicate (XEXP (opright, 1));
2974 :
2975 5889 : if (CONST_INT_P (leftcst) && CONST_INT_P (rightcst)
2976 15596 : && (INTVAL (leftcst) + INTVAL (rightcst)
2977 5889 : == GET_MODE_UNIT_PRECISION (mode)))
2978 5362 : return gen_rtx_ROTATE (mode, XEXP (opright, 0), ashift_amnt);
2979 : }
2980 :
2981 : /* Same, but for ashift that has been "simplified" to a wider mode
2982 : by simplify_shift_const. */
2983 263528775 : scalar_int_mode int_mode, inner_mode;
2984 :
2985 263528775 : if (GET_CODE (opleft) == SUBREG
2986 267016503 : && is_a <scalar_int_mode> (mode, &int_mode)
2987 3482366 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (opleft)),
2988 : &inner_mode)
2989 3451347 : && GET_CODE (SUBREG_REG (opleft)) == ASHIFT
2990 101961 : && GET_CODE (opright) == LSHIFTRT
2991 1108 : && GET_CODE (XEXP (opright, 0)) == SUBREG
2992 251 : && known_eq (SUBREG_BYTE (opleft), SUBREG_BYTE (XEXP (opright, 0)))
2993 498 : && GET_MODE_SIZE (int_mode) < GET_MODE_SIZE (inner_mode)
2994 235 : && rtx_equal_p (XEXP (SUBREG_REG (opleft), 0),
2995 235 : SUBREG_REG (XEXP (opright, 0)))
2996 19 : && CONST_INT_P (XEXP (SUBREG_REG (opleft), 1))
2997 19 : && CONST_INT_P (XEXP (opright, 1))
2998 263528775 : && (INTVAL (XEXP (SUBREG_REG (opleft), 1))
2999 19 : + INTVAL (XEXP (opright, 1))
3000 19 : == GET_MODE_PRECISION (int_mode)))
3001 15 : return gen_rtx_ROTATE (int_mode, XEXP (opright, 0),
3002 : XEXP (SUBREG_REG (opleft), 1));
3003 : return NULL_RTX;
3004 : }
3005 :
3006 : /* Returns true if OP0 and OP1 match the pattern (OP (plus (A - 1)) (neg A)),
3007 : and the pattern can be simplified (there are no side effects). */
3008 :
3009 : static bool
3010 38394906 : match_plus_neg_pattern (rtx op0, rtx op1, machine_mode mode)
3011 : {
3012 : /* Remove SUBREG from OP0 and OP1, if needed. */
3013 38394906 : if (GET_CODE (op0) == SUBREG
3014 6857198 : && GET_CODE (op1) == SUBREG
3015 310751 : && subreg_lowpart_p (op0)
3016 38704257 : && subreg_lowpart_p (op1))
3017 : {
3018 309342 : op0 = XEXP (op0, 0);
3019 309342 : op1 = XEXP (op1, 0);
3020 : }
3021 :
3022 : /* Check for the pattern (OP (plus (A - 1)) (neg A)). */
3023 38394906 : if (((GET_CODE (op1) == NEG
3024 3718 : && GET_CODE (op0) == PLUS
3025 2204 : && XEXP (op0, 1) == CONSTM1_RTX (mode))
3026 38394244 : || (GET_CODE (op0) == NEG
3027 80100 : && GET_CODE (op1) == PLUS
3028 0 : && XEXP (op1, 1) == CONSTM1_RTX (mode)))
3029 662 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3030 38394908 : && !side_effects_p (XEXP (op0, 0)))
3031 : return true;
3032 : return false;
3033 : }
3034 :
3035 : /* Check if OP matches the pattern of (subreg (not X)) and the subreg is
3036 : non-paradoxical. */
3037 :
3038 : static bool
3039 72735081 : non_paradoxical_subreg_not_p (rtx op)
3040 : {
3041 72735081 : return GET_CODE (op) == SUBREG
3042 8385987 : && !paradoxical_subreg_p (op)
3043 75664198 : && GET_CODE (SUBREG_REG (op)) == NOT;
3044 : }
3045 :
3046 : /* Convert (binop (subreg (not X)) Y) into (binop (not (subreg X)) Y), or
3047 : (binop X (subreg (not Y))) into (binop X (not (subreg Y))) to expose
3048 : opportunities to combine another binary logical operation with NOT. */
3049 :
3050 : static rtx
3051 36368720 : simplify_with_subreg_not (rtx_code binop, machine_mode mode, rtx op0, rtx op1)
3052 : {
3053 36368720 : rtx opn = NULL_RTX;
3054 36368720 : if (non_paradoxical_subreg_not_p (op0))
3055 : opn = op0;
3056 36366361 : else if (non_paradoxical_subreg_not_p (op1))
3057 : opn = op1;
3058 :
3059 2362 : if (opn == NULL_RTX)
3060 : return NULL_RTX;
3061 :
3062 4724 : rtx new_subreg = simplify_gen_subreg (mode,
3063 : XEXP (SUBREG_REG (opn), 0),
3064 2362 : GET_MODE (SUBREG_REG (opn)),
3065 2362 : SUBREG_BYTE (opn));
3066 :
3067 2362 : if (!new_subreg)
3068 : return NULL_RTX;
3069 :
3070 2307 : rtx new_not = simplify_gen_unary (NOT, mode, new_subreg, mode);
3071 2307 : if (opn == op0)
3072 2304 : return simplify_gen_binary (binop, mode, new_not, op1);
3073 : else
3074 3 : return simplify_gen_binary (binop, mode, op0, new_not);
3075 : }
3076 :
3077 : /* Return TRUE iff NOP is a negated form of OP, or vice-versa. */
3078 : static bool
3079 6655360 : negated_ops_p (rtx nop, rtx op)
3080 : {
3081 : /* Explicit negation. */
3082 6655360 : if (GET_CODE (nop) == NOT
3083 6655360 : && rtx_equal_p (XEXP (nop, 0), op))
3084 : return true;
3085 6651913 : if (GET_CODE (op) == NOT
3086 6651913 : && rtx_equal_p (XEXP (op, 0), nop))
3087 : return true;
3088 :
3089 : /* (~C <r A) is a negated form of (C << A) if C == 1. */
3090 6651234 : if (GET_CODE (op) == ASHIFT
3091 1377587 : && GET_CODE (nop) == ROTATE
3092 0 : && XEXP (op, 0) == CONST1_RTX (GET_MODE (op))
3093 0 : && CONST_INT_P (XEXP (nop, 0))
3094 0 : && INTVAL (XEXP (nop, 0)) == -2
3095 6651234 : && rtx_equal_p (XEXP (op, 1), XEXP (nop, 1)))
3096 : return true;
3097 6651234 : if (GET_CODE (nop) == ASHIFT
3098 167551 : && GET_CODE (op) == ROTATE
3099 0 : && XEXP (nop, 0) == CONST1_RTX (GET_MODE (op))
3100 0 : && CONST_INT_P (XEXP (nop, 0))
3101 0 : && INTVAL (XEXP (nop, 0)) == -2
3102 6651234 : && rtx_equal_p (XEXP (op, 1), XEXP (nop, 1)))
3103 : return true;
3104 :
3105 : /* ??? Should we consider rotations of C and ~C by the same amount? */
3106 :
3107 : return false;
3108 : }
3109 :
3110 : /* Subroutine of simplify_binary_operation. Simplify a binary operation
3111 : CODE with result mode MODE, operating on OP0 and OP1. If OP0 and/or
3112 : OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the
3113 : actual constants. */
3114 :
3115 : rtx
3116 441528315 : simplify_context::simplify_binary_operation_1 (rtx_code code,
3117 : machine_mode mode,
3118 : rtx op0, rtx op1,
3119 : rtx trueop0, rtx trueop1)
3120 : {
3121 441528315 : rtx tem, reversed, elt0, elt1;
3122 441528315 : HOST_WIDE_INT val;
3123 441528315 : scalar_int_mode int_mode, inner_mode;
3124 441528315 : poly_int64 offset;
3125 :
3126 : /* Even if we can't compute a constant result,
3127 : there are some cases worth simplifying. */
3128 :
3129 441528315 : switch (code)
3130 : {
3131 253210128 : case PLUS:
3132 : /* Maybe simplify x + 0 to x. The two expressions are equivalent
3133 : when x is NaN, infinite, or finite and nonzero. They aren't
3134 : when x is -0 and the rounding mode is not towards -infinity,
3135 : since (-0) + 0 is then 0. */
3136 502521095 : if (!HONOR_SIGNED_ZEROS (mode) && !HONOR_SNANS (mode)
3137 502521083 : && trueop1 == CONST0_RTX (mode))
3138 : return op0;
3139 :
3140 : /* ((-a) + b) -> (b - a) and similarly for (a + (-b)). These
3141 : transformations are safe even for IEEE. */
3142 251919413 : if (GET_CODE (op0) == NEG)
3143 26033 : return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
3144 251893380 : else if (GET_CODE (op1) == NEG)
3145 7422 : return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
3146 :
3147 : /* (~a) + 1 -> -a */
3148 251885958 : if (INTEGRAL_MODE_P (mode)
3149 247084639 : && GET_CODE (op0) == NOT
3150 629875 : && trueop1 == const1_rtx)
3151 3722 : return simplify_gen_unary (NEG, mode, XEXP (op0, 0), mode);
3152 :
3153 : /* Handle both-operands-constant cases. We can only add
3154 : CONST_INTs to constants since the sum of relocatable symbols
3155 : can't be handled by most assemblers. Don't add CONST_INT
3156 : to CONST_INT since overflow won't be computed properly if wider
3157 : than HOST_BITS_PER_WIDE_INT. */
3158 :
3159 251882236 : if ((GET_CODE (op0) == CONST
3160 251882236 : || GET_CODE (op0) == SYMBOL_REF
3161 249350180 : || GET_CODE (op0) == LABEL_REF)
3162 251882236 : && poly_int_rtx_p (op1, &offset))
3163 2531082 : return plus_constant (mode, op0, offset);
3164 249351154 : else if ((GET_CODE (op1) == CONST
3165 249351154 : || GET_CODE (op1) == SYMBOL_REF
3166 245609950 : || GET_CODE (op1) == LABEL_REF)
3167 249351154 : && poly_int_rtx_p (op0, &offset))
3168 0 : return plus_constant (mode, op1, offset);
3169 :
3170 : /* See if this is something like X * C - X or vice versa or
3171 : if the multiplication is written as a shift. If so, we can
3172 : distribute and make a new multiply, shift, or maybe just
3173 : have X (if C is 2 in the example above). But don't make
3174 : something more expensive than we had before. */
3175 :
3176 249351154 : if (is_a <scalar_int_mode> (mode, &int_mode))
3177 : {
3178 242459621 : rtx lhs = op0, rhs = op1;
3179 :
3180 242459621 : wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
3181 242459621 : wide_int coeff1 = wi::one (GET_MODE_PRECISION (int_mode));
3182 :
3183 242459621 : if (GET_CODE (lhs) == NEG)
3184 : {
3185 0 : coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3186 0 : lhs = XEXP (lhs, 0);
3187 : }
3188 242459621 : else if (GET_CODE (lhs) == MULT
3189 6725584 : && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
3190 : {
3191 5625228 : coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
3192 5625228 : lhs = XEXP (lhs, 0);
3193 : }
3194 236834393 : else if (GET_CODE (lhs) == ASHIFT
3195 10912978 : && CONST_INT_P (XEXP (lhs, 1))
3196 10841311 : && INTVAL (XEXP (lhs, 1)) >= 0
3197 247675692 : && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
3198 : {
3199 10841299 : coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
3200 21682598 : GET_MODE_PRECISION (int_mode));
3201 10841299 : lhs = XEXP (lhs, 0);
3202 : }
3203 :
3204 242459621 : if (GET_CODE (rhs) == NEG)
3205 : {
3206 0 : coeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3207 0 : rhs = XEXP (rhs, 0);
3208 : }
3209 242459621 : else if (GET_CODE (rhs) == MULT
3210 291755 : && CONST_INT_P (XEXP (rhs, 1)))
3211 : {
3212 180833 : coeff1 = rtx_mode_t (XEXP (rhs, 1), int_mode);
3213 180833 : rhs = XEXP (rhs, 0);
3214 : }
3215 242278788 : else if (GET_CODE (rhs) == ASHIFT
3216 534451 : && CONST_INT_P (XEXP (rhs, 1))
3217 524672 : && INTVAL (XEXP (rhs, 1)) >= 0
3218 242803460 : && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
3219 : {
3220 524672 : coeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
3221 1049344 : GET_MODE_PRECISION (int_mode));
3222 524672 : rhs = XEXP (rhs, 0);
3223 : }
3224 :
3225 : /* Keep PLUS of 2 volatile memory references. */
3226 242459621 : if (rtx_equal_p (lhs, rhs)
3227 242459621 : && (!MEM_P (lhs) || !MEM_VOLATILE_P (lhs)))
3228 : {
3229 770461 : rtx orig = gen_rtx_PLUS (int_mode, op0, op1);
3230 770461 : rtx coeff;
3231 770461 : bool speed = optimize_function_for_speed_p (cfun);
3232 :
3233 770461 : coeff = immed_wide_int_const (coeff0 + coeff1, int_mode);
3234 :
3235 770461 : tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
3236 770461 : return (set_src_cost (tem, int_mode, speed)
3237 770461 : <= set_src_cost (orig, int_mode, speed) ? tem : 0);
3238 : }
3239 :
3240 : /* Optimize (X - 1) * Y + Y to X * Y. */
3241 241689160 : lhs = op0;
3242 241689160 : rhs = op1;
3243 241689160 : if (GET_CODE (op0) == MULT)
3244 : {
3245 6706105 : if (((GET_CODE (XEXP (op0, 0)) == PLUS
3246 279683 : && XEXP (XEXP (op0, 0), 1) == constm1_rtx)
3247 6663268 : || (GET_CODE (XEXP (op0, 0)) == MINUS
3248 35976 : && XEXP (XEXP (op0, 0), 1) == const1_rtx))
3249 6748942 : && rtx_equal_p (XEXP (op0, 1), op1))
3250 78 : lhs = XEXP (XEXP (op0, 0), 0);
3251 6706027 : else if (((GET_CODE (XEXP (op0, 1)) == PLUS
3252 1287 : && XEXP (XEXP (op0, 1), 1) == constm1_rtx)
3253 6705993 : || (GET_CODE (XEXP (op0, 1)) == MINUS
3254 339 : && XEXP (XEXP (op0, 1), 1) == const1_rtx))
3255 6706061 : && rtx_equal_p (XEXP (op0, 0), op1))
3256 0 : lhs = XEXP (XEXP (op0, 1), 0);
3257 : }
3258 234983055 : else if (GET_CODE (op1) == MULT)
3259 : {
3260 137102 : if (((GET_CODE (XEXP (op1, 0)) == PLUS
3261 42 : && XEXP (XEXP (op1, 0), 1) == constm1_rtx)
3262 137097 : || (GET_CODE (XEXP (op1, 0)) == MINUS
3263 27 : && XEXP (XEXP (op1, 0), 1) == const1_rtx))
3264 137107 : && rtx_equal_p (XEXP (op1, 1), op0))
3265 0 : rhs = XEXP (XEXP (op1, 0), 0);
3266 137102 : else if (((GET_CODE (XEXP (op1, 1)) == PLUS
3267 0 : && XEXP (XEXP (op1, 1), 1) == constm1_rtx)
3268 137102 : || (GET_CODE (XEXP (op1, 1)) == MINUS
3269 0 : && XEXP (XEXP (op1, 1), 1) == const1_rtx))
3270 137102 : && rtx_equal_p (XEXP (op1, 0), op0))
3271 0 : rhs = XEXP (XEXP (op1, 1), 0);
3272 : }
3273 241689160 : if (lhs != op0 || rhs != op1)
3274 78 : return simplify_gen_binary (MULT, int_mode, lhs, rhs);
3275 242459621 : }
3276 :
3277 : /* (plus (xor X C1) C2) is (xor X (C1^C2)) if C2 is signbit. */
3278 248580615 : if (CONST_SCALAR_INT_P (op1)
3279 191631611 : && GET_CODE (op0) == XOR
3280 18696 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
3281 248590817 : && mode_signbit_p (mode, op1))
3282 121 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3283 : simplify_gen_binary (XOR, mode, op1,
3284 121 : XEXP (op0, 1)));
3285 :
3286 : /* (plus (xor X C1) C2) is (xor X (C1^C2)) if X is either 0 or 1 and
3287 : 2 * ((X ^ C1) & C2) == 0; based on A + B == A ^ B + 2 * (A & B). */
3288 248580494 : if (CONST_SCALAR_INT_P (op1)
3289 191631490 : && GET_CODE (op0) == XOR
3290 18575 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
3291 10081 : && nonzero_bits (XEXP (op0, 0), mode) == 1
3292 191 : && 2 * (INTVAL (XEXP (op0, 1)) & INTVAL (op1)) == 0
3293 248580494 : && 2 * ((1 ^ INTVAL (XEXP (op0, 1))) & INTVAL (op1)) == 0)
3294 0 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3295 : simplify_gen_binary (XOR, mode, op1,
3296 0 : XEXP (op0, 1)));
3297 :
3298 : /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)). */
3299 248580494 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3300 248578014 : && GET_CODE (op0) == MULT
3301 255650142 : && GET_CODE (XEXP (op0, 0)) == NEG)
3302 : {
3303 5665 : rtx in1, in2;
3304 :
3305 5665 : in1 = XEXP (XEXP (op0, 0), 0);
3306 5665 : in2 = XEXP (op0, 1);
3307 5665 : return simplify_gen_binary (MINUS, mode, op1,
3308 : simplify_gen_binary (MULT, mode,
3309 5665 : in1, in2));
3310 : }
3311 :
3312 : /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
3313 : C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
3314 : is 1. */
3315 248574829 : if (COMPARISON_P (op0)
3316 1438603 : && ((STORE_FLAG_VALUE == -1 && trueop1 == const1_rtx)
3317 1438603 : || (STORE_FLAG_VALUE == 1 && trueop1 == constm1_rtx))
3318 248628327 : && (reversed = reversed_comparison (op0, mode)))
3319 53149 : return
3320 53149 : simplify_gen_unary (NEG, mode, reversed, mode);
3321 :
3322 : /* Convert (plus (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3323 : mode size to (rotate A CX). */
3324 248521680 : if ((tem = simplify_rotate_op (op0, op1, mode)))
3325 : return tem;
3326 :
3327 : /* If one of the operands is a PLUS or a MINUS, see if we can
3328 : simplify this by the associative law.
3329 : Don't use the associative law for floating point.
3330 : The inaccuracy makes it nonassociative,
3331 : and subtle programs can break if operations are associated. */
3332 :
3333 248520210 : if (INTEGRAL_MODE_P (mode)
3334 243718940 : && (plus_minus_operand_p (op0)
3335 210346513 : || plus_minus_operand_p (op1))
3336 34393297 : && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
3337 : return tem;
3338 :
3339 : /* Reassociate floating point addition only when the user
3340 : specifies associative math operations. */
3341 214838756 : if (FLOAT_MODE_P (mode)
3342 4801270 : && flag_associative_math)
3343 : {
3344 902089 : tem = simplify_associative_operation (code, mode, op0, op1);
3345 902089 : if (tem)
3346 : return tem;
3347 : }
3348 :
3349 : /* Handle vector series. */
3350 214825275 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3351 : {
3352 1924986 : tem = simplify_binary_operation_series (code, mode, op0, op1);
3353 1924986 : if (tem)
3354 : return tem;
3355 : }
3356 : break;
3357 :
3358 : case COMPARE:
3359 : break;
3360 :
3361 41788657 : case MINUS:
3362 : /* We can't assume x-x is 0 even with non-IEEE floating point,
3363 : but since it is zero except in very strange circumstances, we
3364 : will treat it as zero with -ffinite-math-only. */
3365 41788657 : if (rtx_equal_p (trueop0, trueop1)
3366 218291 : && ! side_effects_p (op0)
3367 42005687 : && (!FLOAT_MODE_P (mode) || !HONOR_NANS (mode)))
3368 214572 : return CONST0_RTX (mode);
3369 :
3370 : /* Change subtraction from zero into negation. (0 - x) is the
3371 : same as -x when x is NaN, infinite, or finite and nonzero.
3372 : But if the mode has signed zeros, and does not round towards
3373 : -infinity, then 0 - 0 is 0, not -0. */
3374 41574085 : if (!HONOR_SIGNED_ZEROS (mode) && trueop0 == CONST0_RTX (mode))
3375 298739 : return simplify_gen_unary (NEG, mode, op1, mode);
3376 :
3377 : /* (-1 - a) is ~a, unless the expression contains symbolic
3378 : constants, in which case not retaining additions and
3379 : subtractions could cause invalid assembly to be produced. */
3380 41275346 : if (trueop0 == CONSTM1_RTX (mode)
3381 41275346 : && !contains_symbolic_reference_p (op1))
3382 353392 : return simplify_gen_unary (NOT, mode, op1, mode);
3383 :
3384 : /* Subtracting 0 has no effect unless the mode has signalling NaNs,
3385 : or has signed zeros and supports rounding towards -infinity.
3386 : In such a case, 0 - 0 is -0. */
3387 41617519 : if (!(HONOR_SIGNED_ZEROS (mode)
3388 695565 : && HONOR_SIGN_DEPENDENT_ROUNDING (mode))
3389 40920748 : && !HONOR_SNANS (mode)
3390 81842666 : && trueop1 == CONST0_RTX (mode))
3391 : return op0;
3392 :
3393 : /* See if this is something like X * C - X or vice versa or
3394 : if the multiplication is written as a shift. If so, we can
3395 : distribute and make a new multiply, shift, or maybe just
3396 : have X (if C is 2 in the example above). But don't make
3397 : something more expensive than we had before. */
3398 :
3399 39973873 : if (is_a <scalar_int_mode> (mode, &int_mode))
3400 : {
3401 38719137 : rtx lhs = op0, rhs = op1;
3402 :
3403 38719137 : wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
3404 38719137 : wide_int negcoeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3405 :
3406 38719137 : if (GET_CODE (lhs) == NEG)
3407 : {
3408 103664 : coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3409 103664 : lhs = XEXP (lhs, 0);
3410 : }
3411 38615473 : else if (GET_CODE (lhs) == MULT
3412 228277 : && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
3413 : {
3414 81215 : coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
3415 81215 : lhs = XEXP (lhs, 0);
3416 : }
3417 38534258 : else if (GET_CODE (lhs) == ASHIFT
3418 327344 : && CONST_INT_P (XEXP (lhs, 1))
3419 324031 : && INTVAL (XEXP (lhs, 1)) >= 0
3420 38858268 : && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
3421 : {
3422 324010 : coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
3423 648020 : GET_MODE_PRECISION (int_mode));
3424 324010 : lhs = XEXP (lhs, 0);
3425 : }
3426 :
3427 38719137 : if (GET_CODE (rhs) == NEG)
3428 : {
3429 8554 : negcoeff1 = wi::one (GET_MODE_PRECISION (int_mode));
3430 8554 : rhs = XEXP (rhs, 0);
3431 : }
3432 38710583 : else if (GET_CODE (rhs) == MULT
3433 147762 : && CONST_INT_P (XEXP (rhs, 1)))
3434 : {
3435 114430 : negcoeff1 = wi::neg (rtx_mode_t (XEXP (rhs, 1), int_mode));
3436 114430 : rhs = XEXP (rhs, 0);
3437 : }
3438 38596153 : else if (GET_CODE (rhs) == ASHIFT
3439 382724 : && CONST_INT_P (XEXP (rhs, 1))
3440 382215 : && INTVAL (XEXP (rhs, 1)) >= 0
3441 38978368 : && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
3442 : {
3443 382215 : negcoeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
3444 764430 : GET_MODE_PRECISION (int_mode));
3445 382215 : negcoeff1 = -negcoeff1;
3446 382215 : rhs = XEXP (rhs, 0);
3447 : }
3448 :
3449 38719137 : if (rtx_equal_p (lhs, rhs))
3450 : {
3451 99133 : rtx orig = gen_rtx_MINUS (int_mode, op0, op1);
3452 99133 : rtx coeff;
3453 99133 : bool speed = optimize_function_for_speed_p (cfun);
3454 :
3455 99133 : coeff = immed_wide_int_const (coeff0 + negcoeff1, int_mode);
3456 :
3457 99133 : tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
3458 99133 : return (set_src_cost (tem, int_mode, speed)
3459 99133 : <= set_src_cost (orig, int_mode, speed) ? tem : 0);
3460 : }
3461 :
3462 : /* Optimize (X + 1) * Y - Y to X * Y. */
3463 38620004 : lhs = op0;
3464 38620004 : if (GET_CODE (op0) == MULT)
3465 : {
3466 228157 : if (((GET_CODE (XEXP (op0, 0)) == PLUS
3467 4872 : && XEXP (XEXP (op0, 0), 1) == const1_rtx)
3468 226575 : || (GET_CODE (XEXP (op0, 0)) == MINUS
3469 1837 : && XEXP (XEXP (op0, 0), 1) == constm1_rtx))
3470 229739 : && rtx_equal_p (XEXP (op0, 1), op1))
3471 2 : lhs = XEXP (XEXP (op0, 0), 0);
3472 228155 : else if (((GET_CODE (XEXP (op0, 1)) == PLUS
3473 26 : && XEXP (XEXP (op0, 1), 1) == const1_rtx)
3474 228149 : || (GET_CODE (XEXP (op0, 1)) == MINUS
3475 84 : && XEXP (XEXP (op0, 1), 1) == constm1_rtx))
3476 228161 : && rtx_equal_p (XEXP (op0, 0), op1))
3477 0 : lhs = XEXP (XEXP (op0, 1), 0);
3478 : }
3479 38620004 : if (lhs != op0)
3480 2 : return simplify_gen_binary (MULT, int_mode, lhs, op1);
3481 38719137 : }
3482 :
3483 : /* (a - (-b)) -> (a + b). True even for IEEE. */
3484 39874738 : if (GET_CODE (op1) == NEG)
3485 8516 : return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
3486 :
3487 : /* (-x - c) may be simplified as (-c - x). */
3488 39866222 : if (GET_CODE (op0) == NEG
3489 107793 : && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1)))
3490 : {
3491 693 : tem = simplify_unary_operation (NEG, mode, op1, mode);
3492 693 : if (tem)
3493 693 : return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
3494 : }
3495 :
3496 39865529 : if ((GET_CODE (op0) == CONST
3497 39865529 : || GET_CODE (op0) == SYMBOL_REF
3498 34786258 : || GET_CODE (op0) == LABEL_REF)
3499 39865529 : && poly_int_rtx_p (op1, &offset))
3500 50624 : return plus_constant (mode, op0, trunc_int_for_mode (-offset, mode));
3501 :
3502 : /* Don't let a relocatable value get a negative coeff. */
3503 39814905 : if (is_a <scalar_int_mode> (mode)
3504 38560200 : && poly_int_rtx_p (op1)
3505 46817076 : && GET_MODE (op0) != VOIDmode)
3506 7002171 : return simplify_gen_binary (PLUS, mode,
3507 : op0,
3508 7002171 : neg_poly_int_rtx (mode, op1));
3509 :
3510 : /* (x - (x & y)) -> (x & ~y) */
3511 32812734 : if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND)
3512 : {
3513 263004 : if (rtx_equal_p (op0, XEXP (op1, 0)))
3514 : {
3515 498 : tem = simplify_gen_unary (NOT, mode, XEXP (op1, 1),
3516 249 : GET_MODE (XEXP (op1, 1)));
3517 249 : return simplify_gen_binary (AND, mode, op0, tem);
3518 : }
3519 262755 : if (rtx_equal_p (op0, XEXP (op1, 1)))
3520 : {
3521 2248 : tem = simplify_gen_unary (NOT, mode, XEXP (op1, 0),
3522 1124 : GET_MODE (XEXP (op1, 0)));
3523 1124 : return simplify_gen_binary (AND, mode, op0, tem);
3524 : }
3525 : }
3526 :
3527 : /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
3528 : by reversing the comparison code if valid. */
3529 32811361 : if (STORE_FLAG_VALUE == 1
3530 32811361 : && trueop0 == const1_rtx
3531 1112991 : && COMPARISON_P (op1)
3532 32916802 : && (reversed = reversed_comparison (op1, mode)))
3533 : return reversed;
3534 :
3535 : /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A). */
3536 32705943 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3537 32704536 : && GET_CODE (op1) == MULT
3538 32953146 : && GET_CODE (XEXP (op1, 0)) == NEG)
3539 : {
3540 165 : rtx in1, in2;
3541 :
3542 165 : in1 = XEXP (XEXP (op1, 0), 0);
3543 165 : in2 = XEXP (op1, 1);
3544 165 : return simplify_gen_binary (PLUS, mode,
3545 : simplify_gen_binary (MULT, mode,
3546 : in1, in2),
3547 165 : op0);
3548 : }
3549 :
3550 : /* Canonicalize (minus (neg A) (mult B C)) to
3551 : (minus (mult (neg B) C) A). */
3552 32705778 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3553 32704371 : && GET_CODE (op1) == MULT
3554 32952816 : && GET_CODE (op0) == NEG)
3555 : {
3556 655 : rtx in1, in2;
3557 :
3558 655 : in1 = simplify_gen_unary (NEG, mode, XEXP (op1, 0), mode);
3559 655 : in2 = XEXP (op1, 1);
3560 655 : return simplify_gen_binary (MINUS, mode,
3561 : simplify_gen_binary (MULT, mode,
3562 : in1, in2),
3563 655 : XEXP (op0, 0));
3564 : }
3565 :
3566 : /* If one of the operands is a PLUS or a MINUS, see if we can
3567 : simplify this by the associative law. This will, for example,
3568 : canonicalize (minus A (plus B C)) to (minus (minus A B) C).
3569 : Don't use the associative law for floating point.
3570 : The inaccuracy makes it nonassociative,
3571 : and subtle programs can break if operations are associated. */
3572 :
3573 32705123 : if (INTEGRAL_MODE_P (mode)
3574 31889971 : && (plus_minus_operand_p (op0)
3575 29251936 : || plus_minus_operand_p (op1))
3576 3828810 : && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
3577 : return tem;
3578 :
3579 : /* Handle vector series. */
3580 29011051 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3581 : {
3582 418739 : tem = simplify_binary_operation_series (code, mode, op0, op1);
3583 418739 : if (tem)
3584 : return tem;
3585 : }
3586 : break;
3587 :
3588 12119740 : case MULT:
3589 12119740 : if (trueop1 == constm1_rtx)
3590 33001 : return simplify_gen_unary (NEG, mode, op0, mode);
3591 :
3592 12086739 : if (GET_CODE (op0) == NEG)
3593 : {
3594 33121 : rtx temp = simplify_unary_operation (NEG, mode, op1, mode);
3595 : /* If op1 is a MULT as well and simplify_unary_operation
3596 : just moved the NEG to the second operand, simplify_gen_binary
3597 : below could through simplify_associative_operation move
3598 : the NEG around again and recurse endlessly. */
3599 33121 : if (temp
3600 1537 : && GET_CODE (op1) == MULT
3601 0 : && GET_CODE (temp) == MULT
3602 0 : && XEXP (op1, 0) == XEXP (temp, 0)
3603 0 : && GET_CODE (XEXP (temp, 1)) == NEG
3604 0 : && XEXP (op1, 1) == XEXP (XEXP (temp, 1), 0))
3605 : temp = NULL_RTX;
3606 : if (temp)
3607 1537 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp);
3608 : }
3609 12085202 : if (GET_CODE (op1) == NEG)
3610 : {
3611 881 : rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
3612 : /* If op0 is a MULT as well and simplify_unary_operation
3613 : just moved the NEG to the second operand, simplify_gen_binary
3614 : below could through simplify_associative_operation move
3615 : the NEG around again and recurse endlessly. */
3616 881 : if (temp
3617 421 : && GET_CODE (op0) == MULT
3618 300 : && GET_CODE (temp) == MULT
3619 300 : && XEXP (op0, 0) == XEXP (temp, 0)
3620 6 : && GET_CODE (XEXP (temp, 1)) == NEG
3621 5 : && XEXP (op0, 1) == XEXP (XEXP (temp, 1), 0))
3622 : temp = NULL_RTX;
3623 : if (temp)
3624 416 : return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
3625 : }
3626 :
3627 : /* Maybe simplify x * 0 to 0. The reduction is not valid if
3628 : x is NaN, since x * 0 is then also NaN. Nor is it valid
3629 : when the mode has signed zeros, since multiplying a negative
3630 : number by 0 will give -0, not 0. */
3631 12084786 : if (!HONOR_NANS (mode)
3632 11131568 : && !HONOR_SIGNED_ZEROS (mode)
3633 11131125 : && trueop1 == CONST0_RTX (mode)
3634 12128010 : && ! side_effects_p (op0))
3635 : return op1;
3636 :
3637 : /* In IEEE floating point, x*1 is not equivalent to x for
3638 : signalling NaNs. */
3639 12042825 : if (!HONOR_SNANS (mode)
3640 12042825 : && trueop1 == CONST1_RTX (mode))
3641 : return op0;
3642 :
3643 : /* Convert multiply by constant power of two into shift. */
3644 11524571 : if (mem_depth == 0 && CONST_SCALAR_INT_P (trueop1))
3645 : {
3646 6247986 : val = wi::exact_log2 (rtx_mode_t (trueop1, mode));
3647 6247986 : if (val >= 0)
3648 3003967 : return simplify_gen_binary (ASHIFT, mode, op0,
3649 3003967 : gen_int_shift_amount (mode, val));
3650 : }
3651 :
3652 : /* x*2 is x+x and x*(-1) is -x */
3653 8520604 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
3654 166385 : && SCALAR_FLOAT_MODE_P (GET_MODE (trueop1))
3655 166385 : && !DECIMAL_FLOAT_MODE_P (GET_MODE (trueop1))
3656 166101 : && GET_MODE (op0) == mode)
3657 : {
3658 166101 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
3659 :
3660 166101 : if (real_equal (d1, &dconst2))
3661 615 : return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
3662 :
3663 165486 : if (!HONOR_SNANS (mode)
3664 165486 : && real_equal (d1, &dconstm1))
3665 24 : return simplify_gen_unary (NEG, mode, op0, mode);
3666 : }
3667 :
3668 : /* Optimize -x * -x as x * x. */
3669 8519965 : if (FLOAT_MODE_P (mode)
3670 1371084 : && GET_CODE (op0) == NEG
3671 7876 : && GET_CODE (op1) == NEG
3672 0 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3673 0 : && !side_effects_p (XEXP (op0, 0)))
3674 0 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3675 :
3676 : /* Likewise, optimize abs(x) * abs(x) as x * x. */
3677 8519965 : if (SCALAR_FLOAT_MODE_P (mode)
3678 1083972 : && GET_CODE (op0) == ABS
3679 1329 : && GET_CODE (op1) == ABS
3680 0 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3681 8519965 : && !side_effects_p (XEXP (op0, 0)))
3682 0 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3683 :
3684 : /* Reassociate multiplication, but for floating point MULTs
3685 : only when the user specifies unsafe math optimizations. */
3686 8519965 : if (! FLOAT_MODE_P (mode)
3687 1371084 : || flag_unsafe_math_optimizations)
3688 : {
3689 7567857 : tem = simplify_associative_operation (code, mode, op0, op1);
3690 7567857 : if (tem)
3691 : return tem;
3692 : }
3693 : break;
3694 :
3695 14854314 : case IOR:
3696 14854314 : if (trueop1 == CONST0_RTX (mode))
3697 : return op0;
3698 14072182 : if (INTEGRAL_MODE_P (mode)
3699 13797448 : && trueop1 == CONSTM1_RTX (mode)
3700 9620 : && !side_effects_p (op0))
3701 : return op1;
3702 14062562 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
3703 : return op0;
3704 : /* A | (~A) -> -1 */
3705 75237 : if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
3706 14043717 : || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
3707 11 : && ! side_effects_p (op0)
3708 14043739 : && GET_MODE_CLASS (mode) != MODE_CC)
3709 11 : return CONSTM1_RTX (mode);
3710 :
3711 : /* IOR of two single bit bitfields extracted from the same object.
3712 : Bitfields are represented as an AND based extraction */
3713 14043717 : if (GET_CODE (op0) == AND
3714 4004082 : && GET_CODE (op1) == AND
3715 : /* Verify both AND operands are logical right shifts. */
3716 312648 : && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
3717 5161 : && GET_CODE (XEXP (op1, 0)) == LSHIFTRT
3718 : /* Verify both bitfields are extracted from the same object. */
3719 54 : && XEXP (XEXP (op0, 0), 0) == XEXP (XEXP (op1, 0), 0)
3720 : /* Verify both fields are a single bit (could be generalized). */
3721 54 : && XEXP (op0, 1) == CONST1_RTX (mode)
3722 0 : && XEXP (op1, 1) == CONST1_RTX (mode)
3723 : /* Verify bit positions (for cases with variable bit position). */
3724 0 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
3725 0 : && CONST_INT_P (XEXP (XEXP (op1, 0), 1)))
3726 : {
3727 0 : unsigned HOST_WIDE_INT bitpos1 = INTVAL (XEXP (XEXP (op0, 0), 1));
3728 0 : unsigned HOST_WIDE_INT bitpos2 = INTVAL (XEXP (XEXP (op1, 0), 1));
3729 0 : unsigned HOST_WIDE_INT mask
3730 0 : = (HOST_WIDE_INT_1U << bitpos1) | (HOST_WIDE_INT_1U << bitpos2);
3731 :
3732 0 : rtx m = GEN_INT (mask);
3733 0 : rtx t = gen_rtx_AND (mode, XEXP (XEXP (op0, 0), 0), m);
3734 0 : t = gen_rtx_NE (mode, t, CONST0_RTX (mode));
3735 0 : return t;
3736 : }
3737 :
3738 : /* IOR of multiple single bit bitfields extracted from the same object
3739 : (building on previous case).
3740 : First bitfield is represented as an AND based extraction, as done
3741 : above. Second represented as NE based extraction, from
3742 : output above. */
3743 14043717 : if (GET_CODE (op0) == AND
3744 4004082 : && GET_CODE (op1) == NE
3745 : /* Verify AND operand is logical right shift. */
3746 4638 : && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
3747 : /* Verify NE operand is an AND (based on output above). */
3748 86 : && GET_CODE (XEXP (op1, 0)) == AND
3749 : /* Verify both bitfields are extracted from the same object. */
3750 0 : && XEXP (XEXP (op0, 0), 0) == XEXP (XEXP (op1, 0), 0)
3751 : /* Verify masking is with a single bit and that we have a NE 0
3752 : comparison for the other operand. */
3753 0 : && XEXP (op0, 1) == CONST1_RTX (mode)
3754 0 : && XEXP (op1, 1) == CONST0_RTX (mode)
3755 : /* Verify bit position. */
3756 0 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
3757 : {
3758 0 : unsigned HOST_WIDE_INT bitpos1 = INTVAL (XEXP (XEXP (op0, 0), 1));
3759 0 : unsigned HOST_WIDE_INT mask
3760 0 : = (HOST_WIDE_INT_1U << bitpos1) | INTVAL (XEXP (XEXP (op1, 0), 1));
3761 :
3762 0 : rtx m = GEN_INT (mask);
3763 0 : rtx t = gen_rtx_AND (mode, XEXP (XEXP (op0, 0), 0), m);
3764 0 : t = gen_rtx_NE (mode, t, CONST0_RTX (mode));
3765 0 : return t;
3766 : }
3767 :
3768 : /* Convert (ior (plus (A - 1)) (neg A)) to -1. */
3769 14043717 : if (match_plus_neg_pattern (op0, op1, mode))
3770 0 : return CONSTM1_RTX (mode);
3771 :
3772 : /* (ior A C) is C if all bits of A that might be nonzero are on in C. */
3773 14043717 : if (CONST_INT_P (op1)
3774 3444913 : && HWI_COMPUTABLE_MODE_P (mode)
3775 3387389 : && (nonzero_bits (op0, mode) & ~UINTVAL (op1)) == 0
3776 14409571 : && !side_effects_p (op0))
3777 : return op1;
3778 :
3779 : /* Canonicalize (X & C1) | C2. */
3780 13677863 : if (GET_CODE (op0) == AND
3781 3995487 : && CONST_INT_P (trueop1)
3782 655712 : && CONST_INT_P (XEXP (op0, 1)))
3783 : {
3784 497061 : HOST_WIDE_INT mask = GET_MODE_MASK (mode);
3785 497061 : HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
3786 497061 : HOST_WIDE_INT c2 = INTVAL (trueop1);
3787 :
3788 : /* If (C1&C2) == C1, then (X&C1)|C2 becomes C2. */
3789 497061 : if ((c1 & c2) == c1
3790 497061 : && !side_effects_p (XEXP (op0, 0)))
3791 : return trueop1;
3792 :
3793 : /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2. */
3794 497041 : if (((c1|c2) & mask) == mask)
3795 70814 : return simplify_gen_binary (IOR, mode, XEXP (op0, 0), op1);
3796 :
3797 : /* If (C1|C2) has a single bit clear, then adjust C1 so that
3798 : when split it'll match a single bit clear style insn.
3799 :
3800 : This could have been done with a target dependent splitter, but
3801 : then every target with single bit manipulation insns would need
3802 : to implement such splitters. */
3803 426227 : if (exact_log2 (~(c1 | c2)) >= 0)
3804 : {
3805 58701 : rtx temp = gen_rtx_AND (mode, XEXP (op0, 0), GEN_INT (c1 | c2));
3806 58701 : temp = gen_rtx_IOR (mode, temp, trueop1);
3807 58701 : return temp;
3808 : }
3809 : }
3810 :
3811 : /* Convert (A & B) | A to A. */
3812 13548328 : if (GET_CODE (op0) == AND
3813 3865952 : && (rtx_equal_p (XEXP (op0, 0), op1)
3814 3865841 : || rtx_equal_p (XEXP (op0, 1), op1))
3815 3749 : && ! side_effects_p (XEXP (op0, 0))
3816 13552077 : && ! side_effects_p (XEXP (op0, 1)))
3817 : return op1;
3818 :
3819 : /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3820 : mode size to (rotate A CX). */
3821 13544579 : tem = simplify_rotate_op (op0, op1, mode);
3822 13544579 : if (tem)
3823 : return tem;
3824 :
3825 : /* If OP0 is (ashiftrt (plus ...) C), it might actually be
3826 : a (sign_extend (plus ...)). Then check if OP1 is a CONST_INT and
3827 : the PLUS does not affect any of the bits in OP1: then we can do
3828 : the IOR as a PLUS and we can associate. This is valid if OP1
3829 : can be safely shifted left C bits. */
3830 13542052 : if (CONST_INT_P (trueop1) && GET_CODE (op0) == ASHIFTRT
3831 6273 : && GET_CODE (XEXP (op0, 0)) == PLUS
3832 141 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
3833 87 : && CONST_INT_P (XEXP (op0, 1))
3834 87 : && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
3835 : {
3836 87 : int count = INTVAL (XEXP (op0, 1));
3837 87 : HOST_WIDE_INT mask = UINTVAL (trueop1) << count;
3838 :
3839 87 : if (mask >> count == INTVAL (trueop1)
3840 80 : && trunc_int_for_mode (mask, mode) == mask
3841 154 : && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
3842 0 : return simplify_gen_binary (ASHIFTRT, mode,
3843 : plus_constant (mode, XEXP (op0, 0),
3844 0 : mask),
3845 : XEXP (op0, 1));
3846 : }
3847 :
3848 : /* The following happens with bitfield merging.
3849 : (X & C) | ((X | Y) & ~C) -> X | (Y & ~C) */
3850 13542052 : if (GET_CODE (op0) == AND
3851 3862203 : && GET_CODE (op1) == AND
3852 312648 : && CONST_INT_P (XEXP (op0, 1))
3853 144138 : && CONST_INT_P (XEXP (op1, 1))
3854 138726 : && (INTVAL (XEXP (op0, 1))
3855 138726 : == ~INTVAL (XEXP (op1, 1))))
3856 : {
3857 : /* The IOR may be on both sides. */
3858 32095 : rtx top0 = NULL_RTX, top1 = NULL_RTX;
3859 32095 : if (GET_CODE (XEXP (op1, 0)) == IOR)
3860 : top0 = op0, top1 = op1;
3861 32039 : else if (GET_CODE (XEXP (op0, 0)) == IOR)
3862 3 : top0 = op1, top1 = op0;
3863 32095 : if (top0 && top1)
3864 : {
3865 : /* X may be on either side of the inner IOR. */
3866 59 : rtx tem = NULL_RTX;
3867 59 : if (rtx_equal_p (XEXP (top0, 0),
3868 59 : XEXP (XEXP (top1, 0), 0)))
3869 42 : tem = XEXP (XEXP (top1, 0), 1);
3870 17 : else if (rtx_equal_p (XEXP (top0, 0),
3871 17 : XEXP (XEXP (top1, 0), 1)))
3872 8 : tem = XEXP (XEXP (top1, 0), 0);
3873 50 : if (tem)
3874 50 : return simplify_gen_binary (IOR, mode, XEXP (top0, 0),
3875 : simplify_gen_binary
3876 50 : (AND, mode, tem, XEXP (top1, 1)));
3877 : }
3878 : }
3879 :
3880 : /* Convert (ior (and A C) (and B C)) into (and (ior A B) C). */
3881 13542002 : if (GET_CODE (op0) == GET_CODE (op1)
3882 3395880 : && (GET_CODE (op0) == AND
3883 : || GET_CODE (op0) == IOR
3884 3395880 : || GET_CODE (op0) == LSHIFTRT
3885 3082301 : || GET_CODE (op0) == ASHIFTRT
3886 3082171 : || GET_CODE (op0) == ASHIFT
3887 3065099 : || GET_CODE (op0) == ROTATE
3888 3065099 : || GET_CODE (op0) == ROTATERT))
3889 : {
3890 330781 : tem = simplify_distributive_operation (code, mode, op0, op1);
3891 330781 : if (tem)
3892 : return tem;
3893 : }
3894 :
3895 : /* Convert (ior (and (not A) B) A) into A | B. */
3896 13450705 : if (GET_CODE (op0) == AND
3897 13450705 : && negated_ops_p (XEXP (op0, 0), op1))
3898 4106 : return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
3899 :
3900 13446599 : tem = simplify_with_subreg_not (code, mode, op0, op1);
3901 13446599 : if (tem)
3902 : return tem;
3903 :
3904 13446594 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3905 13446594 : if (tem)
3906 : return tem;
3907 :
3908 13446561 : tem = simplify_associative_operation (code, mode, op0, op1);
3909 13446561 : if (tem)
3910 : return tem;
3911 :
3912 13176238 : tem = simplify_logical_relational_operation (code, mode, op0, op1);
3913 13176238 : if (tem)
3914 : return tem;
3915 : break;
3916 :
3917 1737694 : case XOR:
3918 1737694 : if (trueop1 == CONST0_RTX (mode))
3919 : return op0;
3920 1681652 : if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
3921 24753 : return simplify_gen_unary (NOT, mode, op0, mode);
3922 1656899 : if (rtx_equal_p (trueop0, trueop1)
3923 2407 : && ! side_effects_p (op0)
3924 1659302 : && GET_MODE_CLASS (mode) != MODE_CC)
3925 2403 : return CONST0_RTX (mode);
3926 :
3927 : /* Canonicalize XOR of the most significant bit to PLUS. */
3928 1654496 : if (CONST_SCALAR_INT_P (op1)
3929 1654496 : && mode_signbit_p (mode, op1))
3930 40514 : return simplify_gen_binary (PLUS, mode, op0, op1);
3931 : /* (xor (plus X C1) C2) is (xor X (C1^C2)) if C1 is signbit. */
3932 1613982 : if (CONST_SCALAR_INT_P (op1)
3933 487131 : && GET_CODE (op0) == PLUS
3934 2512 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
3935 1615578 : && mode_signbit_p (mode, XEXP (op0, 1)))
3936 189 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3937 : simplify_gen_binary (XOR, mode, op1,
3938 189 : XEXP (op0, 1)));
3939 :
3940 : /* If we are XORing two things that have no bits in common,
3941 : convert them into an IOR. This helps to detect rotation encoded
3942 : using those methods and possibly other simplifications. */
3943 :
3944 1613793 : if (HWI_COMPUTABLE_MODE_P (mode)
3945 1321937 : && (nonzero_bits (op0, mode)
3946 1321937 : & nonzero_bits (op1, mode)) == 0)
3947 10691 : return (simplify_gen_binary (IOR, mode, op0, op1));
3948 :
3949 : /* Convert (xor (plus (A - 1)) (neg A)) to -1. */
3950 1603102 : if (match_plus_neg_pattern (op0, op1, mode))
3951 0 : return CONSTM1_RTX (mode);
3952 :
3953 : /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
3954 : Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
3955 : (NOT y). */
3956 1603102 : {
3957 1603102 : int num_negated = 0;
3958 :
3959 1603102 : if (GET_CODE (op0) == NOT)
3960 949 : num_negated++, op0 = XEXP (op0, 0);
3961 1603102 : if (GET_CODE (op1) == NOT)
3962 0 : num_negated++, op1 = XEXP (op1, 0);
3963 :
3964 0 : if (num_negated == 2)
3965 0 : return simplify_gen_binary (XOR, mode, op0, op1);
3966 1603102 : else if (num_negated == 1)
3967 949 : return simplify_gen_unary (NOT, mode,
3968 : simplify_gen_binary (XOR, mode, op0, op1),
3969 949 : mode);
3970 : }
3971 :
3972 : /* Convert (xor (and A B) B) to (and (not A) B). The latter may
3973 : correspond to a machine insn or result in further simplifications
3974 : if B is a constant. */
3975 :
3976 1602153 : if (GET_CODE (op0) == AND
3977 173477 : && rtx_equal_p (XEXP (op0, 1), op1)
3978 1626701 : && ! side_effects_p (op1))
3979 24548 : return simplify_gen_binary (AND, mode,
3980 : simplify_gen_unary (NOT, mode,
3981 : XEXP (op0, 0), mode),
3982 24548 : op1);
3983 :
3984 1577605 : else if (GET_CODE (op0) == AND
3985 148929 : && rtx_equal_p (XEXP (op0, 0), op1)
3986 1578844 : && ! side_effects_p (op1))
3987 1239 : return simplify_gen_binary (AND, mode,
3988 : simplify_gen_unary (NOT, mode,
3989 : XEXP (op0, 1), mode),
3990 1239 : op1);
3991 :
3992 : /* Given (xor (ior (xor A B) C) D), where B, C and D are
3993 : constants, simplify to (xor (ior A C) (B&~C)^D), canceling
3994 : out bits inverted twice and not set by C. Similarly, given
3995 : (xor (and (xor A B) C) D), simplify without inverting C in
3996 : the xor operand: (xor (and A C) (B&C)^D).
3997 : */
3998 1576366 : else if ((GET_CODE (op0) == IOR || GET_CODE (op0) == AND)
3999 169360 : && GET_CODE (XEXP (op0, 0)) == XOR
4000 7292 : && CONST_INT_P (op1)
4001 331 : && CONST_INT_P (XEXP (op0, 1))
4002 286 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
4003 : {
4004 38 : enum rtx_code op = GET_CODE (op0);
4005 38 : rtx a = XEXP (XEXP (op0, 0), 0);
4006 38 : rtx b = XEXP (XEXP (op0, 0), 1);
4007 38 : rtx c = XEXP (op0, 1);
4008 38 : rtx d = op1;
4009 38 : HOST_WIDE_INT bval = INTVAL (b);
4010 38 : HOST_WIDE_INT cval = INTVAL (c);
4011 38 : HOST_WIDE_INT dval = INTVAL (d);
4012 38 : HOST_WIDE_INT xcval;
4013 :
4014 38 : if (op == IOR)
4015 8 : xcval = ~cval;
4016 : else
4017 : xcval = cval;
4018 :
4019 38 : return simplify_gen_binary (XOR, mode,
4020 : simplify_gen_binary (op, mode, a, c),
4021 38 : gen_int_mode ((bval & xcval) ^ dval,
4022 : mode));
4023 : }
4024 :
4025 : /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P),
4026 : we can transform like this:
4027 : (A&B)^C == ~(A&B)&C | ~C&(A&B)
4028 : == (~A|~B)&C | ~C&(A&B) * DeMorgan's Law
4029 : == ~A&C | ~B&C | A&(~C&B) * Distribute and re-order
4030 : Attempt a few simplifications when B and C are both constants. */
4031 1576328 : if (GET_CODE (op0) == AND
4032 147660 : && CONST_INT_P (op1)
4033 13338 : && CONST_INT_P (XEXP (op0, 1)))
4034 : {
4035 11606 : rtx a = XEXP (op0, 0);
4036 11606 : rtx b = XEXP (op0, 1);
4037 11606 : rtx c = op1;
4038 11606 : HOST_WIDE_INT bval = INTVAL (b);
4039 11606 : HOST_WIDE_INT cval = INTVAL (c);
4040 :
4041 : /* Instead of computing ~A&C, we compute its negated value,
4042 : ~(A|~C). If it yields -1, ~A&C is zero, so we can
4043 : optimize for sure. If it does not simplify, we still try
4044 : to compute ~A&C below, but since that always allocates
4045 : RTL, we don't try that before committing to returning a
4046 : simplified expression. */
4047 11606 : rtx n_na_c = simplify_binary_operation (IOR, mode, a,
4048 : GEN_INT (~cval));
4049 :
4050 11606 : if ((~cval & bval) == 0)
4051 : {
4052 518 : rtx na_c = NULL_RTX;
4053 518 : if (n_na_c)
4054 0 : na_c = simplify_gen_unary (NOT, mode, n_na_c, mode);
4055 : else
4056 : {
4057 : /* If ~A does not simplify, don't bother: we don't
4058 : want to simplify 2 operations into 3, and if na_c
4059 : were to simplify with na, n_na_c would have
4060 : simplified as well. */
4061 518 : rtx na = simplify_unary_operation (NOT, mode, a, mode);
4062 518 : if (na)
4063 0 : na_c = simplify_gen_binary (AND, mode, na, c);
4064 : }
4065 :
4066 : /* Try to simplify ~A&C | ~B&C. */
4067 0 : if (na_c != NULL_RTX)
4068 0 : return simplify_gen_binary (IOR, mode, na_c,
4069 0 : gen_int_mode (~bval & cval, mode));
4070 : }
4071 : else
4072 : {
4073 : /* If ~A&C is zero, simplify A&(~C&B) | ~B&C. */
4074 11088 : if (n_na_c == CONSTM1_RTX (mode))
4075 : {
4076 0 : rtx a_nc_b = simplify_gen_binary (AND, mode, a,
4077 0 : gen_int_mode (~cval & bval,
4078 : mode));
4079 0 : return simplify_gen_binary (IOR, mode, a_nc_b,
4080 0 : gen_int_mode (~bval & cval,
4081 : mode));
4082 : }
4083 : }
4084 : }
4085 :
4086 : /* If we have (xor (and (xor A B) C) A) with C a constant we can instead
4087 : do (ior (and A ~C) (and B C)) which is a machine instruction on some
4088 : machines, and also has shorter instruction path length. */
4089 1576328 : if (GET_CODE (op0) == AND
4090 147660 : && GET_CODE (XEXP (op0, 0)) == XOR
4091 6807 : && CONST_INT_P (XEXP (op0, 1))
4092 1579864 : && rtx_equal_p (XEXP (XEXP (op0, 0), 0), trueop1))
4093 : {
4094 7 : rtx a = trueop1;
4095 7 : rtx b = XEXP (XEXP (op0, 0), 1);
4096 7 : rtx c = XEXP (op0, 1);
4097 7 : rtx nc = simplify_gen_unary (NOT, mode, c, mode);
4098 7 : rtx a_nc = simplify_gen_binary (AND, mode, a, nc);
4099 7 : rtx bc = simplify_gen_binary (AND, mode, b, c);
4100 7 : return simplify_gen_binary (IOR, mode, a_nc, bc);
4101 : }
4102 : /* Similarly, (xor (and (xor A B) C) B) as (ior (and A C) (and B ~C)) */
4103 1576321 : else if (GET_CODE (op0) == AND
4104 147653 : && GET_CODE (XEXP (op0, 0)) == XOR
4105 6800 : && CONST_INT_P (XEXP (op0, 1))
4106 1579850 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), trueop1))
4107 : {
4108 8 : rtx a = XEXP (XEXP (op0, 0), 0);
4109 8 : rtx b = trueop1;
4110 8 : rtx c = XEXP (op0, 1);
4111 8 : rtx nc = simplify_gen_unary (NOT, mode, c, mode);
4112 8 : rtx b_nc = simplify_gen_binary (AND, mode, b, nc);
4113 8 : rtx ac = simplify_gen_binary (AND, mode, a, c);
4114 8 : return simplify_gen_binary (IOR, mode, ac, b_nc);
4115 : }
4116 :
4117 : /* (xor (comparison foo bar) (const_int 1)) can become the reversed
4118 : comparison if STORE_FLAG_VALUE is 1. */
4119 1576313 : if (STORE_FLAG_VALUE == 1
4120 1576313 : && trueop1 == const1_rtx
4121 201442 : && COMPARISON_P (op0)
4122 1582494 : && (reversed = reversed_comparison (op0, mode)))
4123 : return reversed;
4124 :
4125 : /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
4126 : is (lt foo (const_int 0)), so we can perform the above
4127 : simplification if STORE_FLAG_VALUE is 1. */
4128 :
4129 1570140 : if (is_a <scalar_int_mode> (mode, &int_mode)
4130 : && STORE_FLAG_VALUE == 1
4131 1282449 : && trueop1 == const1_rtx
4132 195269 : && GET_CODE (op0) == LSHIFTRT
4133 35194 : && CONST_INT_P (XEXP (op0, 1))
4134 35194 : && INTVAL (XEXP (op0, 1)) == GET_MODE_PRECISION (int_mode) - 1)
4135 34299 : return gen_rtx_GE (int_mode, XEXP (op0, 0), const0_rtx);
4136 :
4137 : /* (xor (comparison foo bar) (const_int sign-bit))
4138 : when STORE_FLAG_VALUE is the sign bit. */
4139 1535841 : if (is_a <scalar_int_mode> (mode, &int_mode)
4140 1248150 : && val_signbit_p (int_mode, STORE_FLAG_VALUE)
4141 0 : && trueop1 == const_true_rtx
4142 0 : && COMPARISON_P (op0)
4143 0 : && (reversed = reversed_comparison (op0, int_mode)))
4144 : return reversed;
4145 :
4146 : /* Convert (xor (and A C) (and B C)) into (and (xor A B) C). */
4147 1535841 : if (GET_CODE (op0) == GET_CODE (op1)
4148 531027 : && (GET_CODE (op0) == AND
4149 531027 : || GET_CODE (op0) == LSHIFTRT
4150 459430 : || GET_CODE (op0) == ASHIFTRT
4151 459330 : || GET_CODE (op0) == ASHIFT
4152 459196 : || GET_CODE (op0) == ROTATE
4153 459088 : || GET_CODE (op0) == ROTATERT))
4154 : {
4155 72473 : tem = simplify_distributive_operation (code, mode, op0, op1);
4156 72473 : if (tem)
4157 : return tem;
4158 : }
4159 :
4160 : /* Convert (xor (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
4161 : mode size to (rotate A CX). */
4162 1467878 : tem = simplify_rotate_op (op0, op1, mode);
4163 1467878 : if (tem)
4164 : return tem;
4165 :
4166 : /* Convert (xor (and (not A) B) A) into A | B. */
4167 1466498 : if (GET_CODE (op0) == AND
4168 1466498 : && negated_ops_p (XEXP (op0, 0), op1))
4169 1 : return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
4170 :
4171 : /* Convert (xor (and (rotate (~1) A) B) (ashift 1 A))
4172 : into B | (1 << A). */
4173 1466497 : if (SHIFT_COUNT_TRUNCATED
4174 : && GET_CODE (op0) == AND
4175 : && GET_CODE (XEXP (op0, 0)) == ROTATE
4176 : && CONST_INT_P (XEXP (XEXP (op0, 0), 0))
4177 : && INTVAL (XEXP (XEXP (op0, 0), 0)) == -2
4178 : && GET_CODE (op1) == ASHIFT
4179 : && CONST_INT_P (XEXP (op1, 0))
4180 : && INTVAL (XEXP (op1, 0)) == 1
4181 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), XEXP (op1, 1))
4182 : && !side_effects_p (XEXP (op1, 1)))
4183 : return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
4184 :
4185 1466497 : tem = simplify_with_subreg_not (code, mode, op0, op1);
4186 1466497 : if (tem)
4187 : return tem;
4188 :
4189 1466496 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
4190 1466496 : if (tem)
4191 : return tem;
4192 :
4193 1466496 : tem = simplify_associative_operation (code, mode, op0, op1);
4194 1466496 : if (tem)
4195 : return tem;
4196 : break;
4197 :
4198 23794356 : case AND:
4199 23794356 : if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
4200 : return trueop1;
4201 23548971 : if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
4202 : return op0;
4203 23168422 : if (HWI_COMPUTABLE_MODE_P (mode))
4204 : {
4205 : /* When WORD_REGISTER_OPERATIONS is true, we need to know the
4206 : nonzero bits in WORD_MODE rather than MODE. */
4207 20313671 : scalar_int_mode tmode = as_a <scalar_int_mode> (mode);
4208 20313671 : if (WORD_REGISTER_OPERATIONS
4209 : && GET_MODE_BITSIZE (tmode) < BITS_PER_WORD)
4210 : tmode = word_mode;
4211 20313671 : HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, tmode);
4212 20313671 : HOST_WIDE_INT nzop1;
4213 20313671 : if (CONST_INT_P (trueop1))
4214 : {
4215 17288028 : HOST_WIDE_INT val1 = INTVAL (trueop1);
4216 : /* If we are turning off bits already known off in OP0, we need
4217 : not do an AND. */
4218 17288028 : if ((nzop0 & ~val1) == 0)
4219 413024 : return op0;
4220 :
4221 : /* Canonicalize (and (subreg (lshiftrt X shift)) mask) into
4222 : (and (lshiftrt (subreg X) shift) mask).
4223 :
4224 : Keeps shift and AND in the same mode, improving recognition.
4225 : Only applied when subreg is a lowpart, shift is valid,
4226 : and no precision is lost. */
4227 16957971 : if (SUBREG_P (op0)
4228 5883269 : && subreg_lowpart_p (op0)
4229 5867362 : && !paradoxical_subreg_p (op0)
4230 937721 : && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
4231 : /* simplify_subreg asserts the object being accessed is not
4232 : VOIDmode or BLKmode. We may have a REG_EQUAL note which
4233 : is not simplified and the source operand is a constant,
4234 : and thus VOIDmode. Guard against that. */
4235 115249 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) != VOIDmode
4236 115199 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) != BLKmode
4237 115199 : && !CONST_INT_P (XEXP (XEXP (op0, 0), 0))
4238 115199 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
4239 95459 : && INTVAL (XEXP (XEXP (op0, 0), 1)) >= 0
4240 95459 : && INTVAL (XEXP (XEXP (op0, 0), 1)) < HOST_BITS_PER_WIDE_INT
4241 17053429 : && ((INTVAL (XEXP (XEXP (op0, 0), 1))
4242 95458 : + floor_log2 (val1))
4243 16957971 : < GET_MODE_PRECISION (as_a <scalar_int_mode> (mode))))
4244 : {
4245 10484 : tem = XEXP (XEXP (op0, 0), 0);
4246 10484 : if (SUBREG_P (tem))
4247 : {
4248 265 : if (subreg_lowpart_p (tem))
4249 265 : tem = SUBREG_REG (tem);
4250 : else
4251 : tem = NULL_RTX;
4252 : }
4253 265 : if (tem != NULL_RTX)
4254 : {
4255 10484 : offset = subreg_lowpart_offset (mode, GET_MODE (tem));
4256 10484 : tem = simplify_gen_subreg (mode, tem, GET_MODE (tem),
4257 10484 : offset);
4258 10484 : if (tem)
4259 : {
4260 10484 : unsigned shiftamt = INTVAL (XEXP (XEXP (op0, 0), 1));
4261 10484 : rtx shiftamtrtx = gen_int_shift_amount (mode,
4262 10484 : shiftamt);
4263 10484 : op0 = simplify_gen_binary (LSHIFTRT, mode, tem,
4264 : shiftamtrtx);
4265 10484 : return simplify_gen_binary (AND, mode, op0, op1);
4266 : }
4267 : }
4268 : }
4269 : }
4270 19973130 : nzop1 = nonzero_bits (trueop1, mode);
4271 : /* If we are clearing all the nonzero bits, the result is zero. */
4272 19973130 : if ((nzop1 & nzop0) == 0
4273 19973130 : && !side_effects_p (op0) && !side_effects_p (op1))
4274 72483 : return CONST0_RTX (mode);
4275 : }
4276 22758716 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
4277 22758712 : && GET_MODE_CLASS (mode) != MODE_CC)
4278 : return op0;
4279 : /* A & (~A) -> 0 */
4280 627207 : if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
4281 22748132 : || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
4282 3998 : && ! side_effects_p (op0)
4283 22756081 : && GET_MODE_CLASS (mode) != MODE_CC)
4284 3997 : return CONST0_RTX (mode);
4285 :
4286 : /* Convert (and (plus (A - 1)) (neg A)) to 0. */
4287 22748087 : if (match_plus_neg_pattern (op0, op1, mode))
4288 2 : return CONST0_RTX (mode);
4289 :
4290 : /* Transform (and (extend X) C) into (zero_extend (and X C)) if
4291 : there are no nonzero bits of C outside of X's mode. */
4292 45496170 : if ((GET_CODE (op0) == SIGN_EXTEND
4293 22748085 : || GET_CODE (op0) == ZERO_EXTEND)
4294 92913 : && CONST_SCALAR_INT_P (trueop1)
4295 78912 : && is_a <scalar_int_mode> (mode, &int_mode)
4296 78912 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
4297 22826997 : && (wi::mask (GET_MODE_PRECISION (inner_mode), true,
4298 78912 : GET_MODE_PRECISION (int_mode))
4299 22826997 : & rtx_mode_t (trueop1, mode)) == 0)
4300 : {
4301 77039 : machine_mode imode = GET_MODE (XEXP (op0, 0));
4302 77039 : tem = immed_wide_int_const (rtx_mode_t (trueop1, mode), imode);
4303 77039 : tem = simplify_gen_binary (AND, imode, XEXP (op0, 0), tem);
4304 77039 : return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
4305 : }
4306 :
4307 : /* Transform (and (truncate X) C) into (truncate (and X C)). This way
4308 : we might be able to further simplify the AND with X and potentially
4309 : remove the truncation altogether. */
4310 22671046 : if (GET_CODE (op0) == TRUNCATE && CONST_INT_P (trueop1))
4311 : {
4312 6 : rtx x = XEXP (op0, 0);
4313 6 : machine_mode xmode = GET_MODE (x);
4314 6 : tem = simplify_gen_binary (AND, xmode, x,
4315 6 : gen_int_mode (INTVAL (trueop1), xmode));
4316 6 : return simplify_gen_unary (TRUNCATE, mode, tem, xmode);
4317 : }
4318 :
4319 : /* Canonicalize (A | C1) & C2 as (A & C2) | (C1 & C2). */
4320 22671040 : if (GET_CODE (op0) == IOR
4321 1402390 : && CONST_INT_P (trueop1)
4322 222636 : && CONST_INT_P (XEXP (op0, 1)))
4323 : {
4324 131581 : HOST_WIDE_INT tmp = INTVAL (trueop1) & INTVAL (XEXP (op0, 1));
4325 131581 : return simplify_gen_binary (IOR, mode,
4326 : simplify_gen_binary (AND, mode,
4327 : XEXP (op0, 0), op1),
4328 131581 : gen_int_mode (tmp, mode));
4329 : }
4330 :
4331 : /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
4332 : insn (and may simplify more). */
4333 22539459 : if (GET_CODE (op0) == XOR
4334 136499 : && rtx_equal_p (XEXP (op0, 0), op1)
4335 22540900 : && ! side_effects_p (op1))
4336 1441 : return simplify_gen_binary (AND, mode,
4337 : simplify_gen_unary (NOT, mode,
4338 : XEXP (op0, 1), mode),
4339 1441 : op1);
4340 :
4341 22538018 : if (GET_CODE (op0) == XOR
4342 135058 : && rtx_equal_p (XEXP (op0, 1), op1)
4343 22540962 : && ! side_effects_p (op1))
4344 2944 : return simplify_gen_binary (AND, mode,
4345 : simplify_gen_unary (NOT, mode,
4346 : XEXP (op0, 0), mode),
4347 2944 : op1);
4348 :
4349 : /* Similarly for (~(A ^ B)) & A. */
4350 22535074 : if (GET_CODE (op0) == NOT
4351 623256 : && GET_CODE (XEXP (op0, 0)) == XOR
4352 3464 : && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
4353 22535128 : && ! side_effects_p (op1))
4354 54 : return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
4355 :
4356 22535020 : if (GET_CODE (op0) == NOT
4357 623202 : && GET_CODE (XEXP (op0, 0)) == XOR
4358 3410 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
4359 22535057 : && ! side_effects_p (op1))
4360 37 : return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
4361 :
4362 : /* Convert (A | B) & A to A. */
4363 22534983 : if (GET_CODE (op0) == IOR
4364 1270809 : && (rtx_equal_p (XEXP (op0, 0), op1)
4365 1270287 : || rtx_equal_p (XEXP (op0, 1), op1))
4366 725 : && ! side_effects_p (XEXP (op0, 0))
4367 22535708 : && ! side_effects_p (XEXP (op0, 1)))
4368 : return op1;
4369 :
4370 : /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
4371 : ((A & N) + B) & M -> (A + B) & M
4372 : Similarly if (N & M) == 0,
4373 : ((A | N) + B) & M -> (A + B) & M
4374 : and for - instead of + and/or ^ instead of |.
4375 : Also, if (N & M) == 0, then
4376 : (A +- N) & M -> A & M. */
4377 22534258 : if (CONST_INT_P (trueop1)
4378 16759134 : && HWI_COMPUTABLE_MODE_P (mode)
4379 16737604 : && ~UINTVAL (trueop1)
4380 16737604 : && (UINTVAL (trueop1) & (UINTVAL (trueop1) + 1)) == 0
4381 33245334 : && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS))
4382 : {
4383 981144 : rtx pmop[2];
4384 981144 : int which;
4385 :
4386 981144 : pmop[0] = XEXP (op0, 0);
4387 981144 : pmop[1] = XEXP (op0, 1);
4388 :
4389 981144 : if (CONST_INT_P (pmop[1])
4390 522247 : && (UINTVAL (pmop[1]) & UINTVAL (trueop1)) == 0)
4391 172734 : return simplify_gen_binary (AND, mode, pmop[0], op1);
4392 :
4393 2448276 : for (which = 0; which < 2; which++)
4394 : {
4395 1632184 : tem = pmop[which];
4396 1632184 : switch (GET_CODE (tem))
4397 : {
4398 11865 : case AND:
4399 11865 : if (CONST_INT_P (XEXP (tem, 1))
4400 10363 : && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1))
4401 : == UINTVAL (trueop1))
4402 7543 : pmop[which] = XEXP (tem, 0);
4403 : break;
4404 1728 : case IOR:
4405 1728 : case XOR:
4406 1728 : if (CONST_INT_P (XEXP (tem, 1))
4407 699 : && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1)) == 0)
4408 139 : pmop[which] = XEXP (tem, 0);
4409 : break;
4410 : default:
4411 : break;
4412 : }
4413 : }
4414 :
4415 816092 : if (pmop[0] != XEXP (op0, 0) || pmop[1] != XEXP (op0, 1))
4416 : {
4417 7682 : tem = simplify_gen_binary (GET_CODE (op0), mode,
4418 : pmop[0], pmop[1]);
4419 7682 : return simplify_gen_binary (code, mode, tem, op1);
4420 : }
4421 : }
4422 :
4423 : /* (and X (ior (not X) Y) -> (and X Y) */
4424 22361524 : if (GET_CODE (op1) == IOR
4425 947814 : && GET_CODE (XEXP (op1, 0)) == NOT
4426 22366947 : && rtx_equal_p (op0, XEXP (XEXP (op1, 0), 0)))
4427 0 : return simplify_gen_binary (AND, mode, op0, XEXP (op1, 1));
4428 :
4429 : /* (and (ior (not X) Y) X) -> (and X Y) */
4430 22361524 : if (GET_CODE (op0) == IOR
4431 1270084 : && GET_CODE (XEXP (op0, 0)) == NOT
4432 22412152 : && rtx_equal_p (op1, XEXP (XEXP (op0, 0), 0)))
4433 6 : return simplify_gen_binary (AND, mode, op1, XEXP (op0, 1));
4434 :
4435 : /* (and X (ior Y (not X)) -> (and X Y) */
4436 22361518 : if (GET_CODE (op1) == IOR
4437 947814 : && GET_CODE (XEXP (op1, 1)) == NOT
4438 22361857 : && rtx_equal_p (op0, XEXP (XEXP (op1, 1), 0)))
4439 0 : return simplify_gen_binary (AND, mode, op0, XEXP (op1, 0));
4440 :
4441 : /* (and (ior Y (not X)) X) -> (and X Y) */
4442 22361518 : if (GET_CODE (op0) == IOR
4443 1270078 : && GET_CODE (XEXP (op0, 1)) == NOT
4444 22370269 : && rtx_equal_p (op1, XEXP (XEXP (op0, 1), 0)))
4445 43 : return simplify_gen_binary (AND, mode, op1, XEXP (op0, 0));
4446 :
4447 : /* (and (ior/xor X Y) (not Y)) -> X & ~Y */
4448 22361475 : if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
4449 22361475 : && negated_ops_p (op1, XEXP (op0, 1)))
4450 15 : return simplify_gen_binary (AND, mode, XEXP (op0, 0),
4451 : simplify_gen_unary (NOT, mode,
4452 : XEXP (op0, 1),
4453 15 : mode));
4454 : /* (and (ior/xor Y X) (not Y)) -> X & ~Y */
4455 22361460 : if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
4456 22361460 : && negated_ops_p (op1, XEXP (op0, 0)))
4457 4 : return simplify_gen_binary (AND, mode, XEXP (op0, 1),
4458 : simplify_gen_unary (NOT, mode,
4459 : XEXP (op0, 0),
4460 4 : mode));
4461 :
4462 : /* Convert (and (ior A C) (ior B C)) into (ior (and A B) C). */
4463 22361456 : if (GET_CODE (op0) == GET_CODE (op1)
4464 2145114 : && (GET_CODE (op0) == AND
4465 : || GET_CODE (op0) == IOR
4466 2145114 : || GET_CODE (op0) == LSHIFTRT
4467 1197979 : || GET_CODE (op0) == ASHIFTRT
4468 1197829 : || GET_CODE (op0) == ASHIFT
4469 1197660 : || GET_CODE (op0) == ROTATE
4470 1197660 : || GET_CODE (op0) == ROTATERT))
4471 : {
4472 947454 : tem = simplify_distributive_operation (code, mode, op0, op1);
4473 947454 : if (tem)
4474 : return tem;
4475 : }
4476 :
4477 : /* (and:v4si
4478 : (ashiftrt:v4si A 16)
4479 : (const_vector: 0xffff x4))
4480 : is just (lshiftrt:v4si A 16). */
4481 21455666 : if (VECTOR_MODE_P (mode) && GET_CODE (op0) == ASHIFTRT
4482 4489 : && (CONST_INT_P (XEXP (op0, 1))
4483 1948 : || (GET_CODE (XEXP (op0, 1)) == CONST_VECTOR
4484 94 : && const_vec_duplicate_p (XEXP (op0, 1))
4485 0 : && CONST_INT_P (XVECEXP (XEXP (op0, 1), 0, 0))))
4486 2541 : && GET_CODE (op1) == CONST_VECTOR
4487 21455691 : && const_vec_duplicate_p (op1)
4488 21455733 : && CONST_INT_P (XVECEXP (op1, 0, 0)))
4489 : {
4490 130 : unsigned HOST_WIDE_INT shift_count
4491 : = (CONST_INT_P (XEXP (op0, 1))
4492 65 : ? UINTVAL (XEXP (op0, 1))
4493 0 : : UINTVAL (XVECEXP (XEXP (op0, 1), 0, 0)));
4494 65 : unsigned HOST_WIDE_INT inner_prec
4495 130 : = GET_MODE_PRECISION (GET_MODE_INNER (mode));
4496 :
4497 : /* Avoid UD shift count. */
4498 65 : if (shift_count < inner_prec
4499 59 : && (UINTVAL (XVECEXP (op1, 0, 0))
4500 59 : == (HOST_WIDE_INT_1U << (inner_prec - shift_count)) - 1))
4501 42 : return simplify_gen_binary (LSHIFTRT, mode, XEXP (op0, 0), XEXP (op0, 1));
4502 : }
4503 :
4504 21455624 : tem = simplify_with_subreg_not (code, mode, op0, op1);
4505 21455624 : if (tem)
4506 : return tem;
4507 :
4508 21453323 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
4509 21453323 : if (tem)
4510 : return tem;
4511 :
4512 21452850 : tem = simplify_associative_operation (code, mode, op0, op1);
4513 21452850 : if (tem)
4514 : return tem;
4515 : break;
4516 :
4517 902848 : case UDIV:
4518 : /* 0/x is 0 (or x&0 if x has side-effects). */
4519 902848 : if (trueop0 == CONST0_RTX (mode)
4520 265 : && !cfun->can_throw_non_call_exceptions)
4521 : {
4522 265 : if (side_effects_p (op1))
4523 0 : return simplify_gen_binary (AND, mode, op1, trueop0);
4524 : return trueop0;
4525 : }
4526 : /* x/1 is x. */
4527 902583 : if (trueop1 == CONST1_RTX (mode))
4528 : {
4529 237528 : tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4530 237528 : if (tem)
4531 : return tem;
4532 : }
4533 : /* Convert divide by power of two into shift. */
4534 665055 : if (CONST_INT_P (trueop1)
4535 996990 : && (val = exact_log2 (UINTVAL (trueop1))) > 0)
4536 331935 : return simplify_gen_binary (LSHIFTRT, mode, op0,
4537 331935 : gen_int_shift_amount (mode, val));
4538 : break;
4539 :
4540 1179853 : case DIV:
4541 : /* Handle floating point and integers separately. */
4542 1179853 : if (SCALAR_FLOAT_MODE_P (mode))
4543 : {
4544 : /* Maybe change 0.0 / x to 0.0. This transformation isn't
4545 : safe for modes with NaNs, since 0.0 / 0.0 will then be
4546 : NaN rather than 0.0. Nor is it safe for modes with signed
4547 : zeros, since dividing 0 by a negative number gives -0.0 */
4548 325898 : if (trueop0 == CONST0_RTX (mode)
4549 2800 : && !HONOR_NANS (mode)
4550 14 : && !HONOR_SIGNED_ZEROS (mode)
4551 325912 : && ! side_effects_p (op1))
4552 : return op0;
4553 : /* x/1.0 is x. */
4554 325884 : if (trueop1 == CONST1_RTX (mode)
4555 325884 : && !HONOR_SNANS (mode))
4556 : return op0;
4557 :
4558 325879 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
4559 27207 : && trueop1 != CONST0_RTX (mode))
4560 : {
4561 21087 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
4562 :
4563 : /* x/-1.0 is -x. */
4564 21087 : if (real_equal (d1, &dconstm1)
4565 21087 : && !HONOR_SNANS (mode))
4566 0 : return simplify_gen_unary (NEG, mode, op0, mode);
4567 :
4568 : /* Change FP division by a constant into multiplication.
4569 : Only do this with -freciprocal-math. */
4570 21087 : if (flag_reciprocal_math
4571 21087 : && !real_equal (d1, &dconst0))
4572 : {
4573 7 : REAL_VALUE_TYPE d;
4574 7 : real_arithmetic (&d, RDIV_EXPR, &dconst1, d1);
4575 7 : tem = const_double_from_real_value (d, mode);
4576 7 : return simplify_gen_binary (MULT, mode, op0, tem);
4577 : }
4578 : }
4579 : }
4580 853955 : else if (SCALAR_INT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
4581 : {
4582 : /* 0/x is 0 (or x&0 if x has side-effects). */
4583 831923 : if (trueop0 == CONST0_RTX (mode)
4584 1002 : && !cfun->can_throw_non_call_exceptions)
4585 : {
4586 925 : if (side_effects_p (op1))
4587 8 : return simplify_gen_binary (AND, mode, op1, trueop0);
4588 : return trueop0;
4589 : }
4590 : /* x/1 is x. */
4591 830998 : if (trueop1 == CONST1_RTX (mode))
4592 : {
4593 882 : tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4594 882 : if (tem)
4595 : return tem;
4596 : }
4597 : /* x/-1 is -x. */
4598 830116 : if (trueop1 == CONSTM1_RTX (mode))
4599 : {
4600 503 : rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4601 503 : if (x)
4602 503 : return simplify_gen_unary (NEG, mode, x, mode);
4603 : }
4604 : }
4605 : break;
4606 :
4607 935248 : case UMOD:
4608 : /* 0%x is 0 (or x&0 if x has side-effects). */
4609 935248 : if (trueop0 == CONST0_RTX (mode))
4610 : {
4611 767 : if (side_effects_p (op1))
4612 0 : return simplify_gen_binary (AND, mode, op1, trueop0);
4613 : return trueop0;
4614 : }
4615 : /* x%1 is 0 (of x&0 if x has side-effects). */
4616 934481 : if (trueop1 == CONST1_RTX (mode))
4617 : {
4618 271371 : if (side_effects_p (op0))
4619 0 : return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
4620 271371 : return CONST0_RTX (mode);
4621 : }
4622 : /* Implement modulus by power of two as AND. */
4623 663110 : if (CONST_INT_P (trueop1)
4624 987363 : && exact_log2 (UINTVAL (trueop1)) > 0)
4625 324253 : return simplify_gen_binary (AND, mode, op0,
4626 324253 : gen_int_mode (UINTVAL (trueop1) - 1,
4627 : mode));
4628 : break;
4629 :
4630 363361 : case MOD:
4631 : /* 0%x is 0 (or x&0 if x has side-effects). */
4632 363361 : if (trueop0 == CONST0_RTX (mode))
4633 : {
4634 1225 : if (side_effects_p (op1))
4635 8 : return simplify_gen_binary (AND, mode, op1, trueop0);
4636 : return trueop0;
4637 : }
4638 : /* x%1 and x%-1 is 0 (or x&0 if x has side-effects). */
4639 362136 : if (trueop1 == CONST1_RTX (mode) || trueop1 == constm1_rtx)
4640 : {
4641 740 : if (side_effects_p (op0))
4642 0 : return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
4643 740 : return CONST0_RTX (mode);
4644 : }
4645 : break;
4646 :
4647 137652 : case ROTATERT:
4648 137652 : case ROTATE:
4649 137652 : if (trueop1 == CONST0_RTX (mode))
4650 : return op0;
4651 : /* Canonicalize rotates by constant amount. If the condition of
4652 : reversing direction is met, then reverse the direction. */
4653 : #if defined(HAVE_rotate) && defined(HAVE_rotatert)
4654 137562 : if (reverse_rotate_by_imm_p (mode, (code == ROTATE), trueop1))
4655 : {
4656 11743 : int new_amount = GET_MODE_UNIT_PRECISION (mode) - INTVAL (trueop1);
4657 11743 : rtx new_amount_rtx = gen_int_shift_amount (mode, new_amount);
4658 12287 : return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
4659 : mode, op0, new_amount_rtx);
4660 : }
4661 : #endif
4662 : /* ROTATE/ROTATERT:HI (X:HI, 8) is BSWAP:HI (X). Other combinations
4663 : such as SImode with a count of 16 do not correspond to RTL BSWAP
4664 : semantics. */
4665 125819 : tem = unwrap_const_vec_duplicate (trueop1);
4666 125819 : if (GET_MODE_UNIT_BITSIZE (mode) == (2 * BITS_PER_UNIT)
4667 125819 : && CONST_INT_P (tem) && INTVAL (tem) == BITS_PER_UNIT)
4668 599 : return simplify_gen_unary (BSWAP, mode, op0, mode);
4669 :
4670 : /* FALLTHRU */
4671 5195611 : case ASHIFTRT:
4672 5195611 : if (trueop1 == CONST0_RTX (mode))
4673 : return op0;
4674 5193582 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4675 : return op0;
4676 : /* Rotating ~0 always results in ~0. */
4677 5193410 : if (CONST_INT_P (trueop0)
4678 14721 : && HWI_COMPUTABLE_MODE_P (mode)
4679 14693 : && UINTVAL (trueop0) == GET_MODE_MASK (mode)
4680 5193410 : && ! side_effects_p (op1))
4681 : return op0;
4682 :
4683 31032926 : canonicalize_shift:
4684 : /* Given:
4685 : scalar modes M1, M2
4686 : scalar constants c1, c2
4687 : size (M2) > size (M1)
4688 : c1 == size (M2) - size (M1)
4689 : optimize:
4690 : ([a|l]shiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int <c1>))
4691 : <low_part>)
4692 : (const_int <c2>))
4693 : to:
4694 : (subreg:M1 ([a|l]shiftrt:M2 (reg:M2) (const_int <c1 + c2>))
4695 : <low_part>). */
4696 31032926 : if ((code == ASHIFTRT || code == LSHIFTRT)
4697 11725893 : && is_a <scalar_int_mode> (mode, &int_mode)
4698 10936572 : && SUBREG_P (op0)
4699 1147524 : && CONST_INT_P (op1)
4700 1145303 : && GET_CODE (SUBREG_REG (op0)) == LSHIFTRT
4701 18541 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op0)),
4702 : &inner_mode)
4703 18541 : && CONST_INT_P (XEXP (SUBREG_REG (op0), 1))
4704 36776 : && GET_MODE_BITSIZE (inner_mode) > GET_MODE_BITSIZE (int_mode)
4705 18388 : && (INTVAL (XEXP (SUBREG_REG (op0), 1))
4706 36776 : == GET_MODE_BITSIZE (inner_mode) - GET_MODE_BITSIZE (int_mode))
4707 31051077 : && subreg_lowpart_p (op0))
4708 : {
4709 18151 : rtx tmp = gen_int_shift_amount
4710 18151 : (inner_mode, INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (op1));
4711 :
4712 : /* Combine would usually zero out the value when combining two
4713 : local shifts and the range becomes larger or equal to the mode.
4714 : However since we fold away one of the shifts here combine won't
4715 : see it so we should immediately zero the result if it's out of
4716 : range. */
4717 18151 : if (code == LSHIFTRT
4718 32808 : && INTVAL (tmp) >= GET_MODE_BITSIZE (inner_mode))
4719 0 : tmp = const0_rtx;
4720 : else
4721 18151 : tmp = simplify_gen_binary (code,
4722 : inner_mode,
4723 18151 : XEXP (SUBREG_REG (op0), 0),
4724 : tmp);
4725 :
4726 18151 : return lowpart_subreg (int_mode, tmp, inner_mode);
4727 : }
4728 :
4729 31014775 : if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
4730 : {
4731 : val = INTVAL (op1) & (GET_MODE_UNIT_PRECISION (mode) - 1);
4732 : if (val != INTVAL (op1))
4733 : return simplify_gen_binary (code, mode, op0,
4734 : gen_int_shift_amount (mode, val));
4735 : }
4736 :
4737 : /* Simplify:
4738 :
4739 : (code:M1
4740 : (subreg:M1
4741 : ([al]shiftrt:M2
4742 : (subreg:M2
4743 : (ashift:M1 X C1))
4744 : C2))
4745 : C3)
4746 :
4747 : to:
4748 :
4749 : (code:M1
4750 : ([al]shiftrt:M1
4751 : (ashift:M1 X C1+N)
4752 : C2+N)
4753 : C3)
4754 :
4755 : where M1 is N bits wider than M2. Optimizing the (subreg:M1 ...)
4756 : directly would be arithmetically correct, but restricting the
4757 : simplification to shifts by constants is more conservative,
4758 : since it is more likely to lead to further simplifications. */
4759 31014775 : if (is_a<scalar_int_mode> (mode, &int_mode)
4760 5443150 : && paradoxical_subreg_p (op0)
4761 5002844 : && is_a<scalar_int_mode> (GET_MODE (SUBREG_REG (op0)), &inner_mode)
4762 5002758 : && (GET_CODE (SUBREG_REG (op0)) == ASHIFTRT
4763 5002758 : || GET_CODE (SUBREG_REG (op0)) == LSHIFTRT)
4764 145225 : && CONST_INT_P (op1))
4765 : {
4766 145225 : auto xcode = GET_CODE (SUBREG_REG (op0));
4767 145225 : rtx xop0 = XEXP (SUBREG_REG (op0), 0);
4768 145225 : rtx xop1 = XEXP (SUBREG_REG (op0), 1);
4769 145225 : if (SUBREG_P (xop0)
4770 10737 : && GET_MODE (SUBREG_REG (xop0)) == mode
4771 10651 : && GET_CODE (SUBREG_REG (xop0)) == ASHIFT
4772 605 : && CONST_INT_P (xop1)
4773 145830 : && UINTVAL (xop1) < GET_MODE_PRECISION (inner_mode))
4774 : {
4775 605 : rtx yop0 = XEXP (SUBREG_REG (xop0), 0);
4776 605 : rtx yop1 = XEXP (SUBREG_REG (xop0), 1);
4777 605 : if (CONST_INT_P (yop1)
4778 605 : && UINTVAL (yop1) < GET_MODE_PRECISION (inner_mode))
4779 : {
4780 1210 : auto bias = (GET_MODE_BITSIZE (int_mode)
4781 605 : - GET_MODE_BITSIZE (inner_mode));
4782 605 : tem = simplify_gen_binary (ASHIFT, mode, yop0,
4783 605 : GEN_INT (INTVAL (yop1) + bias));
4784 605 : tem = simplify_gen_binary (xcode, mode, tem,
4785 605 : GEN_INT (INTVAL (xop1) + bias));
4786 605 : return simplify_gen_binary (code, mode, tem, op1);
4787 : }
4788 : }
4789 : }
4790 : break;
4791 :
4792 0 : case SS_ASHIFT:
4793 0 : if (CONST_INT_P (trueop0)
4794 0 : && HWI_COMPUTABLE_MODE_P (mode)
4795 0 : && (UINTVAL (trueop0) == (GET_MODE_MASK (mode) >> 1)
4796 0 : || mode_signbit_p (mode, trueop0))
4797 0 : && ! side_effects_p (op1))
4798 : return op0;
4799 0 : goto simplify_ashift;
4800 :
4801 0 : case US_ASHIFT:
4802 0 : if (CONST_INT_P (trueop0)
4803 0 : && HWI_COMPUTABLE_MODE_P (mode)
4804 0 : && UINTVAL (trueop0) == GET_MODE_MASK (mode)
4805 0 : && ! side_effects_p (op1))
4806 : return op0;
4807 : /* FALLTHRU */
4808 :
4809 19606549 : case ASHIFT:
4810 19606549 : simplify_ashift:
4811 19606549 : if (trueop1 == CONST0_RTX (mode))
4812 : return op0;
4813 19449453 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4814 : return op0;
4815 19420268 : if (mem_depth
4816 238424 : && code == ASHIFT
4817 238424 : && CONST_INT_P (trueop1)
4818 238416 : && is_a <scalar_int_mode> (mode, &int_mode)
4819 19658672 : && IN_RANGE (UINTVAL (trueop1),
4820 : 1, GET_MODE_PRECISION (int_mode) - 1))
4821 : {
4822 238404 : auto c = (wi::one (GET_MODE_PRECISION (int_mode))
4823 238404 : << UINTVAL (trueop1));
4824 238404 : rtx new_op1 = immed_wide_int_const (c, int_mode);
4825 238404 : return simplify_gen_binary (MULT, int_mode, op0, new_op1);
4826 238404 : }
4827 :
4828 : /* If we're shifting left a signed bitfield extraction and the
4829 : shift count + bitfield size is a natural integral mode and
4830 : the field starts at offset 0 (counting from the LSB), then
4831 : this can be simplified to a sign extension of a left shift.
4832 :
4833 : Some ISAs (RISC-V 64-bit) have inherent support for such
4834 : instructions and it's better for various optimizations to
4835 : express as a SIGN_EXTEND rather than a shifted SIGN_EXTRACT. */
4836 19181864 : if (GET_CODE (op0) == SIGN_EXTRACT
4837 28 : && REG_P (XEXP (op0, 0))
4838 : /* The size of the bitfield, the location of the bitfield and
4839 : shift count must be CONST_INTs. */
4840 22 : && CONST_INT_P (op1)
4841 22 : && CONST_INT_P (XEXP (op0, 1))
4842 22 : && CONST_INT_P (XEXP (op0, 2)))
4843 : {
4844 22 : int size = INTVAL (op1) + INTVAL (XEXP (op0, 1));
4845 22 : machine_mode smaller_mode;
4846 : /* Now we need to verify the size of the bitfield plus the shift
4847 : count is an integral mode and smaller than MODE. This is
4848 : requirement for using SIGN_EXTEND. We also need to verify the
4849 : field starts at bit location 0 and that the subreg lowpart also
4850 : starts at zero. */
4851 22 : if (int_mode_for_size (size, size).exists (&smaller_mode)
4852 3 : && mode > smaller_mode
4853 22 : && (subreg_lowpart_offset (smaller_mode, mode).to_constant ()
4854 3 : == UINTVAL (XEXP (op0, 2)))
4855 1 : && XEXP (op0, 2) == CONST0_RTX (mode))
4856 : {
4857 : /* Everything passed. So we just need to get the subreg of the
4858 : original input, shift it and sign extend the result. */
4859 1 : rtx op = gen_lowpart (smaller_mode, XEXP (op0, 0));
4860 1 : rtx x = gen_rtx_ASHIFT (smaller_mode, op, op1);
4861 1 : return gen_rtx_SIGN_EXTEND (mode, x);
4862 : }
4863 : }
4864 19181863 : goto canonicalize_shift;
4865 :
4866 8425470 : case LSHIFTRT:
4867 8425470 : if (trueop1 == CONST0_RTX (mode))
4868 : return op0;
4869 6659078 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4870 : return op0;
4871 : /* Optimize (lshiftrt (clz X) C) as (eq X 0). */
4872 6657653 : if (GET_CODE (op0) == CLZ
4873 0 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
4874 0 : && CONST_INT_P (trueop1)
4875 : && STORE_FLAG_VALUE == 1
4876 6657653 : && INTVAL (trueop1) < GET_MODE_UNIT_PRECISION (mode))
4877 : {
4878 0 : unsigned HOST_WIDE_INT zero_val = 0;
4879 :
4880 0 : if (CLZ_DEFINED_VALUE_AT_ZERO (inner_mode, zero_val)
4881 0 : && zero_val == GET_MODE_PRECISION (inner_mode)
4882 0 : && INTVAL (trueop1) == exact_log2 (zero_val))
4883 0 : return simplify_gen_relational (EQ, mode, inner_mode,
4884 0 : XEXP (op0, 0), const0_rtx);
4885 : }
4886 6657653 : goto canonicalize_shift;
4887 :
4888 236125 : case SMIN:
4889 236125 : if (HWI_COMPUTABLE_MODE_P (mode)
4890 215220 : && mode_signbit_p (mode, trueop1)
4891 0 : && ! side_effects_p (op0))
4892 : return op1;
4893 236125 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4894 : return op0;
4895 235969 : tem = simplify_associative_operation (code, mode, op0, op1);
4896 235969 : if (tem)
4897 : return tem;
4898 : break;
4899 :
4900 489383 : case SMAX:
4901 489383 : if (HWI_COMPUTABLE_MODE_P (mode)
4902 462228 : && CONST_INT_P (trueop1)
4903 429959 : && (UINTVAL (trueop1) == GET_MODE_MASK (mode) >> 1)
4904 0 : && ! side_effects_p (op0))
4905 : return op1;
4906 489383 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4907 : return op0;
4908 489278 : tem = simplify_associative_operation (code, mode, op0, op1);
4909 489278 : if (tem)
4910 : return tem;
4911 : break;
4912 :
4913 340644 : case UMIN:
4914 340644 : if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
4915 : return op1;
4916 340631 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4917 : return op0;
4918 340513 : tem = simplify_associative_operation (code, mode, op0, op1);
4919 340513 : if (tem)
4920 : return tem;
4921 : break;
4922 :
4923 319888 : case UMAX:
4924 319888 : if (trueop1 == constm1_rtx && ! side_effects_p (op0))
4925 : return op1;
4926 319888 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4927 : return op0;
4928 319798 : tem = simplify_associative_operation (code, mode, op0, op1);
4929 319798 : if (tem)
4930 : return tem;
4931 : break;
4932 :
4933 11681 : case SS_PLUS:
4934 11681 : case US_PLUS:
4935 11681 : case SS_MINUS:
4936 11681 : case US_MINUS:
4937 : /* Simplify x +/- 0 to x, if possible. */
4938 11681 : if (trueop1 == CONST0_RTX (mode))
4939 : return op0;
4940 : return 0;
4941 :
4942 0 : case SS_MULT:
4943 0 : case US_MULT:
4944 : /* Simplify x * 0 to 0, if possible. */
4945 0 : if (trueop1 == CONST0_RTX (mode)
4946 0 : && !side_effects_p (op0))
4947 : return op1;
4948 :
4949 : /* Simplify x * 1 to x, if possible. */
4950 0 : if (trueop1 == CONST1_RTX (mode))
4951 : return op0;
4952 : return 0;
4953 :
4954 463951 : case SMUL_HIGHPART:
4955 463951 : case UMUL_HIGHPART:
4956 : /* Simplify x * 0 to 0, if possible. */
4957 463951 : if (trueop1 == CONST0_RTX (mode)
4958 463951 : && !side_effects_p (op0))
4959 : return op1;
4960 : return 0;
4961 :
4962 0 : case SS_DIV:
4963 0 : case US_DIV:
4964 : /* Simplify x / 1 to x, if possible. */
4965 0 : if (trueop1 == CONST1_RTX (mode))
4966 : return op0;
4967 : return 0;
4968 :
4969 0 : case COPYSIGN:
4970 0 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4971 : return op0;
4972 0 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1))
4973 : {
4974 0 : REAL_VALUE_TYPE f1;
4975 0 : real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (trueop1));
4976 0 : rtx tmp = simplify_gen_unary (ABS, mode, op0, mode);
4977 0 : if (REAL_VALUE_NEGATIVE (f1))
4978 0 : tmp = simplify_unary_operation (NEG, mode, tmp, mode);
4979 0 : return tmp;
4980 : }
4981 0 : if (GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
4982 0 : return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
4983 0 : if (GET_CODE (op1) == ABS
4984 0 : && ! side_effects_p (op1))
4985 0 : return simplify_gen_unary (ABS, mode, op0, mode);
4986 0 : if (GET_CODE (op0) == COPYSIGN
4987 0 : && ! side_effects_p (XEXP (op0, 1)))
4988 0 : return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
4989 0 : if (GET_CODE (op1) == COPYSIGN
4990 0 : && ! side_effects_p (XEXP (op1, 0)))
4991 0 : return simplify_gen_binary (COPYSIGN, mode, op0, XEXP (op1, 1));
4992 : return 0;
4993 :
4994 1112 : case VEC_SERIES:
4995 2224 : if (op1 == CONST0_RTX (GET_MODE_INNER (mode)))
4996 92 : return gen_vec_duplicate (mode, op0);
4997 1020 : if (valid_for_const_vector_p (mode, op0)
4998 1020 : && valid_for_const_vector_p (mode, op1))
4999 93 : return gen_const_vec_series (mode, op0, op1);
5000 : return 0;
5001 :
5002 3410204 : case VEC_SELECT:
5003 3410204 : if (!VECTOR_MODE_P (mode))
5004 : {
5005 937575 : gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
5006 1875150 : gcc_assert (mode == GET_MODE_INNER (GET_MODE (trueop0)));
5007 937575 : gcc_assert (GET_CODE (trueop1) == PARALLEL);
5008 937575 : gcc_assert (XVECLEN (trueop1, 0) == 1);
5009 :
5010 : /* We can't reason about selections made at runtime. */
5011 937575 : if (!CONST_INT_P (XVECEXP (trueop1, 0, 0)))
5012 441528315 : return 0;
5013 :
5014 937575 : if (vec_duplicate_p (trueop0, &elt0))
5015 2143 : return elt0;
5016 :
5017 935432 : if (GET_CODE (trueop0) == CONST_VECTOR)
5018 7256 : return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP
5019 : (trueop1, 0, 0)));
5020 :
5021 : /* Extract a scalar element from a nested VEC_SELECT expression
5022 : (with optional nested VEC_CONCAT expression). Some targets
5023 : (i386) extract scalar element from a vector using chain of
5024 : nested VEC_SELECT expressions. When input operand is a memory
5025 : operand, this operation can be simplified to a simple scalar
5026 : load from an offseted memory address. */
5027 928176 : int n_elts;
5028 928176 : if (GET_CODE (trueop0) == VEC_SELECT
5029 1000461 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
5030 72285 : .is_constant (&n_elts)))
5031 : {
5032 72285 : rtx op0 = XEXP (trueop0, 0);
5033 72285 : rtx op1 = XEXP (trueop0, 1);
5034 :
5035 72285 : int i = INTVAL (XVECEXP (trueop1, 0, 0));
5036 72285 : int elem;
5037 :
5038 72285 : rtvec vec;
5039 72285 : rtx tmp_op, tmp;
5040 :
5041 72285 : gcc_assert (GET_CODE (op1) == PARALLEL);
5042 72285 : gcc_assert (i < XVECLEN (op1, 0));
5043 :
5044 : /* Select element, pointed by nested selector. */
5045 72285 : elem = INTVAL (XVECEXP (op1, 0, i));
5046 :
5047 72285 : gcc_assert (elem < n_elts);
5048 :
5049 : /* Handle the case when nested VEC_SELECT wraps VEC_CONCAT. */
5050 72285 : if (GET_CODE (op0) == VEC_CONCAT)
5051 : {
5052 29129 : rtx op00 = XEXP (op0, 0);
5053 29129 : rtx op01 = XEXP (op0, 1);
5054 :
5055 29129 : machine_mode mode00, mode01;
5056 29129 : int n_elts00, n_elts01;
5057 :
5058 29129 : mode00 = GET_MODE (op00);
5059 29129 : mode01 = GET_MODE (op01);
5060 :
5061 : /* Find out the number of elements of each operand.
5062 : Since the concatenated result has a constant number
5063 : of elements, the operands must too. */
5064 29129 : n_elts00 = GET_MODE_NUNITS (mode00).to_constant ();
5065 29129 : n_elts01 = GET_MODE_NUNITS (mode01).to_constant ();
5066 :
5067 29129 : gcc_assert (n_elts == n_elts00 + n_elts01);
5068 :
5069 : /* Select correct operand of VEC_CONCAT
5070 : and adjust selector. */
5071 29129 : if (elem < n_elts01)
5072 : tmp_op = op00;
5073 : else
5074 : {
5075 41 : tmp_op = op01;
5076 41 : elem -= n_elts00;
5077 : }
5078 : }
5079 : else
5080 : tmp_op = op0;
5081 :
5082 72285 : vec = rtvec_alloc (1);
5083 72285 : RTVEC_ELT (vec, 0) = GEN_INT (elem);
5084 :
5085 72285 : tmp = gen_rtx_fmt_ee (code, mode,
5086 : tmp_op, gen_rtx_PARALLEL (VOIDmode, vec));
5087 72285 : return tmp;
5088 : }
5089 : }
5090 : else
5091 : {
5092 2472629 : gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
5093 7417887 : gcc_assert (GET_MODE_INNER (mode)
5094 : == GET_MODE_INNER (GET_MODE (trueop0)));
5095 2472629 : gcc_assert (GET_CODE (trueop1) == PARALLEL);
5096 :
5097 2472629 : if (vec_duplicate_p (trueop0, &elt0))
5098 : /* It doesn't matter which elements are selected by trueop1,
5099 : because they are all the same. */
5100 15472 : return gen_vec_duplicate (mode, elt0);
5101 :
5102 2457157 : if (GET_CODE (trueop0) == CONST_VECTOR)
5103 : {
5104 17216 : unsigned n_elts = XVECLEN (trueop1, 0);
5105 17216 : rtvec v = rtvec_alloc (n_elts);
5106 17216 : unsigned int i;
5107 :
5108 34432 : gcc_assert (known_eq (n_elts, GET_MODE_NUNITS (mode)));
5109 80184 : for (i = 0; i < n_elts; i++)
5110 : {
5111 62968 : rtx x = XVECEXP (trueop1, 0, i);
5112 :
5113 62968 : if (!CONST_INT_P (x))
5114 : return 0;
5115 :
5116 62968 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0,
5117 : INTVAL (x));
5118 : }
5119 :
5120 17216 : return gen_rtx_CONST_VECTOR (mode, v);
5121 : }
5122 :
5123 : /* Recognize the identity. */
5124 2439941 : if (GET_MODE (trueop0) == mode)
5125 : {
5126 582426 : bool maybe_ident = true;
5127 582426 : for (int i = 0; i < XVECLEN (trueop1, 0); i++)
5128 : {
5129 582020 : rtx j = XVECEXP (trueop1, 0, i);
5130 582020 : if (!CONST_INT_P (j) || INTVAL (j) != i)
5131 : {
5132 : maybe_ident = false;
5133 : break;
5134 : }
5135 : }
5136 357397 : if (maybe_ident)
5137 : return trueop0;
5138 : }
5139 :
5140 : /* If we select a low-part subreg, return that. */
5141 2439535 : if (vec_series_lowpart_p (mode, GET_MODE (trueop0), trueop1))
5142 : {
5143 0 : rtx new_rtx = lowpart_subreg (mode, trueop0,
5144 0 : GET_MODE (trueop0));
5145 0 : if (new_rtx != NULL_RTX)
5146 : return new_rtx;
5147 : }
5148 :
5149 : /* If we build {a,b} then permute it, build the result directly. */
5150 2439535 : if (XVECLEN (trueop1, 0) == 2
5151 591220 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
5152 591220 : && CONST_INT_P (XVECEXP (trueop1, 0, 1))
5153 591220 : && GET_CODE (trueop0) == VEC_CONCAT
5154 178024 : && GET_CODE (XEXP (trueop0, 0)) == VEC_CONCAT
5155 78 : && GET_MODE (XEXP (trueop0, 0)) == mode
5156 78 : && GET_CODE (XEXP (trueop0, 1)) == VEC_CONCAT
5157 54 : && GET_MODE (XEXP (trueop0, 1)) == mode)
5158 : {
5159 54 : unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5160 54 : unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
5161 54 : rtx subop0, subop1;
5162 :
5163 54 : gcc_assert (i0 < 4 && i1 < 4);
5164 54 : subop0 = XEXP (XEXP (trueop0, i0 / 2), i0 % 2);
5165 54 : subop1 = XEXP (XEXP (trueop0, i1 / 2), i1 % 2);
5166 :
5167 54 : return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
5168 : }
5169 :
5170 2439481 : if (XVECLEN (trueop1, 0) == 2
5171 591166 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
5172 591166 : && CONST_INT_P (XVECEXP (trueop1, 0, 1))
5173 591166 : && GET_CODE (trueop0) == VEC_CONCAT
5174 177970 : && GET_MODE (trueop0) == mode)
5175 : {
5176 2 : unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5177 2 : unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
5178 2 : rtx subop0, subop1;
5179 :
5180 2 : gcc_assert (i0 < 2 && i1 < 2);
5181 2 : subop0 = XEXP (trueop0, i0);
5182 2 : subop1 = XEXP (trueop0, i1);
5183 :
5184 2 : return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
5185 : }
5186 :
5187 : /* If we select one half of a vec_concat, return that. */
5188 2439479 : int l0, l1;
5189 2439479 : if (GET_CODE (trueop0) == VEC_CONCAT
5190 3019342 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
5191 1509671 : .is_constant (&l0))
5192 3019342 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 1)))
5193 1509671 : .is_constant (&l1))
5194 3949150 : && CONST_INT_P (XVECEXP (trueop1, 0, 0)))
5195 : {
5196 1509671 : rtx subop0 = XEXP (trueop0, 0);
5197 1509671 : rtx subop1 = XEXP (trueop0, 1);
5198 1509671 : machine_mode mode0 = GET_MODE (subop0);
5199 1509671 : machine_mode mode1 = GET_MODE (subop1);
5200 1509671 : int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5201 1509671 : if (i0 == 0 && !side_effects_p (op1) && mode == mode0)
5202 : {
5203 962164 : bool success = true;
5204 962164 : for (int i = 1; i < l0; ++i)
5205 : {
5206 961835 : rtx j = XVECEXP (trueop1, 0, i);
5207 961835 : if (!CONST_INT_P (j) || INTVAL (j) != i)
5208 : {
5209 : success = false;
5210 : break;
5211 : }
5212 : }
5213 879168 : if (success)
5214 : return subop0;
5215 : }
5216 1509342 : if (i0 == l0 && !side_effects_p (op0) && mode == mode1)
5217 : {
5218 590 : bool success = true;
5219 590 : for (int i = 1; i < l1; ++i)
5220 : {
5221 543 : rtx j = XVECEXP (trueop1, 0, i);
5222 543 : if (!CONST_INT_P (j) || INTVAL (j) != i0 + i)
5223 : {
5224 : success = false;
5225 : break;
5226 : }
5227 : }
5228 76 : if (success)
5229 : return subop1;
5230 : }
5231 : }
5232 :
5233 : /* Simplify vec_select of a subreg of X to just a vec_select of X
5234 : when X has same component mode as vec_select. */
5235 2439103 : unsigned HOST_WIDE_INT subreg_offset = 0;
5236 2439103 : if (GET_CODE (trueop0) == SUBREG
5237 364730 : && GET_MODE_INNER (mode)
5238 729460 : == GET_MODE_INNER (GET_MODE (SUBREG_REG (trueop0)))
5239 29584 : && GET_MODE_NUNITS (mode).is_constant (&l1)
5240 2803833 : && constant_multiple_p (subreg_memory_offset (trueop0),
5241 29584 : GET_MODE_UNIT_BITSIZE (mode),
5242 : &subreg_offset))
5243 : {
5244 14792 : poly_uint64 nunits
5245 29584 : = GET_MODE_NUNITS (GET_MODE (SUBREG_REG (trueop0)));
5246 14792 : bool success = true;
5247 91526 : for (int i = 0; i != l1; i++)
5248 : {
5249 87083 : rtx idx = XVECEXP (trueop1, 0, i);
5250 87083 : if (!CONST_INT_P (idx)
5251 87083 : || maybe_ge (UINTVAL (idx) + subreg_offset, nunits))
5252 : {
5253 : success = false;
5254 : break;
5255 : }
5256 : }
5257 :
5258 14792 : if (success)
5259 : {
5260 4443 : rtx par = trueop1;
5261 4443 : if (subreg_offset)
5262 : {
5263 0 : rtvec vec = rtvec_alloc (l1);
5264 0 : for (int i = 0; i < l1; i++)
5265 0 : RTVEC_ELT (vec, i)
5266 0 : = GEN_INT (INTVAL (XVECEXP (trueop1, 0, i))
5267 : + subreg_offset);
5268 0 : par = gen_rtx_PARALLEL (VOIDmode, vec);
5269 : }
5270 4443 : return gen_rtx_VEC_SELECT (mode, SUBREG_REG (trueop0), par);
5271 : }
5272 : }
5273 : }
5274 :
5275 3290551 : if (XVECLEN (trueop1, 0) == 1
5276 855975 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
5277 855975 : && GET_CODE (trueop0) == VEC_CONCAT)
5278 : {
5279 1291 : rtx vec = trueop0;
5280 2582 : offset = INTVAL (XVECEXP (trueop1, 0, 0)) * GET_MODE_SIZE (mode);
5281 :
5282 : /* Try to find the element in the VEC_CONCAT. */
5283 1291 : while (GET_MODE (vec) != mode
5284 2582 : && GET_CODE (vec) == VEC_CONCAT)
5285 : {
5286 1291 : poly_int64 vec_size;
5287 :
5288 1291 : if (CONST_INT_P (XEXP (vec, 0)))
5289 : {
5290 : /* vec_concat of two const_ints doesn't make sense with
5291 : respect to modes. */
5292 3 : if (CONST_INT_P (XEXP (vec, 1)))
5293 378833510 : return 0;
5294 :
5295 3 : vec_size = GET_MODE_SIZE (GET_MODE (trueop0))
5296 9 : - GET_MODE_SIZE (GET_MODE (XEXP (vec, 1)));
5297 : }
5298 : else
5299 2576 : vec_size = GET_MODE_SIZE (GET_MODE (XEXP (vec, 0)));
5300 :
5301 1291 : if (known_lt (offset, vec_size))
5302 : vec = XEXP (vec, 0);
5303 230 : else if (known_ge (offset, vec_size))
5304 : {
5305 230 : offset -= vec_size;
5306 230 : vec = XEXP (vec, 1);
5307 : }
5308 : else
5309 : break;
5310 1291 : vec = avoid_constant_pool_reference (vec);
5311 : }
5312 :
5313 1291 : if (GET_MODE (vec) == mode)
5314 : return vec;
5315 : }
5316 :
5317 : /* If we select elements in a vec_merge that all come from the same
5318 : operand, select from that operand directly. */
5319 3289440 : if (GET_CODE (op0) == VEC_MERGE)
5320 : {
5321 9767 : rtx trueop02 = avoid_constant_pool_reference (XEXP (op0, 2));
5322 9767 : if (CONST_INT_P (trueop02))
5323 : {
5324 2999 : unsigned HOST_WIDE_INT sel = UINTVAL (trueop02);
5325 2999 : bool all_operand0 = true;
5326 2999 : bool all_operand1 = true;
5327 10919 : for (int i = 0; i < XVECLEN (trueop1, 0); i++)
5328 : {
5329 7920 : rtx j = XVECEXP (trueop1, 0, i);
5330 7920 : if (sel & (HOST_WIDE_INT_1U << UINTVAL (j)))
5331 : all_operand1 = false;
5332 : else
5333 3562 : all_operand0 = false;
5334 : }
5335 2999 : if (all_operand0 && !side_effects_p (XEXP (op0, 1)))
5336 1460 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 0), op1);
5337 1539 : if (all_operand1 && !side_effects_p (XEXP (op0, 0)))
5338 47 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 1), op1);
5339 : }
5340 : }
5341 :
5342 : /* If we have two nested selects that are inverses of each
5343 : other, replace them with the source operand. */
5344 3287933 : if (GET_CODE (trueop0) == VEC_SELECT
5345 68492 : && GET_MODE (XEXP (trueop0, 0)) == mode)
5346 : {
5347 1030 : rtx op0_subop1 = XEXP (trueop0, 1);
5348 1030 : gcc_assert (GET_CODE (op0_subop1) == PARALLEL);
5349 2060 : gcc_assert (known_eq (XVECLEN (trueop1, 0), GET_MODE_NUNITS (mode)));
5350 : bool identical_p = true;
5351 :
5352 : /* Apply the outer ordering vector to the inner one. (The inner
5353 : ordering vector is expressly permitted to be of a different
5354 : length than the outer one.) If the result is { 0, 1, ..., n-1 }
5355 : then the two VEC_SELECTs cancel. */
5356 8946 : for (int i = 0; i < XVECLEN (trueop1, 0); ++i)
5357 : {
5358 7916 : rtx x = XVECEXP (trueop1, 0, i);
5359 7916 : if (!CONST_INT_P (x))
5360 : return 0;
5361 7916 : rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
5362 7916 : if (!CONST_INT_P (y))
5363 : return 0;
5364 7916 : if (i != INTVAL (y))
5365 5854 : identical_p = false;
5366 : }
5367 1030 : if (identical_p)
5368 : return XEXP (trueop0, 0);
5369 :
5370 : /* Otherwise a permutation of a permutation is a permutation. */
5371 1030 : int len = XVECLEN (trueop1, 0);
5372 1030 : rtvec vec = rtvec_alloc (len);
5373 8946 : for (int i = 0; i < len; ++i)
5374 : {
5375 7916 : rtx x = XVECEXP (trueop1, 0, i);
5376 7916 : rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
5377 7916 : RTVEC_ELT (vec, i) = y;
5378 : }
5379 1030 : return gen_rtx_fmt_ee (code, mode, XEXP (trueop0, 0),
5380 : gen_rtx_PARALLEL (VOIDmode, vec));
5381 : }
5382 :
5383 : return 0;
5384 4090781 : case VEC_CONCAT:
5385 4090781 : {
5386 4090781 : machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
5387 4090781 : ? GET_MODE (trueop0)
5388 4090781 : : GET_MODE_INNER (mode));
5389 4090781 : machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
5390 4090781 : ? GET_MODE (trueop1)
5391 4090781 : : GET_MODE_INNER (mode));
5392 :
5393 4090781 : gcc_assert (VECTOR_MODE_P (mode));
5394 16363124 : gcc_assert (known_eq (GET_MODE_SIZE (op0_mode)
5395 : + GET_MODE_SIZE (op1_mode),
5396 : GET_MODE_SIZE (mode)));
5397 :
5398 4090781 : if (VECTOR_MODE_P (op0_mode))
5399 5661783 : gcc_assert (GET_MODE_INNER (mode)
5400 : == GET_MODE_INNER (op0_mode));
5401 : else
5402 4407040 : gcc_assert (GET_MODE_INNER (mode) == op0_mode);
5403 :
5404 4090781 : if (VECTOR_MODE_P (op1_mode))
5405 5661783 : gcc_assert (GET_MODE_INNER (mode)
5406 : == GET_MODE_INNER (op1_mode));
5407 : else
5408 4407040 : gcc_assert (GET_MODE_INNER (mode) == op1_mode);
5409 :
5410 4090781 : unsigned int n_elts, in_n_elts;
5411 4090781 : if ((GET_CODE (trueop0) == CONST_VECTOR
5412 4090781 : || CONST_SCALAR_INT_P (trueop0)
5413 3938545 : || CONST_DOUBLE_AS_FLOAT_P (trueop0))
5414 153805 : && (GET_CODE (trueop1) == CONST_VECTOR
5415 153805 : || CONST_SCALAR_INT_P (trueop1)
5416 153805 : || CONST_DOUBLE_AS_FLOAT_P (trueop1))
5417 0 : && GET_MODE_NUNITS (mode).is_constant (&n_elts)
5418 4090781 : && GET_MODE_NUNITS (op0_mode).is_constant (&in_n_elts))
5419 : {
5420 0 : rtvec v = rtvec_alloc (n_elts);
5421 0 : unsigned int i;
5422 0 : for (i = 0; i < n_elts; i++)
5423 : {
5424 0 : if (i < in_n_elts)
5425 : {
5426 0 : if (!VECTOR_MODE_P (op0_mode))
5427 0 : RTVEC_ELT (v, i) = trueop0;
5428 : else
5429 0 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
5430 : }
5431 : else
5432 : {
5433 0 : if (!VECTOR_MODE_P (op1_mode))
5434 0 : RTVEC_ELT (v, i) = trueop1;
5435 : else
5436 0 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
5437 : i - in_n_elts);
5438 : }
5439 : }
5440 :
5441 0 : return gen_rtx_CONST_VECTOR (mode, v);
5442 : }
5443 :
5444 : /* Try to merge two VEC_SELECTs from the same vector into a single one.
5445 : Restrict the transformation to avoid generating a VEC_SELECT with a
5446 : mode unrelated to its operand. */
5447 4090781 : if (GET_CODE (trueop0) == VEC_SELECT
5448 131560 : && GET_CODE (trueop1) == VEC_SELECT
5449 28448 : && rtx_equal_p (XEXP (trueop0, 0), XEXP (trueop1, 0))
5450 4106770 : && GET_MODE_INNER (GET_MODE (XEXP (trueop0, 0)))
5451 31978 : == GET_MODE_INNER(mode))
5452 : {
5453 15989 : rtx par0 = XEXP (trueop0, 1);
5454 15989 : rtx par1 = XEXP (trueop1, 1);
5455 15989 : int len0 = XVECLEN (par0, 0);
5456 15989 : int len1 = XVECLEN (par1, 0);
5457 15989 : rtvec vec = rtvec_alloc (len0 + len1);
5458 98806 : for (int i = 0; i < len0; i++)
5459 82817 : RTVEC_ELT (vec, i) = XVECEXP (par0, 0, i);
5460 98806 : for (int i = 0; i < len1; i++)
5461 82817 : RTVEC_ELT (vec, len0 + i) = XVECEXP (par1, 0, i);
5462 15989 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (trueop0, 0),
5463 15989 : gen_rtx_PARALLEL (VOIDmode, vec));
5464 : }
5465 : /* (vec_concat:
5466 : (subreg_lowpart:N OP)
5467 : (vec_select:N OP P)) --> OP when P selects the high half
5468 : of the OP. */
5469 4074792 : if (GET_CODE (trueop0) == SUBREG
5470 483665 : && subreg_lowpart_p (trueop0)
5471 483458 : && GET_CODE (trueop1) == VEC_SELECT
5472 3 : && SUBREG_REG (trueop0) == XEXP (trueop1, 0)
5473 0 : && !side_effects_p (XEXP (trueop1, 0))
5474 4074792 : && vec_series_highpart_p (op1_mode, mode, XEXP (trueop1, 1)))
5475 0 : return XEXP (trueop1, 0);
5476 : }
5477 : return 0;
5478 :
5479 0 : default:
5480 0 : gcc_unreachable ();
5481 : }
5482 :
5483 370995320 : if (mode == GET_MODE (op0)
5484 317454907 : && mode == GET_MODE (op1)
5485 97300851 : && vec_duplicate_p (op0, &elt0)
5486 371111362 : && vec_duplicate_p (op1, &elt1))
5487 : {
5488 : /* Try applying the operator to ELT and see if that simplifies.
5489 : We can duplicate the result if so.
5490 :
5491 : The reason we don't use simplify_gen_binary is that it isn't
5492 : necessarily a win to convert things like:
5493 :
5494 : (plus:V (vec_duplicate:V (reg:S R1))
5495 : (vec_duplicate:V (reg:S R2)))
5496 :
5497 : to:
5498 :
5499 : (vec_duplicate:V (plus:S (reg:S R1) (reg:S R2)))
5500 :
5501 : The first might be done entirely in vector registers while the
5502 : second might need a move between register files. */
5503 120 : tem = simplify_binary_operation (code, GET_MODE_INNER (mode),
5504 : elt0, elt1);
5505 60 : if (tem)
5506 2 : return gen_vec_duplicate (mode, tem);
5507 : }
5508 :
5509 : return 0;
5510 : }
5511 :
5512 : /* Return true if binary operation OP distributes over addition in operand
5513 : OPNO, with the other operand being held constant. OPNO counts from 1. */
5514 :
5515 : static bool
5516 7339 : distributes_over_addition_p (rtx_code op, int opno)
5517 : {
5518 0 : switch (op)
5519 : {
5520 : case PLUS:
5521 : case MINUS:
5522 : case MULT:
5523 : return true;
5524 :
5525 0 : case ASHIFT:
5526 0 : return opno == 1;
5527 :
5528 0 : default:
5529 0 : return false;
5530 : }
5531 : }
5532 :
5533 : rtx
5534 474957637 : simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
5535 : rtx op0, rtx op1)
5536 : {
5537 474957637 : if (VECTOR_MODE_P (mode)
5538 14775495 : && code != VEC_CONCAT
5539 10673418 : && GET_CODE (op0) == CONST_VECTOR
5540 192440 : && GET_CODE (op1) == CONST_VECTOR)
5541 : {
5542 8050 : bool step_ok_p;
5543 8050 : if (CONST_VECTOR_STEPPED_P (op0)
5544 8050 : && CONST_VECTOR_STEPPED_P (op1))
5545 : /* We can operate directly on the encoding if:
5546 :
5547 : a3 - a2 == a2 - a1 && b3 - b2 == b2 - b1
5548 : implies
5549 : (a3 op b3) - (a2 op b2) == (a2 op b2) - (a1 op b1)
5550 :
5551 : Addition and subtraction are the supported operators
5552 : for which this is true. */
5553 711 : step_ok_p = (code == PLUS || code == MINUS);
5554 7339 : else if (CONST_VECTOR_STEPPED_P (op0))
5555 : /* We can operate directly on stepped encodings if:
5556 :
5557 : a3 - a2 == a2 - a1
5558 : implies:
5559 : (a3 op c) - (a2 op c) == (a2 op c) - (a1 op c)
5560 :
5561 : which is true if (x -> x op c) distributes over addition. */
5562 1009 : step_ok_p = distributes_over_addition_p (code, 1);
5563 : else
5564 : /* Similarly in reverse. */
5565 6330 : step_ok_p = distributes_over_addition_p (code, 2);
5566 8050 : rtx_vector_builder builder;
5567 8050 : if (!builder.new_binary_operation (mode, op0, op1, step_ok_p))
5568 : return 0;
5569 :
5570 8050 : unsigned int count = builder.encoded_nelts ();
5571 51658 : for (unsigned int i = 0; i < count; i++)
5572 : {
5573 87316 : rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
5574 : CONST_VECTOR_ELT (op0, i),
5575 43658 : CONST_VECTOR_ELT (op1, i));
5576 43658 : if (!x || !valid_for_const_vector_p (mode, x))
5577 50 : return 0;
5578 43608 : builder.quick_push (x);
5579 : }
5580 8000 : return builder.build ();
5581 8050 : }
5582 :
5583 474949587 : if (VECTOR_MODE_P (mode)
5584 14767445 : && code == VEC_CONCAT
5585 4102077 : && (CONST_SCALAR_INT_P (op0)
5586 3959415 : || CONST_FIXED_P (op0)
5587 3959415 : || CONST_DOUBLE_AS_FLOAT_P (op0)
5588 3956476 : || CONST_VECTOR_P (op0))
5589 165101 : && (CONST_SCALAR_INT_P (op1)
5590 162418 : || CONST_DOUBLE_AS_FLOAT_P (op1)
5591 161048 : || CONST_FIXED_P (op1)
5592 161048 : || CONST_VECTOR_P (op1)))
5593 : {
5594 : /* Both inputs have a constant number of elements, so the result
5595 : must too. */
5596 11296 : unsigned n_elts = GET_MODE_NUNITS (mode).to_constant ();
5597 11296 : rtvec v = rtvec_alloc (n_elts);
5598 :
5599 11296 : gcc_assert (n_elts >= 2);
5600 11296 : if (n_elts == 2)
5601 : {
5602 4053 : gcc_assert (GET_CODE (op0) != CONST_VECTOR);
5603 4053 : gcc_assert (GET_CODE (op1) != CONST_VECTOR);
5604 :
5605 4053 : RTVEC_ELT (v, 0) = op0;
5606 4053 : RTVEC_ELT (v, 1) = op1;
5607 : }
5608 : else
5609 : {
5610 7243 : unsigned op0_n_elts = GET_MODE_NUNITS (GET_MODE (op0)).to_constant ();
5611 7243 : unsigned op1_n_elts = GET_MODE_NUNITS (GET_MODE (op1)).to_constant ();
5612 7243 : unsigned i;
5613 :
5614 7243 : gcc_assert (GET_CODE (op0) == CONST_VECTOR);
5615 7243 : gcc_assert (GET_CODE (op1) == CONST_VECTOR);
5616 7243 : gcc_assert (op0_n_elts + op1_n_elts == n_elts);
5617 :
5618 47623 : for (i = 0; i < op0_n_elts; ++i)
5619 40380 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op0, i);
5620 47815 : for (i = 0; i < op1_n_elts; ++i)
5621 40572 : RTVEC_ELT (v, op0_n_elts+i) = CONST_VECTOR_ELT (op1, i);
5622 : }
5623 :
5624 11296 : return gen_rtx_CONST_VECTOR (mode, v);
5625 : }
5626 :
5627 463398641 : if (VECTOR_MODE_P (mode)
5628 14756149 : && GET_CODE (op0) == CONST_VECTOR
5629 196647 : && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1))
5630 474938291 : && (CONST_VECTOR_DUPLICATE_P (op0)
5631 : || CONST_VECTOR_NUNITS (op0).is_constant ()))
5632 : {
5633 140823 : switch (code)
5634 : {
5635 140823 : case PLUS:
5636 140823 : case MINUS:
5637 140823 : case MULT:
5638 140823 : case DIV:
5639 140823 : case MOD:
5640 140823 : case UDIV:
5641 140823 : case UMOD:
5642 140823 : case AND:
5643 140823 : case IOR:
5644 140823 : case XOR:
5645 140823 : case SMIN:
5646 140823 : case SMAX:
5647 140823 : case UMIN:
5648 140823 : case UMAX:
5649 140823 : case LSHIFTRT:
5650 140823 : case ASHIFTRT:
5651 140823 : case ASHIFT:
5652 140823 : case ROTATE:
5653 140823 : case ROTATERT:
5654 140823 : case SS_PLUS:
5655 140823 : case US_PLUS:
5656 140823 : case SS_MINUS:
5657 140823 : case US_MINUS:
5658 140823 : case SS_ASHIFT:
5659 140823 : case US_ASHIFT:
5660 140823 : case COPYSIGN:
5661 140823 : break;
5662 : default:
5663 : return NULL_RTX;
5664 : }
5665 :
5666 140823 : unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op0)
5667 140823 : ? CONST_VECTOR_NPATTERNS (op0)
5668 148556 : : CONST_VECTOR_NUNITS (op0).to_constant ());
5669 140823 : rtx_vector_builder builder (mode, npatterns, 1);
5670 294717 : for (unsigned i = 0; i < npatterns; i++)
5671 : {
5672 307788 : rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
5673 153894 : CONST_VECTOR_ELT (op0, i), op1);
5674 153894 : if (!x || !valid_for_const_vector_p (mode, x))
5675 0 : return 0;
5676 153894 : builder.quick_push (x);
5677 : }
5678 140823 : return builder.build ();
5679 : }
5680 :
5681 474797468 : if (SCALAR_FLOAT_MODE_P (mode)
5682 6368347 : && CONST_DOUBLE_AS_FLOAT_P (op0)
5683 75708 : && CONST_DOUBLE_AS_FLOAT_P (op1)
5684 11530 : && mode == GET_MODE (op0) && mode == GET_MODE (op1))
5685 : {
5686 11530 : if (code == AND
5687 : || code == IOR
5688 11530 : || code == XOR)
5689 : {
5690 2515 : long tmp0[4];
5691 2515 : long tmp1[4];
5692 2515 : REAL_VALUE_TYPE r;
5693 2515 : int i;
5694 :
5695 2515 : real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0),
5696 2515 : GET_MODE (op0));
5697 2515 : real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1),
5698 2515 : GET_MODE (op1));
5699 12575 : for (i = 0; i < 4; i++)
5700 : {
5701 10060 : switch (code)
5702 : {
5703 5268 : case AND:
5704 5268 : tmp0[i] &= tmp1[i];
5705 5268 : break;
5706 2512 : case IOR:
5707 2512 : tmp0[i] |= tmp1[i];
5708 2512 : break;
5709 2280 : case XOR:
5710 2280 : tmp0[i] ^= tmp1[i];
5711 2280 : break;
5712 : default:
5713 : gcc_unreachable ();
5714 : }
5715 : }
5716 2515 : real_from_target (&r, tmp0, mode);
5717 2515 : return const_double_from_real_value (r, mode);
5718 : }
5719 9015 : else if (code == COPYSIGN)
5720 : {
5721 0 : REAL_VALUE_TYPE f0, f1;
5722 0 : real_convert (&f0, mode, CONST_DOUBLE_REAL_VALUE (op0));
5723 0 : real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (op1));
5724 0 : real_copysign (&f0, &f1);
5725 0 : return const_double_from_real_value (f0, mode);
5726 : }
5727 : else
5728 : {
5729 9015 : REAL_VALUE_TYPE f0, f1, value, result;
5730 9015 : const REAL_VALUE_TYPE *opr0, *opr1;
5731 9015 : bool inexact;
5732 :
5733 9015 : opr0 = CONST_DOUBLE_REAL_VALUE (op0);
5734 9015 : opr1 = CONST_DOUBLE_REAL_VALUE (op1);
5735 :
5736 9015 : if (HONOR_SNANS (mode)
5737 9015 : && (REAL_VALUE_ISSIGNALING_NAN (*opr0)
5738 803 : || REAL_VALUE_ISSIGNALING_NAN (*opr1)))
5739 10 : return 0;
5740 :
5741 9005 : real_convert (&f0, mode, opr0);
5742 9005 : real_convert (&f1, mode, opr1);
5743 :
5744 9005 : if (code == DIV
5745 4108 : && real_equal (&f1, &dconst0)
5746 12649 : && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
5747 3640 : return 0;
5748 :
5749 26724 : if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
5750 5273 : && flag_trapping_math
5751 5197 : && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
5752 : {
5753 9 : int s0 = REAL_VALUE_NEGATIVE (f0);
5754 9 : int s1 = REAL_VALUE_NEGATIVE (f1);
5755 :
5756 9 : switch (code)
5757 : {
5758 0 : case PLUS:
5759 : /* Inf + -Inf = NaN plus exception. */
5760 0 : if (s0 != s1)
5761 : return 0;
5762 : break;
5763 0 : case MINUS:
5764 : /* Inf - Inf = NaN plus exception. */
5765 0 : if (s0 == s1)
5766 : return 0;
5767 : break;
5768 : case DIV:
5769 : /* Inf / Inf = NaN plus exception. */
5770 : return 0;
5771 : default:
5772 : break;
5773 : }
5774 : }
5775 :
5776 7944 : if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
5777 1952 : && flag_trapping_math
5778 7262 : && ((REAL_VALUE_ISINF (f0) && real_equal (&f1, &dconst0))
5779 1898 : || (REAL_VALUE_ISINF (f1)
5780 10 : && real_equal (&f0, &dconst0))))
5781 : /* Inf * 0 = NaN plus exception. */
5782 18 : return 0;
5783 :
5784 5338 : inexact = real_arithmetic (&value, rtx_to_tree_code (code),
5785 : &f0, &f1);
5786 5338 : real_convert (&result, mode, &value);
5787 :
5788 : /* Don't constant fold this floating point operation if
5789 : the result has overflowed and flag_trapping_math. */
5790 :
5791 5338 : if (flag_trapping_math
5792 20680 : && MODE_HAS_INFINITIES (mode)
5793 5170 : && REAL_VALUE_ISINF (result)
5794 1104 : && !REAL_VALUE_ISINF (f0)
5795 6428 : && !REAL_VALUE_ISINF (f1))
5796 : /* Overflow plus exception. */
5797 1090 : return 0;
5798 :
5799 : /* Don't constant fold this floating point operation if the
5800 : result may dependent upon the run-time rounding mode and
5801 : flag_rounding_math is set, or if GCC's software emulation
5802 : is unable to accurately represent the result. */
5803 :
5804 4248 : if ((flag_rounding_math
5805 27055 : || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
5806 4248 : && (inexact || !real_identical (&result, &value)))
5807 378 : return NULL_RTX;
5808 :
5809 3870 : return const_double_from_real_value (result, mode);
5810 : }
5811 : }
5812 :
5813 : /* We can fold some multi-word operations. */
5814 474785938 : scalar_int_mode int_mode;
5815 474785938 : if (is_a <scalar_int_mode> (mode, &int_mode)
5816 405775496 : && CONST_SCALAR_INT_P (op0)
5817 39713710 : && CONST_SCALAR_INT_P (op1)
5818 33265283 : && GET_MODE_PRECISION (int_mode) <= MAX_BITSIZE_MODE_ANY_INT)
5819 : {
5820 33265283 : wide_int result;
5821 33265283 : wi::overflow_type overflow;
5822 33265283 : rtx_mode_t pop0 = rtx_mode_t (op0, int_mode);
5823 33265283 : rtx_mode_t pop1 = rtx_mode_t (op1, int_mode);
5824 :
5825 : #if TARGET_SUPPORTS_WIDE_INT == 0
5826 : /* This assert keeps the simplification from producing a result
5827 : that cannot be represented in a CONST_DOUBLE but a lot of
5828 : upstream callers expect that this function never fails to
5829 : simplify something and so you if you added this to the test
5830 : above the code would die later anyway. If this assert
5831 : happens, you just need to make the port support wide int. */
5832 : gcc_assert (GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_DOUBLE_INT);
5833 : #endif
5834 33265283 : switch (code)
5835 : {
5836 1095713 : case MINUS:
5837 1095713 : result = wi::sub (pop0, pop1);
5838 1095713 : break;
5839 :
5840 26116701 : case PLUS:
5841 26116701 : result = wi::add (pop0, pop1);
5842 26116701 : break;
5843 :
5844 316284 : case MULT:
5845 316284 : result = wi::mul (pop0, pop1);
5846 316284 : break;
5847 :
5848 7098 : case DIV:
5849 7098 : result = wi::div_trunc (pop0, pop1, SIGNED, &overflow);
5850 7098 : if (overflow)
5851 : return NULL_RTX;
5852 : break;
5853 :
5854 1238 : case MOD:
5855 1238 : result = wi::mod_trunc (pop0, pop1, SIGNED, &overflow);
5856 1238 : if (overflow)
5857 : return NULL_RTX;
5858 : break;
5859 :
5860 6415 : case UDIV:
5861 6415 : result = wi::div_trunc (pop0, pop1, UNSIGNED, &overflow);
5862 6415 : if (overflow)
5863 : return NULL_RTX;
5864 : break;
5865 :
5866 16135 : case UMOD:
5867 16135 : result = wi::mod_trunc (pop0, pop1, UNSIGNED, &overflow);
5868 16135 : if (overflow)
5869 : return NULL_RTX;
5870 : break;
5871 :
5872 585945 : case AND:
5873 585945 : result = wi::bit_and (pop0, pop1);
5874 585945 : break;
5875 :
5876 270572 : case IOR:
5877 270572 : result = wi::bit_or (pop0, pop1);
5878 270572 : break;
5879 :
5880 56570 : case XOR:
5881 56570 : result = wi::bit_xor (pop0, pop1);
5882 56570 : break;
5883 :
5884 1761 : case SMIN:
5885 1761 : result = wi::smin (pop0, pop1);
5886 1761 : break;
5887 :
5888 1849 : case SMAX:
5889 1849 : result = wi::smax (pop0, pop1);
5890 1849 : break;
5891 :
5892 3399 : case UMIN:
5893 3399 : result = wi::umin (pop0, pop1);
5894 3399 : break;
5895 :
5896 2998 : case UMAX:
5897 2998 : result = wi::umax (pop0, pop1);
5898 2998 : break;
5899 :
5900 4739528 : case LSHIFTRT:
5901 4739528 : case ASHIFTRT:
5902 4739528 : case ASHIFT:
5903 4739528 : case SS_ASHIFT:
5904 4739528 : case US_ASHIFT:
5905 4739528 : {
5906 : /* The shift count might be in SImode while int_mode might
5907 : be narrower. On IA-64 it is even DImode. If the shift
5908 : count is too large and doesn't fit into int_mode, we'd
5909 : ICE. So, if int_mode is narrower than
5910 : HOST_BITS_PER_WIDE_INT, use DImode for the shift count. */
5911 4739528 : if (GET_MODE (op1) == VOIDmode
5912 4739528 : && GET_MODE_PRECISION (int_mode) < HOST_BITS_PER_WIDE_INT)
5913 1833476 : pop1 = rtx_mode_t (op1, DImode);
5914 :
5915 4739528 : wide_int wop1 = pop1;
5916 4739528 : if (SHIFT_COUNT_TRUNCATED)
5917 : wop1 = wi::umod_trunc (wop1, GET_MODE_PRECISION (int_mode));
5918 4739528 : else if (wi::geu_p (wop1, GET_MODE_PRECISION (int_mode)))
5919 132 : return NULL_RTX;
5920 :
5921 4739396 : switch (code)
5922 : {
5923 2734692 : case LSHIFTRT:
5924 2734692 : result = wi::lrshift (pop0, wop1);
5925 2734692 : break;
5926 :
5927 71483 : case ASHIFTRT:
5928 71483 : result = wi::arshift (pop0, wop1);
5929 71483 : break;
5930 :
5931 1933221 : case ASHIFT:
5932 1933221 : result = wi::lshift (pop0, wop1);
5933 1933221 : break;
5934 :
5935 0 : case SS_ASHIFT:
5936 0 : if (wi::leu_p (wop1, wi::clrsb (pop0)))
5937 0 : result = wi::lshift (pop0, wop1);
5938 0 : else if (wi::neg_p (pop0))
5939 0 : result = wi::min_value (int_mode, SIGNED);
5940 : else
5941 0 : result = wi::max_value (int_mode, SIGNED);
5942 : break;
5943 :
5944 0 : case US_ASHIFT:
5945 0 : if (wi::eq_p (pop0, 0))
5946 0 : result = pop0;
5947 0 : else if (wi::leu_p (wop1, wi::clz (pop0)))
5948 0 : result = wi::lshift (pop0, wop1);
5949 : else
5950 0 : result = wi::max_value (int_mode, UNSIGNED);
5951 : break;
5952 :
5953 0 : default:
5954 0 : gcc_unreachable ();
5955 : }
5956 4739396 : break;
5957 4739528 : }
5958 34513 : case ROTATE:
5959 34513 : case ROTATERT:
5960 34513 : {
5961 : /* The rotate count might be in SImode while int_mode might
5962 : be narrower. On IA-64 it is even DImode. If the shift
5963 : count is too large and doesn't fit into int_mode, we'd
5964 : ICE. So, if int_mode is narrower than
5965 : HOST_BITS_PER_WIDE_INT, use DImode for the shift count. */
5966 34513 : if (GET_MODE (op1) == VOIDmode
5967 34513 : && GET_MODE_PRECISION (int_mode) < HOST_BITS_PER_WIDE_INT)
5968 27541 : pop1 = rtx_mode_t (op1, DImode);
5969 :
5970 34513 : if (wi::neg_p (pop1))
5971 : return NULL_RTX;
5972 :
5973 34413 : switch (code)
5974 : {
5975 11605 : case ROTATE:
5976 11605 : result = wi::lrotate (pop0, pop1);
5977 11605 : break;
5978 :
5979 22808 : case ROTATERT:
5980 22808 : result = wi::rrotate (pop0, pop1);
5981 22808 : break;
5982 :
5983 0 : default:
5984 0 : gcc_unreachable ();
5985 : }
5986 : break;
5987 : }
5988 :
5989 2270 : case SS_PLUS:
5990 2270 : result = wi::add (pop0, pop1, SIGNED, &overflow);
5991 4484 : clamp_signed_saturation:
5992 4484 : if (overflow == wi::OVF_OVERFLOW)
5993 314 : result = wi::max_value (GET_MODE_PRECISION (int_mode), SIGNED);
5994 4170 : else if (overflow == wi::OVF_UNDERFLOW)
5995 278 : result = wi::min_value (GET_MODE_PRECISION (int_mode), SIGNED);
5996 3892 : else if (overflow != wi::OVF_NONE)
5997 : return NULL_RTX;
5998 : break;
5999 :
6000 2220 : case US_PLUS:
6001 2220 : result = wi::add (pop0, pop1, UNSIGNED, &overflow);
6002 2220 : clamp_unsigned_saturation:
6003 2220 : if (overflow != wi::OVF_NONE)
6004 461 : result = wi::max_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
6005 : break;
6006 :
6007 2214 : case SS_MINUS:
6008 2214 : result = wi::sub (pop0, pop1, SIGNED, &overflow);
6009 2214 : goto clamp_signed_saturation;
6010 :
6011 1852 : case US_MINUS:
6012 1852 : result = wi::sub (pop0, pop1, UNSIGNED, &overflow);
6013 1852 : if (overflow != wi::OVF_NONE)
6014 1203 : result = wi::min_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
6015 : break;
6016 :
6017 0 : case SS_MULT:
6018 0 : result = wi::mul (pop0, pop1, SIGNED, &overflow);
6019 0 : goto clamp_signed_saturation;
6020 :
6021 0 : case US_MULT:
6022 0 : result = wi::mul (pop0, pop1, UNSIGNED, &overflow);
6023 0 : goto clamp_unsigned_saturation;
6024 :
6025 8 : case SMUL_HIGHPART:
6026 8 : result = wi::mul_high (pop0, pop1, SIGNED);
6027 8 : break;
6028 :
6029 0 : case UMUL_HIGHPART:
6030 0 : result = wi::mul_high (pop0, pop1, UNSIGNED);
6031 0 : break;
6032 :
6033 : default:
6034 : return NULL_RTX;
6035 : }
6036 33262818 : return immed_wide_int_const (result, int_mode);
6037 33265283 : }
6038 :
6039 : /* Handle polynomial integers. */
6040 : if (NUM_POLY_INT_COEFFS > 1
6041 : && is_a <scalar_int_mode> (mode, &int_mode)
6042 : && poly_int_rtx_p (op0)
6043 : && poly_int_rtx_p (op1))
6044 : {
6045 : poly_wide_int result;
6046 : switch (code)
6047 : {
6048 : case PLUS:
6049 : result = wi::to_poly_wide (op0, mode) + wi::to_poly_wide (op1, mode);
6050 : break;
6051 :
6052 : case MINUS:
6053 : result = wi::to_poly_wide (op0, mode) - wi::to_poly_wide (op1, mode);
6054 : break;
6055 :
6056 : case MULT:
6057 : if (CONST_SCALAR_INT_P (op1))
6058 : result = wi::to_poly_wide (op0, mode) * rtx_mode_t (op1, mode);
6059 : else
6060 : return NULL_RTX;
6061 : break;
6062 :
6063 : case ASHIFT:
6064 : if (CONST_SCALAR_INT_P (op1))
6065 : {
6066 : wide_int shift
6067 : = rtx_mode_t (op1,
6068 : GET_MODE (op1) == VOIDmode
6069 : && (GET_MODE_PRECISION (int_mode)
6070 : < HOST_BITS_PER_WIDE_INT)
6071 : ? DImode : mode);
6072 : if (SHIFT_COUNT_TRUNCATED)
6073 : shift = wi::umod_trunc (shift, GET_MODE_PRECISION (int_mode));
6074 : else if (wi::geu_p (shift, GET_MODE_PRECISION (int_mode)))
6075 : return NULL_RTX;
6076 : result = wi::to_poly_wide (op0, mode) << shift;
6077 : }
6078 : else
6079 : return NULL_RTX;
6080 : break;
6081 :
6082 : case IOR:
6083 : if (!CONST_SCALAR_INT_P (op1)
6084 : || !can_ior_p (wi::to_poly_wide (op0, mode),
6085 : rtx_mode_t (op1, mode), &result))
6086 : return NULL_RTX;
6087 : break;
6088 :
6089 : default:
6090 : return NULL_RTX;
6091 : }
6092 : return immed_wide_int_const (result, int_mode);
6093 : }
6094 :
6095 : return NULL_RTX;
6096 : }
6097 :
6098 :
6099 :
6100 : /* Return a positive integer if X should sort after Y. The value
6101 : returned is 1 if and only if X and Y are both regs. */
6102 :
6103 : static int
6104 113878990 : simplify_plus_minus_op_data_cmp (rtx x, rtx y)
6105 : {
6106 113878990 : int result;
6107 :
6108 113878990 : result = (commutative_operand_precedence (y)
6109 113878990 : - commutative_operand_precedence (x));
6110 113878990 : if (result)
6111 79866152 : return result + result;
6112 :
6113 : /* Group together equal REGs to do more simplification. */
6114 34012838 : if (REG_P (x) && REG_P (y))
6115 8588491 : return REGNO (x) > REGNO (y);
6116 :
6117 : return 0;
6118 : }
6119 :
6120 : /* Simplify and canonicalize a PLUS or MINUS, at least one of whose
6121 : operands may be another PLUS or MINUS.
6122 :
6123 : Rather than test for specific case, we do this by a brute-force method
6124 : and do all possible simplifications until no more changes occur. Then
6125 : we rebuild the operation.
6126 :
6127 : May return NULL_RTX when no changes were made. */
6128 :
6129 : rtx
6130 38222107 : simplify_context::simplify_plus_minus (rtx_code code, machine_mode mode,
6131 : rtx op0, rtx op1)
6132 : {
6133 38222107 : struct simplify_plus_minus_op_data
6134 : {
6135 : rtx op;
6136 : short neg;
6137 : } ops[16];
6138 38222107 : rtx result, tem;
6139 38222107 : int n_ops = 2;
6140 38222107 : int changed, n_constants, canonicalized = 0;
6141 38222107 : int i, j;
6142 :
6143 38222107 : memset (ops, 0, sizeof ops);
6144 :
6145 : /* Set up the two operands and then expand them until nothing has been
6146 : changed. If we run out of room in our array, give up; this should
6147 : almost never happen. */
6148 :
6149 38222107 : ops[0].op = op0;
6150 38222107 : ops[0].neg = 0;
6151 38222107 : ops[1].op = op1;
6152 38222107 : ops[1].neg = (code == MINUS);
6153 :
6154 77835990 : do
6155 : {
6156 77835990 : changed = 0;
6157 77835990 : n_constants = 0;
6158 :
6159 315293075 : for (i = 0; i < n_ops; i++)
6160 : {
6161 237457100 : rtx this_op = ops[i].op;
6162 237457100 : int this_neg = ops[i].neg;
6163 237457100 : enum rtx_code this_code = GET_CODE (this_op);
6164 :
6165 237457100 : switch (this_code)
6166 : {
6167 38741007 : case PLUS:
6168 38741007 : case MINUS:
6169 38741007 : if (n_ops == ARRAY_SIZE (ops))
6170 : return NULL_RTX;
6171 :
6172 38740992 : ops[n_ops].op = XEXP (this_op, 1);
6173 38740992 : ops[n_ops].neg = (this_code == MINUS) ^ this_neg;
6174 38740992 : n_ops++;
6175 :
6176 38740992 : ops[i].op = XEXP (this_op, 0);
6177 38740992 : changed = 1;
6178 : /* If this operand was negated then we will potentially
6179 : canonicalize the expression. Similarly if we don't
6180 : place the operands adjacent we're re-ordering the
6181 : expression and thus might be performing a
6182 : canonicalization. Ignore register re-ordering.
6183 : ??? It might be better to shuffle the ops array here,
6184 : but then (plus (plus (A, B), plus (C, D))) wouldn't
6185 : be seen as non-canonical. */
6186 38740992 : if (this_neg
6187 38050664 : || (i != n_ops - 2
6188 37364369 : && !(REG_P (ops[i].op) && REG_P (ops[n_ops - 1].op))))
6189 237457085 : canonicalized = 1;
6190 : break;
6191 :
6192 1716 : case NEG:
6193 1716 : ops[i].op = XEXP (this_op, 0);
6194 1716 : ops[i].neg = ! this_neg;
6195 1716 : changed = 1;
6196 1716 : canonicalized = 1;
6197 1716 : break;
6198 :
6199 1503887 : case CONST:
6200 1503887 : if (n_ops != ARRAY_SIZE (ops)
6201 1503887 : && GET_CODE (XEXP (this_op, 0)) == PLUS
6202 1379601 : && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
6203 1359984 : && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
6204 : {
6205 1359984 : ops[i].op = XEXP (XEXP (this_op, 0), 0);
6206 1359984 : ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
6207 1359984 : ops[n_ops].neg = this_neg;
6208 1359984 : n_ops++;
6209 1359984 : changed = 1;
6210 1359984 : canonicalized = 1;
6211 : }
6212 : break;
6213 :
6214 40381 : case NOT:
6215 : /* ~a -> (-a - 1) */
6216 40381 : if (n_ops != ARRAY_SIZE (ops))
6217 : {
6218 40381 : ops[n_ops].op = CONSTM1_RTX (mode);
6219 40381 : ops[n_ops++].neg = this_neg;
6220 40381 : ops[i].op = XEXP (this_op, 0);
6221 40381 : ops[i].neg = !this_neg;
6222 40381 : changed = 1;
6223 40381 : canonicalized = 1;
6224 : }
6225 : break;
6226 :
6227 119375491 : CASE_CONST_SCALAR_INT:
6228 119375491 : case CONST_POLY_INT:
6229 119375491 : n_constants++;
6230 119375491 : if (this_neg)
6231 : {
6232 1175254 : ops[i].op = neg_poly_int_rtx (mode, this_op);
6233 1175254 : ops[i].neg = 0;
6234 1175254 : changed = 1;
6235 1175254 : canonicalized = 1;
6236 : }
6237 : break;
6238 :
6239 : default:
6240 : break;
6241 : }
6242 : }
6243 : }
6244 77835975 : while (changed);
6245 :
6246 38222092 : if (n_constants > 1)
6247 23668996 : canonicalized = 1;
6248 :
6249 38222092 : gcc_assert (n_ops >= 2);
6250 :
6251 : /* If we only have two operands, we can avoid the loops. */
6252 38222092 : if (n_ops == 2)
6253 : {
6254 0 : enum rtx_code code = ops[0].neg || ops[1].neg ? MINUS : PLUS;
6255 0 : rtx lhs, rhs;
6256 :
6257 : /* Get the two operands. Be careful with the order, especially for
6258 : the cases where code == MINUS. */
6259 0 : if (ops[0].neg && ops[1].neg)
6260 : {
6261 0 : lhs = gen_rtx_NEG (mode, ops[0].op);
6262 0 : rhs = ops[1].op;
6263 : }
6264 0 : else if (ops[0].neg)
6265 : {
6266 0 : lhs = ops[1].op;
6267 0 : rhs = ops[0].op;
6268 : }
6269 : else
6270 : {
6271 0 : lhs = ops[0].op;
6272 0 : rhs = ops[1].op;
6273 : }
6274 :
6275 0 : return simplify_const_binary_operation (code, mode, lhs, rhs);
6276 : }
6277 :
6278 : /* Now simplify each pair of operands until nothing changes. */
6279 62669777 : while (1)
6280 : {
6281 : /* Insertion sort is good enough for a small array. */
6282 166030293 : for (i = 1; i < n_ops; i++)
6283 : {
6284 103360516 : struct simplify_plus_minus_op_data save;
6285 103360516 : int cmp;
6286 :
6287 103360516 : j = i - 1;
6288 103360516 : cmp = simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op);
6289 103360516 : if (cmp <= 0)
6290 91093442 : continue;
6291 : /* Just swapping registers doesn't count as canonicalization. */
6292 12267074 : if (cmp != 1)
6293 9305470 : canonicalized = 1;
6294 :
6295 12267074 : save = ops[i];
6296 14696400 : do
6297 14696400 : ops[j + 1] = ops[j];
6298 14696400 : while (j--
6299 26963474 : && simplify_plus_minus_op_data_cmp (ops[j].op, save.op) > 0);
6300 12267074 : ops[j + 1] = save;
6301 : }
6302 :
6303 62669777 : changed = 0;
6304 166030293 : for (i = n_ops - 1; i > 0; i--)
6305 248293259 : for (j = i - 1; j >= 0; j--)
6306 : {
6307 145767606 : rtx lhs = ops[j].op, rhs = ops[i].op;
6308 145767606 : int lneg = ops[j].neg, rneg = ops[i].neg;
6309 :
6310 145767606 : if (lhs != 0 && rhs != 0)
6311 : {
6312 120422028 : enum rtx_code ncode = PLUS;
6313 :
6314 120422028 : if (lneg != rneg)
6315 : {
6316 10503753 : ncode = MINUS;
6317 10503753 : if (lneg)
6318 6728002 : std::swap (lhs, rhs);
6319 : }
6320 109918275 : else if (swap_commutative_operands_p (lhs, rhs))
6321 216467 : std::swap (lhs, rhs);
6322 :
6323 120422028 : if ((GET_CODE (lhs) == CONST || CONST_INT_P (lhs))
6324 28208250 : && (GET_CODE (rhs) == CONST || CONST_INT_P (rhs)))
6325 : {
6326 23818316 : rtx tem_lhs, tem_rhs;
6327 :
6328 23818316 : tem_lhs = GET_CODE (lhs) == CONST ? XEXP (lhs, 0) : lhs;
6329 23818316 : tem_rhs = GET_CODE (rhs) == CONST ? XEXP (rhs, 0) : rhs;
6330 23818316 : tem = simplify_binary_operation (ncode, mode, tem_lhs,
6331 : tem_rhs);
6332 :
6333 23818316 : if (tem && !CONSTANT_P (tem))
6334 1754 : tem = gen_rtx_CONST (GET_MODE (tem), tem);
6335 : }
6336 : else
6337 96603712 : tem = simplify_binary_operation (ncode, mode, lhs, rhs);
6338 :
6339 96605466 : if (tem)
6340 : {
6341 : /* Reject "simplifications" that just wrap the two
6342 : arguments in a CONST. Failure to do so can result
6343 : in infinite recursion with simplify_binary_operation
6344 : when it calls us to simplify CONST operations.
6345 : Also, if we find such a simplification, don't try
6346 : any more combinations with this rhs: We must have
6347 : something like symbol+offset, ie. one of the
6348 : trivial CONST expressions we handle later. */
6349 25744073 : if (GET_CODE (tem) == CONST
6350 836617 : && GET_CODE (XEXP (tem, 0)) == ncode
6351 836068 : && XEXP (XEXP (tem, 0), 0) == lhs
6352 834863 : && XEXP (XEXP (tem, 0), 1) == rhs)
6353 : break;
6354 24909210 : lneg &= rneg;
6355 24909210 : if (GET_CODE (tem) == NEG)
6356 45724 : tem = XEXP (tem, 0), lneg = !lneg;
6357 24909210 : if (poly_int_rtx_p (tem) && lneg)
6358 0 : tem = neg_poly_int_rtx (mode, tem), lneg = 0;
6359 :
6360 24909210 : ops[i].op = tem;
6361 24909210 : ops[i].neg = lneg;
6362 24909210 : ops[j].op = NULL_RTX;
6363 24909210 : changed = 1;
6364 24909210 : canonicalized = 1;
6365 : }
6366 : }
6367 : }
6368 :
6369 62669777 : if (!changed)
6370 : break;
6371 :
6372 : /* Pack all the operands to the lower-numbered entries. */
6373 98801857 : for (i = 0, j = 0; j < n_ops; j++)
6374 74354172 : if (ops[j].op)
6375 : {
6376 49444962 : ops[i] = ops[j];
6377 49444962 : i++;
6378 : }
6379 : n_ops = i;
6380 : }
6381 :
6382 : /* If nothing changed, check that rematerialization of rtl instructions
6383 : is still required. */
6384 38222092 : if (!canonicalized)
6385 : {
6386 : /* Perform rematerialization if only all operands are registers and
6387 : all operations are PLUS. */
6388 : /* ??? Also disallow (non-global, non-frame) fixed registers to work
6389 : around rs6000 and how it uses the CA register. See PR67145. */
6390 5093876 : for (i = 0; i < n_ops; i++)
6391 4108251 : if (ops[i].neg
6392 3839193 : || !REG_P (ops[i].op)
6393 7369936 : || (REGNO (ops[i].op) < FIRST_PSEUDO_REGISTER
6394 314475 : && fixed_regs[REGNO (ops[i].op)]
6395 189 : && !global_regs[REGNO (ops[i].op)]
6396 189 : && ops[i].op != frame_pointer_rtx
6397 101 : && ops[i].op != arg_pointer_rtx
6398 88 : && ops[i].op != stack_pointer_rtx))
6399 : return NULL_RTX;
6400 985625 : goto gen_result;
6401 : }
6402 :
6403 : /* Create (minus -C X) instead of (neg (const (plus X C))). */
6404 36389901 : if (n_ops == 2
6405 22728142 : && CONST_INT_P (ops[1].op)
6406 22267295 : && CONSTANT_P (ops[0].op)
6407 162 : && ops[0].neg)
6408 56 : return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
6409 :
6410 : /* We suppressed creation of trivial CONST expressions in the
6411 : combination loop to avoid recursion. Create one manually now.
6412 : The combination loop should have ensured that there is exactly
6413 : one CONST_INT, and the sort will have ensured that it is last
6414 : in the array and that any other constant will be next-to-last. */
6415 :
6416 36389845 : if (n_ops > 1
6417 35873451 : && poly_int_rtx_p (ops[n_ops - 1].op)
6418 70095217 : && CONSTANT_P (ops[n_ops - 2].op))
6419 : {
6420 1432482 : rtx value = ops[n_ops - 1].op;
6421 1432482 : if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg)
6422 683065 : value = neg_poly_int_rtx (mode, value);
6423 1432482 : if (CONST_INT_P (value))
6424 : {
6425 2864964 : ops[n_ops - 2].op = plus_constant (mode, ops[n_ops - 2].op,
6426 1432482 : INTVAL (value));
6427 1432482 : n_ops--;
6428 : }
6429 : }
6430 :
6431 : /* Put a non-negated operand first, if possible. */
6432 :
6433 38066644 : for (i = 0; i < n_ops && ops[i].neg; i++)
6434 1676799 : continue;
6435 36389845 : if (i == n_ops)
6436 9249 : ops[0].op = gen_rtx_NEG (mode, ops[0].op);
6437 36380596 : else if (i != 0)
6438 : {
6439 1576991 : tem = ops[0].op;
6440 1576991 : ops[0] = ops[i];
6441 1576991 : ops[i].op = tem;
6442 1576991 : ops[i].neg = 1;
6443 : }
6444 :
6445 : /* Now make the result by performing the requested operations. */
6446 34803605 : gen_result:
6447 37375470 : result = ops[0].op;
6448 87701942 : for (i = 1; i < n_ops; i++)
6449 100652944 : result = gen_rtx_fmt_ee (ops[i].neg ? MINUS : PLUS,
6450 : mode, result, ops[i].op);
6451 :
6452 : return result;
6453 1676799 : }
6454 :
6455 : /* Check whether an operand is suitable for calling simplify_plus_minus. */
6456 : static bool
6457 515207360 : plus_minus_operand_p (const_rtx x)
6458 : {
6459 515207360 : return GET_CODE (x) == PLUS
6460 515207360 : || GET_CODE (x) == MINUS
6461 515207360 : || (GET_CODE (x) == CONST
6462 1874927 : && GET_CODE (XEXP (x, 0)) == PLUS
6463 1261259 : && CONSTANT_P (XEXP (XEXP (x, 0), 0))
6464 1188537 : && CONSTANT_P (XEXP (XEXP (x, 0), 1)));
6465 : }
6466 :
6467 : /* Like simplify_binary_operation except used for relational operators.
6468 : MODE is the mode of the result. If MODE is VOIDmode, both operands must
6469 : not also be VOIDmode.
6470 :
6471 : CMP_MODE specifies in which mode the comparison is done in, so it is
6472 : the mode of the operands. If CMP_MODE is VOIDmode, it is taken from
6473 : the operands or, if both are VOIDmode, the operands are compared in
6474 : "infinite precision". */
6475 : rtx
6476 129658768 : simplify_context::simplify_relational_operation (rtx_code code,
6477 : machine_mode mode,
6478 : machine_mode cmp_mode,
6479 : rtx op0, rtx op1)
6480 : {
6481 129658768 : rtx tem, trueop0, trueop1;
6482 :
6483 129658768 : if (cmp_mode == VOIDmode)
6484 28639638 : cmp_mode = GET_MODE (op0);
6485 28639638 : if (cmp_mode == VOIDmode)
6486 519292 : cmp_mode = GET_MODE (op1);
6487 :
6488 129658768 : tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
6489 129658768 : if (tem)
6490 883551 : return relational_result (mode, cmp_mode, tem);
6491 :
6492 : /* For the following tests, ensure const0_rtx is op1. */
6493 128775217 : if (swap_commutative_operands_p (op0, op1)
6494 128775217 : || (op0 == const0_rtx && op1 != const0_rtx))
6495 2754544 : std::swap (op0, op1), code = swap_condition (code);
6496 :
6497 : /* If op0 is a compare, extract the comparison arguments from it. */
6498 128775217 : if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
6499 13959743 : return simplify_gen_relational (code, mode, VOIDmode,
6500 13959743 : XEXP (op0, 0), XEXP (op0, 1));
6501 :
6502 114815474 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
6503 : return NULL_RTX;
6504 :
6505 84527020 : trueop0 = avoid_constant_pool_reference (op0);
6506 84527020 : trueop1 = avoid_constant_pool_reference (op1);
6507 84527020 : return simplify_relational_operation_1 (code, mode, cmp_mode,
6508 84527020 : trueop0, trueop1);
6509 : }
6510 :
6511 : /* This part of simplify_relational_operation is only used when CMP_MODE
6512 : is not in class MODE_CC (i.e. it is a real comparison).
6513 :
6514 : MODE is the mode of the result, while CMP_MODE specifies in which
6515 : mode the comparison is done in, so it is the mode of the operands. */
6516 :
6517 : rtx
6518 84527020 : simplify_context::simplify_relational_operation_1 (rtx_code code,
6519 : machine_mode mode,
6520 : machine_mode cmp_mode,
6521 : rtx op0, rtx op1)
6522 : {
6523 84527020 : enum rtx_code op0code = GET_CODE (op0);
6524 :
6525 84527020 : if (op1 == const0_rtx && COMPARISON_P (op0))
6526 : {
6527 : /* If op0 is a comparison, extract the comparison arguments
6528 : from it. */
6529 455378 : if (code == NE)
6530 : {
6531 211835 : if (GET_MODE (op0) == mode)
6532 164 : return simplify_rtx (op0);
6533 : else
6534 211671 : return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
6535 211671 : XEXP (op0, 0), XEXP (op0, 1));
6536 : }
6537 243543 : else if (code == EQ)
6538 : {
6539 117649 : enum rtx_code new_code = reversed_comparison_code (op0, NULL);
6540 117649 : if (new_code != UNKNOWN)
6541 117332 : return simplify_gen_relational (new_code, mode, VOIDmode,
6542 117332 : XEXP (op0, 0), XEXP (op0, 1));
6543 : }
6544 : }
6545 :
6546 : /* (LTU/GEU (PLUS a C) C), where C is constant, can be simplified to
6547 : (GEU/LTU a -C). Likewise for (LTU/GEU (PLUS a C) a). */
6548 84197853 : if ((code == LTU || code == GEU)
6549 5202151 : && GET_CODE (op0) == PLUS
6550 696831 : && CONST_INT_P (XEXP (op0, 1))
6551 471071 : && (rtx_equal_p (op1, XEXP (op0, 0))
6552 353344 : || rtx_equal_p (op1, XEXP (op0, 1)))
6553 : /* (LTU/GEU (PLUS a 0) 0) is not the same as (GEU/LTU a 0). */
6554 84381197 : && XEXP (op0, 1) != const0_rtx)
6555 : {
6556 183344 : rtx new_cmp
6557 183344 : = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
6558 185329 : return simplify_gen_relational ((code == LTU ? GEU : LTU), mode,
6559 183344 : cmp_mode, XEXP (op0, 0), new_cmp);
6560 : }
6561 :
6562 : /* (GTU (PLUS a C) (C - 1)) where C is a non-zero constant can be
6563 : transformed into (LTU a -C). */
6564 84014509 : if (code == GTU && GET_CODE (op0) == PLUS && CONST_INT_P (op1)
6565 344150 : && CONST_INT_P (XEXP (op0, 1))
6566 265204 : && (UINTVAL (op1) == UINTVAL (XEXP (op0, 1)) - 1)
6567 29065 : && XEXP (op0, 1) != const0_rtx)
6568 : {
6569 29065 : rtx new_cmp
6570 29065 : = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
6571 29065 : return simplify_gen_relational (LTU, mode, cmp_mode,
6572 29065 : XEXP (op0, 0), new_cmp);
6573 : }
6574 :
6575 : /* Canonicalize (LTU/GEU (PLUS a b) b) as (LTU/GEU (PLUS a b) a). */
6576 83985444 : if ((code == LTU || code == GEU)
6577 5018807 : && GET_CODE (op0) == PLUS
6578 513487 : && rtx_equal_p (op1, XEXP (op0, 1))
6579 : /* Don't recurse "infinitely" for (LTU/GEU (PLUS b b) b). */
6580 83990855 : && !rtx_equal_p (op1, XEXP (op0, 0)))
6581 5411 : return simplify_gen_relational (code, mode, cmp_mode, op0,
6582 5411 : copy_rtx (XEXP (op0, 0)));
6583 :
6584 83980033 : if (op1 == const0_rtx)
6585 : {
6586 : /* Canonicalize (GTU x 0) as (NE x 0). */
6587 37193728 : if (code == GTU)
6588 169102 : return simplify_gen_relational (NE, mode, cmp_mode, op0, op1);
6589 : /* Canonicalize (LEU x 0) as (EQ x 0). */
6590 37024626 : if (code == LEU)
6591 33883 : return simplify_gen_relational (EQ, mode, cmp_mode, op0, op1);
6592 :
6593 36990743 : if ((code == NE || code == EQ)
6594 : /* Verify op0 is IOR */
6595 33369207 : && GET_CODE (op0) == IOR
6596 : /* only enters if op1 is 0 */
6597 : /* Verify IOR operand is NE */
6598 545933 : && GET_CODE (XEXP (op0, 0)) == NE
6599 15819 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) == cmp_mode
6600 : /* Verify second NE operand is 0 */
6601 110 : && XEXP (XEXP (op0, 0), 1) == CONST0_RTX (cmp_mode))
6602 : {
6603 31 : rtx t = gen_rtx_IOR (cmp_mode, XEXP (XEXP (op0, 0), 0), XEXP (op0, 1));
6604 31 : t = gen_rtx_fmt_ee (code, mode, t, CONST0_RTX (mode));
6605 31 : return t;
6606 : }
6607 :
6608 : }
6609 46786305 : else if (op1 == const1_rtx)
6610 : {
6611 3076223 : switch (code)
6612 : {
6613 9169 : case GE:
6614 : /* Canonicalize (GE x 1) as (GT x 0). */
6615 9169 : return simplify_gen_relational (GT, mode, cmp_mode,
6616 9169 : op0, const0_rtx);
6617 175568 : case GEU:
6618 : /* Canonicalize (GEU x 1) as (NE x 0). */
6619 175568 : return simplify_gen_relational (NE, mode, cmp_mode,
6620 175568 : op0, const0_rtx);
6621 10458 : case LT:
6622 : /* Canonicalize (LT x 1) as (LE x 0). */
6623 10458 : return simplify_gen_relational (LE, mode, cmp_mode,
6624 10458 : op0, const0_rtx);
6625 52348 : case LTU:
6626 : /* Canonicalize (LTU x 1) as (EQ x 0). */
6627 52348 : return simplify_gen_relational (EQ, mode, cmp_mode,
6628 52348 : op0, const0_rtx);
6629 : default:
6630 : break;
6631 : }
6632 : }
6633 43710082 : else if (op1 == constm1_rtx)
6634 : {
6635 : /* Canonicalize (LE x -1) as (LT x 0). */
6636 1020135 : if (code == LE)
6637 1662 : return simplify_gen_relational (LT, mode, cmp_mode, op0, const0_rtx);
6638 : /* Canonicalize (GT x -1) as (GE x 0). */
6639 1018473 : if (code == GT)
6640 5214 : return simplify_gen_relational (GE, mode, cmp_mode, op0, const0_rtx);
6641 : }
6642 :
6643 : /* (eq/ne (plus x cst1) cst2) simplifies to (eq/ne x (cst2 - cst1)) */
6644 79901062 : if ((code == EQ || code == NE)
6645 62383795 : && (op0code == PLUS || op0code == MINUS)
6646 2494993 : && CONSTANT_P (op1)
6647 883121 : && CONSTANT_P (XEXP (op0, 1))
6648 509274 : && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
6649 : {
6650 509241 : rtx x = XEXP (op0, 0);
6651 509241 : rtx c = XEXP (op0, 1);
6652 509241 : enum rtx_code invcode = op0code == PLUS ? MINUS : PLUS;
6653 509241 : rtx tem = simplify_gen_binary (invcode, cmp_mode, op1, c);
6654 :
6655 : /* Detect an infinite recursive condition, where we oscillate at this
6656 : simplification case between:
6657 : A + B == C <---> C - B == A,
6658 : where A, B, and C are all constants with non-simplifiable expressions,
6659 : usually SYMBOL_REFs. */
6660 509241 : if (GET_CODE (tem) == invcode
6661 46 : && CONSTANT_P (x)
6662 509259 : && rtx_equal_p (c, XEXP (tem, 1)))
6663 : return NULL_RTX;
6664 :
6665 509223 : return simplify_gen_relational (code, mode, cmp_mode, x, tem);
6666 : }
6667 :
6668 : /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is
6669 : the same as (zero_extract:SI FOO (const_int 1) BAR). */
6670 61874554 : scalar_int_mode int_mode, int_cmp_mode;
6671 61874554 : if (code == NE
6672 32653691 : && op1 == const0_rtx
6673 2186705 : && is_int_mode (mode, &int_mode)
6674 82954164 : && is_a <scalar_int_mode> (cmp_mode, &int_cmp_mode)
6675 : /* ??? Work-around BImode bugs in the ia64 backend. */
6676 2186705 : && int_mode != BImode
6677 2186681 : && int_cmp_mode != BImode
6678 2186681 : && nonzero_bits (op0, int_cmp_mode) == 1
6679 61874554 : && STORE_FLAG_VALUE == 1)
6680 118386 : return GET_MODE_SIZE (int_mode) > GET_MODE_SIZE (int_cmp_mode)
6681 59193 : ? simplify_gen_unary (ZERO_EXTEND, int_mode, op0, int_cmp_mode)
6682 24390 : : lowpart_subreg (int_mode, op0, int_cmp_mode);
6683 :
6684 : /* (eq/ne (xor x y) 0) simplifies to (eq/ne x y). */
6685 82954164 : if ((code == EQ || code == NE)
6686 61815361 : && op1 == const0_rtx
6687 33234795 : && op0code == XOR)
6688 13293 : return simplify_gen_relational (code, mode, cmp_mode,
6689 13293 : XEXP (op0, 0), XEXP (op0, 1));
6690 :
6691 : /* (eq/ne (xor x y) x) simplifies to (eq/ne y 0). */
6692 61802068 : if ((code == EQ || code == NE)
6693 61802068 : && op0code == XOR
6694 4467 : && rtx_equal_p (XEXP (op0, 0), op1)
6695 6 : && !side_effects_p (XEXP (op0, 0)))
6696 0 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 1),
6697 0 : CONST0_RTX (mode));
6698 :
6699 : /* Likewise (eq/ne (xor x y) y) simplifies to (eq/ne x 0). */
6700 82940871 : if ((code == EQ || code == NE)
6701 61802068 : && op0code == XOR
6702 4467 : && rtx_equal_p (XEXP (op0, 1), op1)
6703 82941024 : && !side_effects_p (XEXP (op0, 1)))
6704 153 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6705 153 : CONST0_RTX (mode));
6706 :
6707 : /* (eq/ne (xor x C1) C2) simplifies to (eq/ne x (C1^C2)). */
6708 82940718 : if ((code == EQ || code == NE)
6709 61801915 : && op0code == XOR
6710 4314 : && CONST_SCALAR_INT_P (op1)
6711 975 : && CONST_SCALAR_INT_P (XEXP (op0, 1)))
6712 437 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6713 : simplify_gen_binary (XOR, cmp_mode,
6714 437 : XEXP (op0, 1), op1));
6715 :
6716 : /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or
6717 : constant folding if x/y is a constant. */
6718 61801478 : if ((code == EQ || code == NE)
6719 61801478 : && (op0code == AND || op0code == IOR)
6720 3769764 : && !side_effects_p (op1)
6721 3769658 : && op1 != CONST0_RTX (cmp_mode))
6722 : {
6723 : /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to
6724 : (eq/ne (and (not y) x) 0). */
6725 401159 : if ((op0code == AND && rtx_equal_p (XEXP (op0, 0), op1))
6726 804365 : || (op0code == IOR && rtx_equal_p (XEXP (op0, 1), op1)))
6727 : {
6728 24893 : rtx not_y = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 1),
6729 : cmp_mode);
6730 24893 : rtx lhs = simplify_gen_binary (AND, cmp_mode, not_y, XEXP (op0, 0));
6731 :
6732 24893 : return simplify_gen_relational (code, mode, cmp_mode, lhs,
6733 24893 : CONST0_RTX (cmp_mode));
6734 : }
6735 :
6736 : /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to
6737 : (eq/ne (and (not x) y) 0). */
6738 376343 : if ((op0code == AND && rtx_equal_p (XEXP (op0, 1), op1))
6739 737224 : || (op0code == IOR && rtx_equal_p (XEXP (op0, 0), op1)))
6740 : {
6741 42268 : rtx not_x = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 0),
6742 : cmp_mode);
6743 42268 : rtx lhs = simplify_gen_binary (AND, cmp_mode, not_x, XEXP (op0, 1));
6744 :
6745 42268 : return simplify_gen_relational (code, mode, cmp_mode, lhs,
6746 42268 : CONST0_RTX (cmp_mode));
6747 : }
6748 : }
6749 :
6750 : /* Optimize (cmp (and/ior x C1) C2) depending on the CMP and C1 and C2's
6751 : relationship. */
6752 82873120 : if ((op0code == AND || op0code == IOR)
6753 3886656 : && CONST_INT_P (op1)
6754 3707289 : && CONST_INT_P (XEXP (op0, 1)))
6755 : {
6756 2513991 : unsigned HOST_WIDE_INT c1 = UINTVAL (XEXP (op0, 1));
6757 2513991 : unsigned HOST_WIDE_INT c2 = UINTVAL (op1);
6758 :
6759 : /* For AND operations:
6760 : - (x & c1) == c2 when some bits are set in c2 but not in c1 -> false
6761 : - (x & c1) != c2 when some bits are set in c2 but not in c1 -> true
6762 : - (x & c1) >= c2 when c1 is less than c2 -> false
6763 : - (x & c1) < c2 when c1 is less than c2 -> true
6764 : - (x & c1) > c2 when c1 is less than or equal to c2 -> false
6765 : - (x & c1) <= c2 when c1 is less than or equal to c2 -> true
6766 :
6767 : For IOR operations:
6768 : - (x | c1) == c2 when some bits are set in c1 but not in c2 -> false
6769 : - (x | c1) != c2 when some bits are set in c1 but not in c2 -> true
6770 : - (x | c1) <= c2 when c1 is greater than c2 -> false
6771 : - (x | c1) > c2 when c1 is greater than c2 -> true
6772 : - (x | c1) < c2 when c1 is greater than or equal to c2 -> false
6773 : - (x | c1) >= c2 when c1 is greater than or equal to c2 -> true */
6774 2513991 : if ((op0code == AND
6775 2509747 : && ((code == EQ && (c1 & c2) != c2)
6776 2509734 : || (code == GEU && c1 < c2)
6777 2509734 : || (code == GTU && c1 <= c2)))
6778 2513978 : || ((op0code == IOR
6779 4244 : && ((code == EQ && (c1 & c2) != c1)
6780 4240 : || (code == LEU && c1 > c2)
6781 4240 : || (code == LTU && c1 >= c2)))))
6782 17 : return const0_rtx;
6783 :
6784 2513974 : if ((op0code == AND
6785 2509734 : && ((code == NE && (c1 & c2) != c2)
6786 2509659 : || (code == LTU && c1 < c2)
6787 2509659 : || (code == LEU && c1 <= c2)))
6788 2513899 : || ((op0code == IOR
6789 4240 : && ((code == NE && (c1 & c2) != c1)
6790 4180 : || (code == GTU && c1 > c2)
6791 4180 : || (code == GEU && c1 >= c2)))))
6792 135 : return const_true_rtx;
6793 : }
6794 :
6795 : /* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped. */
6796 82872968 : if ((code == EQ || code == NE)
6797 61734165 : && GET_CODE (op0) == BSWAP
6798 324 : && CONST_SCALAR_INT_P (op1))
6799 93 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6800 : simplify_gen_unary (BSWAP, cmp_mode,
6801 93 : op1, cmp_mode));
6802 :
6803 : /* (eq/ne (bswap x) (bswap y)) simplifies to (eq/ne x y). */
6804 61734072 : if ((code == EQ || code == NE)
6805 61734072 : && GET_CODE (op0) == BSWAP
6806 231 : && GET_CODE (op1) == BSWAP)
6807 18 : return simplify_gen_relational (code, mode, cmp_mode,
6808 18 : XEXP (op0, 0), XEXP (op1, 0));
6809 :
6810 82872857 : if (op0code == POPCOUNT && op1 == const0_rtx)
6811 0 : switch (code)
6812 : {
6813 0 : case EQ:
6814 0 : case LE:
6815 0 : case LEU:
6816 : /* (eq (popcount x) (const_int 0)) -> (eq x (const_int 0)). */
6817 0 : return simplify_gen_relational (EQ, mode, GET_MODE (XEXP (op0, 0)),
6818 : XEXP (op0, 0),
6819 0 : CONST0_RTX (GET_MODE (XEXP (op0, 0))));
6820 :
6821 0 : case NE:
6822 0 : case GT:
6823 0 : case GTU:
6824 : /* (ne (popcount x) (const_int 0)) -> (ne x (const_int 0)). */
6825 0 : return simplify_gen_relational (NE, mode, GET_MODE (XEXP (op0, 0)),
6826 : XEXP (op0, 0),
6827 0 : CONST0_RTX (GET_MODE (XEXP (op0, 0))));
6828 :
6829 : default:
6830 : break;
6831 : }
6832 :
6833 : /* (ne:SI (subreg:QI (ashift:SI x 7) 0) 0) -> (and:SI x 1). */
6834 82872857 : if (code == NE
6835 32553552 : && op1 == const0_rtx
6836 16554385 : && (op0code == TRUNCATE
6837 148147 : || (partial_subreg_p (op0)
6838 147403 : && subreg_lowpart_p (op0)))
6839 123926 : && SCALAR_INT_MODE_P (mode)
6840 82872857 : && STORE_FLAG_VALUE == 1)
6841 : {
6842 30877 : rtx tmp = XEXP (op0, 0);
6843 30877 : if (GET_CODE (tmp) == ASHIFT
6844 2440 : && GET_MODE (tmp) == mode
6845 229 : && CONST_INT_P (XEXP (tmp, 1))
6846 229 : && is_int_mode (GET_MODE (op0), &int_mode)
6847 31106 : && INTVAL (XEXP (tmp, 1)) == GET_MODE_PRECISION (int_mode) - 1)
6848 229 : return simplify_gen_binary (AND, mode, XEXP (tmp, 0), const1_rtx);
6849 : }
6850 :
6851 : /* For two unsigned booleans A and B:
6852 :
6853 : A > B == ~B & A
6854 : A >= B == ~B | A
6855 : A < B == ~A & B
6856 : A <= B == ~A | B
6857 : A == B == ~A ^ B (== ~B ^ A)
6858 : A != B == A ^ B
6859 :
6860 : For signed comparisons, we have to take STORE_FLAG_VALUE into account,
6861 : with the rules above applying for positive STORE_FLAG_VALUE and with
6862 : the relations reversed for negative STORE_FLAG_VALUE. */
6863 82872628 : if (is_a<scalar_int_mode> (cmp_mode)
6864 80277368 : && COMPARISON_P (op0)
6865 82947040 : && COMPARISON_P (op1))
6866 : {
6867 10019 : rtx t = NULL_RTX;
6868 10019 : if (code == GTU || code == (STORE_FLAG_VALUE > 0 ? GT : LT))
6869 755 : t = simplify_logical_relational_operation (AND, mode, op1, op0, true);
6870 : else if (code == GEU || code == (STORE_FLAG_VALUE > 0 ? GE : LE))
6871 720 : t = simplify_logical_relational_operation (IOR, mode, op1, op0, true);
6872 : else if (code == LTU || code == (STORE_FLAG_VALUE > 0 ? LT : GT))
6873 720 : t = simplify_logical_relational_operation (AND, mode, op0, op1, true);
6874 : else if (code == LEU || code == (STORE_FLAG_VALUE > 0 ? LE : GE))
6875 720 : t = simplify_logical_relational_operation (IOR, mode, op0, op1, true);
6876 : else if (code == EQ)
6877 3253 : t = simplify_logical_relational_operation (XOR, mode, op0, op1, true);
6878 : else if (code == NE)
6879 3851 : t = simplify_logical_relational_operation (XOR, mode, op0, op1);
6880 10019 : if (t)
6881 : return t;
6882 : }
6883 :
6884 : return NULL_RTX;
6885 : }
6886 :
6887 : enum
6888 : {
6889 : CMP_EQ = 1,
6890 : CMP_LT = 2,
6891 : CMP_GT = 4,
6892 : CMP_LTU = 8,
6893 : CMP_GTU = 16
6894 : };
6895 :
6896 :
6897 : /* Convert the known results for EQ, LT, GT, LTU, GTU contained in
6898 : KNOWN_RESULT to a CONST_INT, based on the requested comparison CODE
6899 : For KNOWN_RESULT to make sense it should be either CMP_EQ, or the
6900 : logical OR of one of (CMP_LT, CMP_GT) and one of (CMP_LTU, CMP_GTU).
6901 : For floating-point comparisons, assume that the operands were ordered. */
6902 :
6903 : static rtx
6904 710351 : comparison_result (enum rtx_code code, int known_results)
6905 : {
6906 710351 : switch (code)
6907 : {
6908 130979 : case EQ:
6909 130979 : case UNEQ:
6910 130979 : return (known_results & CMP_EQ) ? const_true_rtx : const0_rtx;
6911 442031 : case NE:
6912 442031 : case LTGT:
6913 442031 : return (known_results & CMP_EQ) ? const0_rtx : const_true_rtx;
6914 :
6915 9505 : case LT:
6916 9505 : case UNLT:
6917 9505 : return (known_results & CMP_LT) ? const_true_rtx : const0_rtx;
6918 8613 : case GE:
6919 8613 : case UNGE:
6920 8613 : return (known_results & CMP_LT) ? const0_rtx : const_true_rtx;
6921 :
6922 12772 : case GT:
6923 12772 : case UNGT:
6924 12772 : return (known_results & CMP_GT) ? const_true_rtx : const0_rtx;
6925 14744 : case LE:
6926 14744 : case UNLE:
6927 14744 : return (known_results & CMP_GT) ? const0_rtx : const_true_rtx;
6928 :
6929 24408 : case LTU:
6930 24408 : return (known_results & CMP_LTU) ? const_true_rtx : const0_rtx;
6931 8828 : case GEU:
6932 8828 : return (known_results & CMP_LTU) ? const0_rtx : const_true_rtx;
6933 :
6934 47966 : case GTU:
6935 47966 : return (known_results & CMP_GTU) ? const_true_rtx : const0_rtx;
6936 10497 : case LEU:
6937 10497 : return (known_results & CMP_GTU) ? const0_rtx : const_true_rtx;
6938 :
6939 0 : case ORDERED:
6940 0 : return const_true_rtx;
6941 8 : case UNORDERED:
6942 8 : return const0_rtx;
6943 0 : default:
6944 0 : gcc_unreachable ();
6945 : }
6946 : }
6947 :
6948 : /* Check if the given comparison (done in the given MODE) is actually
6949 : a tautology or a contradiction. If the mode is VOIDmode, the
6950 : comparison is done in "infinite precision". If no simplification
6951 : is possible, this function returns zero. Otherwise, it returns
6952 : either const_true_rtx or const0_rtx. */
6953 :
6954 : rtx
6955 129748912 : simplify_const_relational_operation (enum rtx_code code,
6956 : machine_mode mode,
6957 : rtx op0, rtx op1)
6958 : {
6959 136591670 : rtx tem;
6960 136591670 : rtx trueop0;
6961 136591670 : rtx trueop1;
6962 :
6963 136591670 : gcc_assert (mode != VOIDmode
6964 : || (GET_MODE (op0) == VOIDmode
6965 : && GET_MODE (op1) == VOIDmode));
6966 :
6967 : /* We only handle MODE_CC comparisons that are COMPARE against zero. */
6968 136591670 : if (GET_MODE_CLASS (mode) == MODE_CC
6969 44254255 : && (op1 != const0_rtx
6970 44254255 : || GET_CODE (op0) != COMPARE))
6971 : return NULL_RTX;
6972 :
6973 : /* If op0 is a compare, extract the comparison arguments from it. */
6974 106303216 : if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
6975 : {
6976 13965801 : op1 = XEXP (op0, 1);
6977 13965801 : op0 = XEXP (op0, 0);
6978 :
6979 13965801 : if (GET_MODE (op0) != VOIDmode)
6980 13807750 : mode = GET_MODE (op0);
6981 158051 : else if (GET_MODE (op1) != VOIDmode)
6982 126234 : mode = GET_MODE (op1);
6983 : else
6984 : return 0;
6985 : }
6986 :
6987 : /* We can't simplify MODE_CC values since we don't know what the
6988 : actual comparison is. */
6989 106271399 : if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
6990 : return 0;
6991 :
6992 : /* Make sure the constant is second. */
6993 106271399 : if (swap_commutative_operands_p (op0, op1))
6994 : {
6995 3247483 : std::swap (op0, op1);
6996 3247483 : code = swap_condition (code);
6997 : }
6998 :
6999 106271399 : trueop0 = avoid_constant_pool_reference (op0);
7000 106271399 : trueop1 = avoid_constant_pool_reference (op1);
7001 :
7002 : /* For integer comparisons of A and B maybe we can simplify A - B and can
7003 : then simplify a comparison of that with zero. If A and B are both either
7004 : a register or a CONST_INT, this can't help; testing for these cases will
7005 : prevent infinite recursion here and speed things up.
7006 :
7007 : We can only do this for EQ and NE comparisons as otherwise we may
7008 : lose or introduce overflow which we cannot disregard as undefined as
7009 : we do not know the signedness of the operation on either the left or
7010 : the right hand side of the comparison. */
7011 :
7012 106271399 : if (INTEGRAL_MODE_P (mode)
7013 103695080 : && trueop1 != CONST0_RTX (mode)
7014 53044665 : && (code == EQ || code == NE)
7015 33576660 : && ! ((REG_P (op0)
7016 9866384 : || CONST_SCALAR_INT_P (trueop0)
7017 9837603 : || CONST_VECTOR_P (trueop0))
7018 23739077 : && (REG_P (op1)
7019 14043282 : || CONST_SCALAR_INT_P (trueop1)
7020 3341007 : || CONST_VECTOR_P (trueop1)))
7021 13176312 : && (tem = simplify_binary_operation (MINUS, mode, op0, op1)) != 0
7022 : /* We cannot do this if tem is a nonzero address. */
7023 6842760 : && ! nonzero_address_p (tem))
7024 6842758 : return simplify_const_relational_operation (signed_condition (code),
7025 6842758 : mode, tem, CONST0_RTX (mode));
7026 :
7027 99428641 : if (! HONOR_NANS (mode) && code == ORDERED)
7028 0 : return const_true_rtx;
7029 :
7030 99428641 : if (! HONOR_NANS (mode) && code == UNORDERED)
7031 8 : return const0_rtx;
7032 :
7033 : /* For modes without NaNs, if the two operands are equal, we know the
7034 : result except if they have side-effects. Even with NaNs we know
7035 : the result of unordered comparisons and, if signaling NaNs are
7036 : irrelevant, also the result of LT/GT/LTGT. */
7037 99428633 : if ((! HONOR_NANS (trueop0)
7038 2089910 : || code == UNEQ || code == UNLE || code == UNGE
7039 : || ((code == LT || code == GT || code == LTGT)
7040 835015 : && ! HONOR_SNANS (trueop0)))
7041 98278576 : && rtx_equal_p (trueop0, trueop1)
7042 99934123 : && ! side_effects_p (trueop0))
7043 505401 : return comparison_result (code, CMP_EQ);
7044 :
7045 : /* If the operands are floating-point constants, see if we can fold
7046 : the result. */
7047 98923232 : if (CONST_DOUBLE_AS_FLOAT_P (trueop0)
7048 1290 : && CONST_DOUBLE_AS_FLOAT_P (trueop1)
7049 1290 : && SCALAR_FLOAT_MODE_P (GET_MODE (trueop0)))
7050 : {
7051 1290 : const REAL_VALUE_TYPE *d0 = CONST_DOUBLE_REAL_VALUE (trueop0);
7052 1290 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
7053 :
7054 : /* Comparisons are unordered iff at least one of the values is NaN. */
7055 1290 : if (REAL_VALUE_ISNAN (*d0) || REAL_VALUE_ISNAN (*d1))
7056 174 : switch (code)
7057 : {
7058 0 : case UNEQ:
7059 0 : case UNLT:
7060 0 : case UNGT:
7061 0 : case UNLE:
7062 0 : case UNGE:
7063 0 : case NE:
7064 0 : case UNORDERED:
7065 0 : return const_true_rtx;
7066 174 : case EQ:
7067 174 : case LT:
7068 174 : case GT:
7069 174 : case LE:
7070 174 : case GE:
7071 174 : case LTGT:
7072 174 : case ORDERED:
7073 174 : return const0_rtx;
7074 : default:
7075 : return 0;
7076 : }
7077 :
7078 1201 : return comparison_result (code,
7079 1201 : (real_equal (d0, d1) ? CMP_EQ :
7080 1201 : real_less (d0, d1) ? CMP_LT : CMP_GT));
7081 : }
7082 :
7083 : /* Otherwise, see if the operands are both integers. */
7084 98921942 : if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
7085 95933227 : && CONST_SCALAR_INT_P (trueop0) && CONST_SCALAR_INT_P (trueop1))
7086 : {
7087 : /* It would be nice if we really had a mode here. However, the
7088 : largest int representable on the target is as good as
7089 : infinite. */
7090 203834 : machine_mode cmode = (mode == VOIDmode) ? MAX_MODE_INT : mode;
7091 203834 : rtx_mode_t ptrueop0 = rtx_mode_t (trueop0, cmode);
7092 203834 : rtx_mode_t ptrueop1 = rtx_mode_t (trueop1, cmode);
7093 :
7094 203834 : if (wi::eq_p (ptrueop0, ptrueop1))
7095 0 : return comparison_result (code, CMP_EQ);
7096 : else
7097 : {
7098 203834 : int cr = wi::lts_p (ptrueop0, ptrueop1) ? CMP_LT : CMP_GT;
7099 203834 : cr |= wi::ltu_p (ptrueop0, ptrueop1) ? CMP_LTU : CMP_GTU;
7100 203834 : return comparison_result (code, cr);
7101 : }
7102 : }
7103 :
7104 : /* Optimize comparisons with upper and lower bounds. */
7105 98718108 : scalar_int_mode int_mode;
7106 98718108 : if (CONST_INT_P (trueop1)
7107 69044485 : && is_a <scalar_int_mode> (mode, &int_mode)
7108 69044485 : && HWI_COMPUTABLE_MODE_P (int_mode)
7109 167334028 : && !side_effects_p (trueop0))
7110 : {
7111 68465551 : int sign;
7112 68465551 : unsigned HOST_WIDE_INT nonzero = nonzero_bits (trueop0, int_mode);
7113 68465551 : HOST_WIDE_INT val = INTVAL (trueop1);
7114 68465551 : HOST_WIDE_INT mmin, mmax;
7115 :
7116 68465551 : if (code == GEU
7117 68465551 : || code == LEU
7118 65108934 : || code == GTU
7119 65108934 : || code == LTU)
7120 : sign = 0;
7121 : else
7122 68465551 : sign = 1;
7123 :
7124 : /* Get a reduced range if the sign bit is zero. */
7125 68465551 : if (nonzero <= (GET_MODE_MASK (int_mode) >> 1))
7126 : {
7127 6655418 : mmin = 0;
7128 6655418 : mmax = nonzero;
7129 : }
7130 : else
7131 : {
7132 61810133 : rtx mmin_rtx, mmax_rtx;
7133 61810133 : get_mode_bounds (int_mode, sign, int_mode, &mmin_rtx, &mmax_rtx);
7134 :
7135 61810133 : mmin = INTVAL (mmin_rtx);
7136 61810133 : mmax = INTVAL (mmax_rtx);
7137 61810133 : if (sign)
7138 : {
7139 55596950 : unsigned int sign_copies
7140 55596950 : = num_sign_bit_copies (trueop0, int_mode);
7141 :
7142 55596950 : mmin >>= (sign_copies - 1);
7143 55596950 : mmax >>= (sign_copies - 1);
7144 : }
7145 : }
7146 :
7147 68465551 : switch (code)
7148 : {
7149 : /* x >= y is always true for y <= mmin, always false for y > mmax. */
7150 595397 : case GEU:
7151 595397 : if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
7152 12910 : return const_true_rtx;
7153 582487 : if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
7154 50 : return const0_rtx;
7155 : break;
7156 926409 : case GE:
7157 926409 : if (val <= mmin)
7158 2354 : return const_true_rtx;
7159 924055 : if (val > mmax)
7160 0 : return const0_rtx;
7161 : break;
7162 :
7163 : /* x <= y is always true for y >= mmax, always false for y < mmin. */
7164 2761220 : case LEU:
7165 2761220 : if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
7166 15794 : return const_true_rtx;
7167 2745426 : if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
7168 0 : return const0_rtx;
7169 : break;
7170 2269510 : case LE:
7171 2269510 : if (val >= mmax)
7172 467 : return const_true_rtx;
7173 2269043 : if (val < mmin)
7174 0 : return const0_rtx;
7175 : break;
7176 :
7177 25537987 : case EQ:
7178 : /* x == y is always false for y out of range. */
7179 25537987 : if (val < mmin || val > mmax)
7180 431 : return const0_rtx;
7181 : break;
7182 :
7183 : /* x > y is always false for y >= mmax, always true for y < mmin. */
7184 2588213 : case GTU:
7185 2588213 : if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
7186 132313 : return const0_rtx;
7187 2455900 : if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
7188 0 : return const_true_rtx;
7189 : break;
7190 1766086 : case GT:
7191 1766086 : if (val >= mmax)
7192 336 : return const0_rtx;
7193 1765750 : if (val < mmin)
7194 5 : return const_true_rtx;
7195 : break;
7196 :
7197 : /* x < y is always false for y <= mmin, always true for y > mmax. */
7198 836637 : case LTU:
7199 836637 : if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
7200 2959 : return const0_rtx;
7201 833678 : if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
7202 88884 : return const_true_rtx;
7203 : break;
7204 1111580 : case LT:
7205 1111580 : if (val <= mmin)
7206 2306 : return const0_rtx;
7207 1109274 : if (val > mmax)
7208 3495 : return const_true_rtx;
7209 : break;
7210 :
7211 30072512 : case NE:
7212 : /* x != y is always true for y out of range. */
7213 30072512 : if (val < mmin || val > mmax)
7214 122 : return const_true_rtx;
7215 : break;
7216 :
7217 : default:
7218 : break;
7219 : }
7220 : }
7221 :
7222 : /* Optimize integer comparisons with zero. */
7223 98455682 : if (is_a <scalar_int_mode> (mode, &int_mode)
7224 95510048 : && trueop1 == const0_rtx
7225 49925245 : && !side_effects_p (trueop0))
7226 : {
7227 : /* Some addresses are known to be nonzero. We don't know
7228 : their sign, but equality comparisons are known. */
7229 49772804 : if (nonzero_address_p (trueop0))
7230 : {
7231 532 : if (code == EQ || code == LEU)
7232 251 : return const0_rtx;
7233 281 : if (code == NE || code == GTU)
7234 281 : return const_true_rtx;
7235 : }
7236 :
7237 : /* See if the first operand is an IOR with a constant. If so, we
7238 : may be able to determine the result of this comparison. */
7239 49772272 : if (GET_CODE (op0) == IOR)
7240 : {
7241 628620 : rtx inner_const = avoid_constant_pool_reference (XEXP (op0, 1));
7242 628620 : if (CONST_INT_P (inner_const) && inner_const != const0_rtx)
7243 : {
7244 290 : int sign_bitnum = GET_MODE_PRECISION (int_mode) - 1;
7245 580 : int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
7246 290 : && (UINTVAL (inner_const)
7247 290 : & (HOST_WIDE_INT_1U
7248 : << sign_bitnum)));
7249 :
7250 290 : switch (code)
7251 : {
7252 : case EQ:
7253 : case LEU:
7254 : return const0_rtx;
7255 4 : case NE:
7256 4 : case GTU:
7257 4 : return const_true_rtx;
7258 70 : case LT:
7259 70 : case LE:
7260 70 : if (has_sign)
7261 2 : return const_true_rtx;
7262 : break;
7263 210 : case GT:
7264 210 : case GE:
7265 210 : if (has_sign)
7266 : return const0_rtx;
7267 : break;
7268 : default:
7269 : break;
7270 : }
7271 : }
7272 : }
7273 : }
7274 :
7275 : /* Optimize comparison of ABS with zero. */
7276 50254786 : if (trueop1 == CONST0_RTX (mode) && !side_effects_p (trueop0)
7277 148556978 : && (GET_CODE (trueop0) == ABS
7278 50101449 : || (GET_CODE (trueop0) == FLOAT_EXTEND
7279 38 : && GET_CODE (XEXP (trueop0, 0)) == ABS)))
7280 : {
7281 583 : switch (code)
7282 : {
7283 60 : case LT:
7284 : /* Optimize abs(x) < 0.0. */
7285 60 : if (!INTEGRAL_MODE_P (mode) && !HONOR_SNANS (mode))
7286 0 : return const0_rtx;
7287 : break;
7288 :
7289 42 : case GE:
7290 : /* Optimize abs(x) >= 0.0. */
7291 42 : if (!INTEGRAL_MODE_P (mode) && !HONOR_NANS (mode))
7292 0 : return const_true_rtx;
7293 : break;
7294 :
7295 0 : case UNGE:
7296 : /* Optimize ! (abs(x) < 0.0). */
7297 0 : return const_true_rtx;
7298 :
7299 : default:
7300 : break;
7301 : }
7302 : }
7303 :
7304 : return 0;
7305 : }
7306 :
7307 : /* Recognize expressions of the form (X CMP 0) ? VAL : OP (X)
7308 : where OP is CLZ or CTZ and VAL is the value from CLZ_DEFINED_VALUE_AT_ZERO
7309 : or CTZ_DEFINED_VALUE_AT_ZERO respectively and return OP (X) if the expression
7310 : can be simplified to that or NULL_RTX if not.
7311 : Assume X is compared against zero with CMP_CODE and the true
7312 : arm is TRUE_VAL and the false arm is FALSE_VAL. */
7313 :
7314 : rtx
7315 30817580 : simplify_context::simplify_cond_clz_ctz (rtx x, rtx_code cmp_code,
7316 : rtx true_val, rtx false_val)
7317 : {
7318 30817580 : if (cmp_code != EQ && cmp_code != NE)
7319 : return NULL_RTX;
7320 :
7321 : /* Result on X == 0 and X !=0 respectively. */
7322 22288405 : rtx on_zero, on_nonzero;
7323 22288405 : if (cmp_code == EQ)
7324 : {
7325 : on_zero = true_val;
7326 : on_nonzero = false_val;
7327 : }
7328 : else
7329 : {
7330 11893984 : on_zero = false_val;
7331 11893984 : on_nonzero = true_val;
7332 : }
7333 :
7334 22288405 : rtx_code op_code = GET_CODE (on_nonzero);
7335 22288405 : if ((op_code != CLZ && op_code != CTZ)
7336 1961 : || !rtx_equal_p (XEXP (on_nonzero, 0), x)
7337 22289431 : || !CONST_INT_P (on_zero))
7338 22288103 : return NULL_RTX;
7339 :
7340 302 : HOST_WIDE_INT op_val;
7341 302 : scalar_int_mode mode ATTRIBUTE_UNUSED
7342 302 : = as_a <scalar_int_mode> (GET_MODE (XEXP (on_nonzero, 0)));
7343 0 : if (((op_code == CLZ && CLZ_DEFINED_VALUE_AT_ZERO (mode, op_val))
7344 604 : || (op_code == CTZ && CTZ_DEFINED_VALUE_AT_ZERO (mode, op_val)))
7345 326 : && op_val == INTVAL (on_zero))
7346 : return on_nonzero;
7347 :
7348 : return NULL_RTX;
7349 : }
7350 :
7351 : /* Try to simplify X given that it appears within operand OP of a
7352 : VEC_MERGE operation whose mask is MASK. X need not use the same
7353 : vector mode as the VEC_MERGE, but it must have the same number of
7354 : elements.
7355 :
7356 : Return the simplified X on success, otherwise return NULL_RTX. */
7357 :
7358 : rtx
7359 1637892 : simplify_context::simplify_merge_mask (rtx x, rtx mask, int op)
7360 : {
7361 1637892 : gcc_assert (VECTOR_MODE_P (GET_MODE (x)));
7362 3275784 : poly_uint64 nunits = GET_MODE_NUNITS (GET_MODE (x));
7363 1637892 : if (GET_CODE (x) == VEC_MERGE && rtx_equal_p (XEXP (x, 2), mask))
7364 : {
7365 5486 : if (side_effects_p (XEXP (x, 1 - op)))
7366 : return NULL_RTX;
7367 :
7368 5262 : return XEXP (x, op);
7369 : }
7370 1632406 : if (UNARY_P (x)
7371 194200 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
7372 1690294 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits))
7373 : {
7374 24337 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
7375 24337 : if (top0)
7376 448 : return simplify_gen_unary (GET_CODE (x), GET_MODE (x), top0,
7377 448 : GET_MODE (XEXP (x, 0)));
7378 : }
7379 1631958 : if (BINARY_P (x)
7380 203628 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
7381 406950 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
7382 178183 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
7383 1913996 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits))
7384 : {
7385 141019 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
7386 141019 : rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
7387 141019 : if (top0 || top1)
7388 : {
7389 952 : if (COMPARISON_P (x))
7390 0 : return simplify_gen_relational (GET_CODE (x), GET_MODE (x),
7391 0 : GET_MODE (XEXP (x, 0)) != VOIDmode
7392 : ? GET_MODE (XEXP (x, 0))
7393 0 : : GET_MODE (XEXP (x, 1)),
7394 : top0 ? top0 : XEXP (x, 0),
7395 0 : top1 ? top1 : XEXP (x, 1));
7396 : else
7397 952 : return simplify_gen_binary (GET_CODE (x), GET_MODE (x),
7398 : top0 ? top0 : XEXP (x, 0),
7399 952 : top1 ? top1 : XEXP (x, 1));
7400 : }
7401 : }
7402 1631006 : if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY
7403 35322 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
7404 70644 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
7405 35322 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
7406 70644 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits)
7407 35322 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 2)))
7408 1648446 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 2))), nunits))
7409 : {
7410 8720 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
7411 8720 : rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
7412 8720 : rtx top2 = simplify_merge_mask (XEXP (x, 2), mask, op);
7413 8720 : if (top0 || top1 || top2)
7414 448 : return simplify_gen_ternary (GET_CODE (x), GET_MODE (x),
7415 448 : GET_MODE (XEXP (x, 0)),
7416 : top0 ? top0 : XEXP (x, 0),
7417 : top1 ? top1 : XEXP (x, 1),
7418 448 : top2 ? top2 : XEXP (x, 2));
7419 : }
7420 : return NULL_RTX;
7421 : }
7422 :
7423 :
7424 : /* Simplify CODE, an operation with result mode MODE and three operands,
7425 : OP0, OP1, and OP2. OP0_MODE was the mode of OP0 before it became
7426 : a constant. Return 0 if no simplifications is possible. */
7427 :
7428 : rtx
7429 42596693 : simplify_context::simplify_ternary_operation (rtx_code code, machine_mode mode,
7430 : machine_mode op0_mode,
7431 : rtx op0, rtx op1, rtx op2)
7432 : {
7433 42596693 : bool any_change = false;
7434 42596693 : rtx tem, trueop2;
7435 42596693 : scalar_int_mode int_mode, int_op0_mode;
7436 42596693 : unsigned int n_elts;
7437 :
7438 42596693 : switch (code)
7439 : {
7440 334180 : case FMA:
7441 : /* Simplify negations around the multiplication. */
7442 : /* -a * -b + c => a * b + c. */
7443 334180 : if (GET_CODE (op0) == NEG)
7444 : {
7445 80590 : tem = simplify_unary_operation (NEG, mode, op1, mode);
7446 80590 : if (tem)
7447 271 : op1 = tem, op0 = XEXP (op0, 0), any_change = true;
7448 : }
7449 253590 : else if (GET_CODE (op1) == NEG)
7450 : {
7451 1064 : tem = simplify_unary_operation (NEG, mode, op0, mode);
7452 1064 : if (tem)
7453 0 : op0 = tem, op1 = XEXP (op1, 0), any_change = true;
7454 : }
7455 :
7456 : /* Canonicalize the two multiplication operands. */
7457 : /* a * -b + c => -b * a + c. */
7458 334180 : if (swap_commutative_operands_p (op0, op1))
7459 : std::swap (op0, op1), any_change = true;
7460 :
7461 306001 : if (any_change)
7462 28441 : return gen_rtx_FMA (mode, op0, op1, op2);
7463 : return NULL_RTX;
7464 :
7465 659809 : case SIGN_EXTRACT:
7466 659809 : case ZERO_EXTRACT:
7467 659809 : if (CONST_INT_P (op0)
7468 17489 : && CONST_INT_P (op1)
7469 17489 : && CONST_INT_P (op2)
7470 42596725 : && is_a <scalar_int_mode> (mode, &int_mode)
7471 32 : && INTVAL (op1) + INTVAL (op2) <= GET_MODE_PRECISION (int_mode)
7472 659841 : && HWI_COMPUTABLE_MODE_P (int_mode))
7473 : {
7474 : /* Extracting a bit-field from a constant */
7475 32 : unsigned HOST_WIDE_INT val = UINTVAL (op0);
7476 32 : HOST_WIDE_INT op1val = INTVAL (op1);
7477 32 : HOST_WIDE_INT op2val = INTVAL (op2);
7478 32 : if (!BITS_BIG_ENDIAN)
7479 32 : val >>= op2val;
7480 : else if (is_a <scalar_int_mode> (op0_mode, &int_op0_mode))
7481 : val >>= GET_MODE_PRECISION (int_op0_mode) - op2val - op1val;
7482 : else
7483 : /* Not enough information to calculate the bit position. */
7484 : break;
7485 :
7486 32 : if (HOST_BITS_PER_WIDE_INT != op1val)
7487 : {
7488 : /* First zero-extend. */
7489 29 : val &= (HOST_WIDE_INT_1U << op1val) - 1;
7490 : /* If desired, propagate sign bit. */
7491 29 : if (code == SIGN_EXTRACT
7492 5 : && (val & (HOST_WIDE_INT_1U << (op1val - 1)))
7493 5 : != 0)
7494 2 : val |= ~ ((HOST_WIDE_INT_1U << op1val) - 1);
7495 : }
7496 :
7497 32 : return gen_int_mode (val, int_mode);
7498 : }
7499 : break;
7500 :
7501 40811782 : case IF_THEN_ELSE:
7502 40811782 : if (CONST_INT_P (op0))
7503 283777 : return op0 != const0_rtx ? op1 : op2;
7504 :
7505 : /* Convert c ? a : a into "a". */
7506 40620704 : if (rtx_equal_p (op1, op2) && ! side_effects_p (op0))
7507 : return op1;
7508 :
7509 : /* Convert a != b ? a : b into "a". */
7510 40617436 : if (GET_CODE (op0) == NE
7511 15689954 : && ! side_effects_p (op0)
7512 15648582 : && ! HONOR_NANS (mode)
7513 15642614 : && ! HONOR_SIGNED_ZEROS (mode)
7514 56260050 : && ((rtx_equal_p (XEXP (op0, 0), op1)
7515 102973 : && rtx_equal_p (XEXP (op0, 1), op2))
7516 15642283 : || (rtx_equal_p (XEXP (op0, 0), op2)
7517 4419 : && rtx_equal_p (XEXP (op0, 1), op1))))
7518 534 : return op1;
7519 :
7520 : /* Convert a == b ? a : b into "b". */
7521 40616902 : if (GET_CODE (op0) == EQ
7522 12948570 : && ! side_effects_p (op0)
7523 12922438 : && ! HONOR_NANS (mode)
7524 12785061 : && ! HONOR_SIGNED_ZEROS (mode)
7525 53401963 : && ((rtx_equal_p (XEXP (op0, 0), op1)
7526 14874 : && rtx_equal_p (XEXP (op0, 1), op2))
7527 12785051 : || (rtx_equal_p (XEXP (op0, 0), op2)
7528 6885 : && rtx_equal_p (XEXP (op0, 1), op1))))
7529 26 : return op2;
7530 :
7531 : /* Convert a != 0 ? -a : 0 into "-a". */
7532 40616876 : if (GET_CODE (op0) == NE
7533 15689420 : && ! side_effects_p (op0)
7534 15648048 : && ! HONOR_NANS (mode)
7535 15642080 : && ! HONOR_SIGNED_ZEROS (mode)
7536 15642080 : && XEXP (op0, 1) == CONST0_RTX (mode)
7537 11887906 : && op2 == CONST0_RTX (mode)
7538 179506 : && GET_CODE (op1) == NEG
7539 40616928 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0)))
7540 : return op1;
7541 :
7542 : /* Convert a == 0 ? 0 : -a into "-a". */
7543 40616867 : if (GET_CODE (op0) == EQ
7544 12948544 : && ! side_effects_p (op0)
7545 12922412 : && ! HONOR_NANS (mode)
7546 12785035 : && ! HONOR_SIGNED_ZEROS (mode)
7547 12785035 : && op1 == CONST0_RTX (mode)
7548 30895 : && XEXP (op0, 1) == CONST0_RTX (mode)
7549 13408 : && GET_CODE (op2) == NEG
7550 40616873 : && rtx_equal_p (XEXP (op0, 0), XEXP (op2, 0)))
7551 : return op2;
7552 :
7553 : /* Convert (!c) != {0,...,0} ? a : b into
7554 : c != {0,...,0} ? b : a for vector modes. */
7555 40616861 : if (VECTOR_MODE_P (GET_MODE (op1))
7556 14910 : && GET_CODE (op0) == NE
7557 465 : && GET_CODE (XEXP (op0, 0)) == NOT
7558 0 : && GET_CODE (XEXP (op0, 1)) == CONST_VECTOR)
7559 : {
7560 0 : rtx cv = XEXP (op0, 1);
7561 0 : int nunits;
7562 0 : bool ok = true;
7563 0 : if (!CONST_VECTOR_NUNITS (cv).is_constant (&nunits))
7564 : ok = false;
7565 : else
7566 0 : for (int i = 0; i < nunits; ++i)
7567 0 : if (CONST_VECTOR_ELT (cv, i) != const0_rtx)
7568 : {
7569 : ok = false;
7570 : break;
7571 : }
7572 0 : if (ok)
7573 : {
7574 0 : rtx new_op0 = gen_rtx_NE (GET_MODE (op0),
7575 : XEXP (XEXP (op0, 0), 0),
7576 : XEXP (op0, 1));
7577 0 : rtx retval = gen_rtx_IF_THEN_ELSE (mode, new_op0, op2, op1);
7578 0 : return retval;
7579 : }
7580 : }
7581 :
7582 : /* Convert x == 0 ? N : clz (x) into clz (x) when
7583 : CLZ_DEFINED_VALUE_AT_ZERO is defined to N for the mode of x.
7584 : Similarly for ctz (x). */
7585 40615863 : if (COMPARISON_P (op0) && !side_effects_p (op0)
7586 81132288 : && XEXP (op0, 1) == const0_rtx)
7587 : {
7588 30817580 : rtx simplified
7589 30817580 : = simplify_cond_clz_ctz (XEXP (op0, 0), GET_CODE (op0),
7590 : op1, op2);
7591 30817580 : if (simplified)
7592 : return simplified;
7593 : }
7594 :
7595 40616861 : if (COMPARISON_P (op0) && ! side_effects_p (op0))
7596 : {
7597 81131756 : machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
7598 40515427 : ? GET_MODE (XEXP (op0, 1))
7599 : : GET_MODE (XEXP (op0, 0)));
7600 40515427 : rtx temp;
7601 :
7602 : /* Look for happy constants in op1 and op2. */
7603 40515427 : if (CONST_INT_P (op1) && CONST_INT_P (op2))
7604 : {
7605 205645 : HOST_WIDE_INT t = INTVAL (op1);
7606 205645 : HOST_WIDE_INT f = INTVAL (op2);
7607 :
7608 205645 : if (t == STORE_FLAG_VALUE && f == 0)
7609 52428 : code = GET_CODE (op0);
7610 153217 : else if (t == 0 && f == STORE_FLAG_VALUE)
7611 : {
7612 31189 : enum rtx_code tmp;
7613 31189 : tmp = reversed_comparison_code (op0, NULL);
7614 31189 : if (tmp == UNKNOWN)
7615 : break;
7616 : code = tmp;
7617 : }
7618 : else
7619 : break;
7620 :
7621 78234 : return simplify_gen_relational (code, mode, cmp_mode,
7622 78234 : XEXP (op0, 0), XEXP (op0, 1));
7623 : }
7624 :
7625 40309782 : temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
7626 : cmp_mode, XEXP (op0, 0),
7627 : XEXP (op0, 1));
7628 :
7629 : /* See if any simplifications were possible. */
7630 40309782 : if (temp)
7631 : {
7632 6917 : if (CONST_INT_P (temp))
7633 868 : return temp == const0_rtx ? op2 : op1;
7634 6094 : else if (temp)
7635 6094 : return gen_rtx_IF_THEN_ELSE (mode, temp, op1, op2);
7636 : }
7637 : }
7638 : break;
7639 :
7640 790922 : case VEC_MERGE:
7641 790922 : gcc_assert (GET_MODE (op0) == mode);
7642 790922 : gcc_assert (GET_MODE (op1) == mode);
7643 790922 : gcc_assert (VECTOR_MODE_P (mode));
7644 790922 : trueop2 = avoid_constant_pool_reference (op2);
7645 790922 : if (CONST_INT_P (trueop2)
7646 1261291 : && GET_MODE_NUNITS (mode).is_constant (&n_elts))
7647 : {
7648 470369 : unsigned HOST_WIDE_INT sel = UINTVAL (trueop2);
7649 470369 : unsigned HOST_WIDE_INT mask;
7650 470369 : if (n_elts == HOST_BITS_PER_WIDE_INT)
7651 : mask = -1;
7652 : else
7653 467912 : mask = (HOST_WIDE_INT_1U << n_elts) - 1;
7654 :
7655 470369 : if (!(sel & mask) && !side_effects_p (op0))
7656 : return op1;
7657 469932 : if ((sel & mask) == mask && !side_effects_p (op1))
7658 : return op0;
7659 :
7660 459181 : rtx trueop0 = avoid_constant_pool_reference (op0);
7661 459181 : rtx trueop1 = avoid_constant_pool_reference (op1);
7662 459181 : if (GET_CODE (trueop0) == CONST_VECTOR
7663 9273 : && GET_CODE (trueop1) == CONST_VECTOR)
7664 : {
7665 4805 : rtvec v = rtvec_alloc (n_elts);
7666 4805 : unsigned int i;
7667 :
7668 54292 : for (i = 0; i < n_elts; i++)
7669 44682 : RTVEC_ELT (v, i) = ((sel & (HOST_WIDE_INT_1U << i))
7670 44682 : ? CONST_VECTOR_ELT (trueop0, i)
7671 25083 : : CONST_VECTOR_ELT (trueop1, i));
7672 4805 : return gen_rtx_CONST_VECTOR (mode, v);
7673 : }
7674 :
7675 454376 : if (swap_commutative_operands_p (op0, op1)
7676 : /* Two operands have same precedence, then first bit of mask
7677 : select first operand. */
7678 454376 : || (!swap_commutative_operands_p (op1, op0) && !(sel & 1)))
7679 31619 : return simplify_gen_ternary (code, mode, mode, op1, op0,
7680 63238 : GEN_INT (~sel & mask));
7681 :
7682 : /* Replace (vec_merge (vec_merge a b m) c n) with (vec_merge b c n)
7683 : if no element from a appears in the result. */
7684 422757 : if (GET_CODE (op0) == VEC_MERGE)
7685 : {
7686 17218 : tem = avoid_constant_pool_reference (XEXP (op0, 2));
7687 17218 : if (CONST_INT_P (tem))
7688 : {
7689 1475 : unsigned HOST_WIDE_INT sel0 = UINTVAL (tem);
7690 1475 : if (!(sel & sel0 & mask) && !side_effects_p (XEXP (op0, 0)))
7691 104 : return simplify_gen_ternary (code, mode, mode,
7692 104 : XEXP (op0, 1), op1, op2);
7693 1371 : if (!(sel & ~sel0 & mask) && !side_effects_p (XEXP (op0, 1)))
7694 834 : return simplify_gen_ternary (code, mode, mode,
7695 834 : XEXP (op0, 0), op1, op2);
7696 : }
7697 : }
7698 421819 : if (GET_CODE (op1) == VEC_MERGE)
7699 : {
7700 588 : tem = avoid_constant_pool_reference (XEXP (op1, 2));
7701 588 : if (CONST_INT_P (tem))
7702 : {
7703 557 : unsigned HOST_WIDE_INT sel1 = UINTVAL (tem);
7704 557 : if (!(~sel & sel1 & mask) && !side_effects_p (XEXP (op1, 0)))
7705 526 : return simplify_gen_ternary (code, mode, mode,
7706 526 : op0, XEXP (op1, 1), op2);
7707 31 : if (!(~sel & ~sel1 & mask) && !side_effects_p (XEXP (op1, 1)))
7708 4 : return simplify_gen_ternary (code, mode, mode,
7709 4 : op0, XEXP (op1, 0), op2);
7710 : }
7711 : }
7712 :
7713 : /* Replace (vec_merge (vec_duplicate (vec_select a parallel (i))) a 1 << i)
7714 : with a. */
7715 421289 : if (GET_CODE (op0) == VEC_DUPLICATE
7716 143002 : && GET_CODE (XEXP (op0, 0)) == VEC_SELECT
7717 706 : && GET_CODE (XEXP (XEXP (op0, 0), 1)) == PARALLEL
7718 422701 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (op0, 0))), 1))
7719 : {
7720 638 : tem = XVECEXP ((XEXP (XEXP (op0, 0), 1)), 0, 0);
7721 638 : if (CONST_INT_P (tem) && CONST_INT_P (op2))
7722 : {
7723 638 : if (XEXP (XEXP (op0, 0), 0) == op1
7724 2 : && UINTVAL (op2) == HOST_WIDE_INT_1U << UINTVAL (tem))
7725 : return op1;
7726 : }
7727 : }
7728 : /* Replace (vec_merge (vec_duplicate (X)) (const_vector [A, B])
7729 : (const_int N))
7730 : with (vec_concat (X) (B)) if N == 1 or
7731 : (vec_concat (A) (X)) if N == 2. */
7732 421287 : if (GET_CODE (op0) == VEC_DUPLICATE
7733 143000 : && GET_CODE (op1) == CONST_VECTOR
7734 151514 : && known_eq (CONST_VECTOR_NUNITS (op1), 2)
7735 2346 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7736 422460 : && IN_RANGE (sel, 1, 2))
7737 : {
7738 1171 : rtx newop0 = XEXP (op0, 0);
7739 1171 : rtx newop1 = CONST_VECTOR_ELT (op1, 2 - sel);
7740 1171 : if (sel == 2)
7741 123 : std::swap (newop0, newop1);
7742 1171 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7743 : }
7744 : /* Replace (vec_merge (vec_duplicate x) (vec_concat (y) (z)) (const_int N))
7745 : with (vec_concat x z) if N == 1, or (vec_concat y x) if N == 2.
7746 : Only applies for vectors of two elements. */
7747 420116 : if (GET_CODE (op0) == VEC_DUPLICATE
7748 141829 : && GET_CODE (op1) == VEC_CONCAT
7749 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7750 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
7751 420116 : && IN_RANGE (sel, 1, 2))
7752 : {
7753 0 : rtx newop0 = XEXP (op0, 0);
7754 0 : rtx newop1 = XEXP (op1, 2 - sel);
7755 0 : rtx otherop = XEXP (op1, sel - 1);
7756 0 : if (sel == 2)
7757 0 : std::swap (newop0, newop1);
7758 : /* Don't want to throw away the other part of the vec_concat if
7759 : it has side-effects. */
7760 0 : if (!side_effects_p (otherop))
7761 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7762 : }
7763 :
7764 : /* Replace:
7765 :
7766 : (vec_merge:outer (vec_duplicate:outer x:inner)
7767 : (subreg:outer y:inner 0)
7768 : (const_int N))
7769 :
7770 : with (vec_concat:outer x:inner y:inner) if N == 1,
7771 : or (vec_concat:outer y:inner x:inner) if N == 2.
7772 :
7773 : Implicitly, this means we have a paradoxical subreg, but such
7774 : a check is cheap, so make it anyway.
7775 :
7776 : Only applies for vectors of two elements. */
7777 420116 : if (GET_CODE (op0) == VEC_DUPLICATE
7778 141829 : && GET_CODE (op1) == SUBREG
7779 44336 : && GET_MODE (op1) == GET_MODE (op0)
7780 44336 : && GET_MODE (SUBREG_REG (op1)) == GET_MODE (XEXP (op0, 0))
7781 0 : && paradoxical_subreg_p (op1)
7782 0 : && subreg_lowpart_p (op1)
7783 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7784 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
7785 420116 : && IN_RANGE (sel, 1, 2))
7786 : {
7787 0 : rtx newop0 = XEXP (op0, 0);
7788 0 : rtx newop1 = SUBREG_REG (op1);
7789 0 : if (sel == 2)
7790 0 : std::swap (newop0, newop1);
7791 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7792 : }
7793 :
7794 : /* Same as above but with switched operands:
7795 : Replace (vec_merge:outer (subreg:outer x:inner 0)
7796 : (vec_duplicate:outer y:inner)
7797 : (const_int N))
7798 :
7799 : with (vec_concat:outer x:inner y:inner) if N == 1,
7800 : or (vec_concat:outer y:inner x:inner) if N == 2. */
7801 420116 : if (GET_CODE (op1) == VEC_DUPLICATE
7802 29724 : && GET_CODE (op0) == SUBREG
7803 26567 : && GET_MODE (op0) == GET_MODE (op1)
7804 26567 : && GET_MODE (SUBREG_REG (op0)) == GET_MODE (XEXP (op1, 0))
7805 0 : && paradoxical_subreg_p (op0)
7806 0 : && subreg_lowpart_p (op0)
7807 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
7808 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7809 420116 : && IN_RANGE (sel, 1, 2))
7810 : {
7811 0 : rtx newop0 = SUBREG_REG (op0);
7812 0 : rtx newop1 = XEXP (op1, 0);
7813 0 : if (sel == 2)
7814 0 : std::swap (newop0, newop1);
7815 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7816 : }
7817 :
7818 : /* Replace (vec_merge (vec_duplicate x) (vec_duplicate y)
7819 : (const_int n))
7820 : with (vec_concat x y) or (vec_concat y x) depending on value
7821 : of N. */
7822 420116 : if (GET_CODE (op0) == VEC_DUPLICATE
7823 141829 : && GET_CODE (op1) == VEC_DUPLICATE
7824 198 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7825 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
7826 420116 : && IN_RANGE (sel, 1, 2))
7827 : {
7828 0 : rtx newop0 = XEXP (op0, 0);
7829 0 : rtx newop1 = XEXP (op1, 0);
7830 0 : if (sel == 2)
7831 0 : std::swap (newop0, newop1);
7832 :
7833 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7834 : }
7835 : }
7836 :
7837 740669 : if (rtx_equal_p (op0, op1)
7838 740669 : && !side_effects_p (op2) && !side_effects_p (op1))
7839 : return op0;
7840 :
7841 740376 : if (!side_effects_p (op2))
7842 : {
7843 736698 : rtx top0
7844 736698 : = may_trap_p (op0) ? NULL_RTX : simplify_merge_mask (op0, op2, 0);
7845 736698 : rtx top1
7846 736698 : = may_trap_p (op1) ? NULL_RTX : simplify_merge_mask (op1, op2, 1);
7847 736698 : if (top0 || top1)
7848 988 : return simplify_gen_ternary (code, mode, mode,
7849 : top0 ? top0 : op0,
7850 814 : top1 ? top1 : op1, op2);
7851 : }
7852 :
7853 : break;
7854 :
7855 0 : default:
7856 0 : gcc_unreachable ();
7857 : }
7858 :
7859 : return 0;
7860 : }
7861 :
7862 : /* Try to calculate NUM_BYTES bytes of the target memory image of X,
7863 : starting at byte FIRST_BYTE. Return true on success and add the
7864 : bytes to BYTES, such that each byte has BITS_PER_UNIT bits and such
7865 : that the bytes follow target memory order. Leave BYTES unmodified
7866 : on failure.
7867 :
7868 : MODE is the mode of X. The caller must reserve NUM_BYTES bytes in
7869 : BYTES before calling this function. */
7870 :
7871 : bool
7872 12937134 : native_encode_rtx (machine_mode mode, rtx x, vec<target_unit> &bytes,
7873 : unsigned int first_byte, unsigned int num_bytes)
7874 : {
7875 : /* Check the mode is sensible. */
7876 12937134 : gcc_assert (GET_MODE (x) == VOIDmode
7877 : ? is_a <scalar_int_mode> (mode)
7878 : : mode == GET_MODE (x));
7879 :
7880 12937134 : if (GET_CODE (x) == CONST_VECTOR)
7881 : {
7882 : /* CONST_VECTOR_ELT follows target memory order, so no shuffling
7883 : is necessary. The only complication is that MODE_VECTOR_BOOL
7884 : vectors can have several elements per byte. */
7885 990138 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
7886 : GET_MODE_NUNITS (mode));
7887 495069 : unsigned int elt = first_byte * BITS_PER_UNIT / elt_bits;
7888 495069 : if (elt_bits < BITS_PER_UNIT)
7889 : {
7890 : /* This is the only case in which elements can be smaller than
7891 : a byte. */
7892 0 : gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
7893 0 : auto mask = GET_MODE_MASK (GET_MODE_INNER (mode));
7894 0 : for (unsigned int i = 0; i < num_bytes; ++i)
7895 : {
7896 0 : target_unit value = 0;
7897 0 : for (unsigned int j = 0; j < BITS_PER_UNIT; j += elt_bits)
7898 : {
7899 0 : if (INTVAL (CONST_VECTOR_ELT (x, elt)))
7900 0 : value |= mask << j;
7901 0 : elt += 1;
7902 : }
7903 0 : bytes.quick_push (value);
7904 : }
7905 : return true;
7906 : }
7907 :
7908 495069 : unsigned int start = bytes.length ();
7909 495069 : unsigned int elt_bytes = GET_MODE_UNIT_SIZE (mode);
7910 : /* Make FIRST_BYTE relative to ELT. */
7911 495069 : first_byte %= elt_bytes;
7912 2583310 : while (num_bytes > 0)
7913 : {
7914 : /* Work out how many bytes we want from element ELT. */
7915 2088241 : unsigned int chunk_bytes = MIN (num_bytes, elt_bytes - first_byte);
7916 4176482 : if (!native_encode_rtx (GET_MODE_INNER (mode),
7917 : CONST_VECTOR_ELT (x, elt), bytes,
7918 : first_byte, chunk_bytes))
7919 : {
7920 0 : bytes.truncate (start);
7921 0 : return false;
7922 : }
7923 2088241 : elt += 1;
7924 2088241 : first_byte = 0;
7925 2088241 : num_bytes -= chunk_bytes;
7926 : }
7927 : return true;
7928 : }
7929 :
7930 : /* All subsequent cases are limited to scalars. */
7931 12442065 : scalar_mode smode;
7932 12472946 : if (!is_a <scalar_mode> (mode, &smode))
7933 : return false;
7934 :
7935 : /* Make sure that the region is in range. */
7936 12442065 : unsigned int end_byte = first_byte + num_bytes;
7937 12442065 : unsigned int mode_bytes = GET_MODE_SIZE (smode);
7938 12442065 : gcc_assert (end_byte <= mode_bytes);
7939 :
7940 12442065 : if (CONST_SCALAR_INT_P (x))
7941 : {
7942 : /* The target memory layout is affected by both BYTES_BIG_ENDIAN
7943 : and WORDS_BIG_ENDIAN. Use the subreg machinery to get the lsb
7944 : position of each byte. */
7945 11775370 : rtx_mode_t value (x, smode);
7946 11775370 : wide_int_ref value_wi (value);
7947 50462273 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
7948 : {
7949 : /* Always constant because the inputs are. */
7950 38686903 : unsigned int lsb
7951 38686903 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
7952 : /* Operate directly on the encoding rather than using
7953 : wi::extract_uhwi, so that we preserve the sign or zero
7954 : extension for modes that are not a whole number of bits in
7955 : size. (Zero extension is only used for the combination of
7956 : innermode == BImode && STORE_FLAG_VALUE == 1). */
7957 38686903 : unsigned int elt = lsb / HOST_BITS_PER_WIDE_INT;
7958 38686903 : unsigned int shift = lsb % HOST_BITS_PER_WIDE_INT;
7959 38686903 : unsigned HOST_WIDE_INT uhwi = value_wi.elt (elt);
7960 38686903 : bytes.quick_push (uhwi >> shift);
7961 : }
7962 11775370 : return true;
7963 : }
7964 :
7965 666695 : if (CONST_DOUBLE_P (x))
7966 : {
7967 : /* real_to_target produces an array of integers in target memory order.
7968 : All integers before the last one have 32 bits; the last one may
7969 : have 32 bits or fewer, depending on whether the mode bitsize
7970 : is divisible by 32. Each of these integers is then laid out
7971 : in target memory as any other integer would be. */
7972 635814 : long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
7973 635814 : real_to_target (el32, CONST_DOUBLE_REAL_VALUE (x), smode);
7974 :
7975 : /* The (maximum) number of target bytes per element of el32. */
7976 635814 : unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
7977 635814 : gcc_assert (bytes_per_el32 != 0);
7978 :
7979 : /* Build up the integers in a similar way to the CONST_SCALAR_INT_P
7980 : handling above. */
7981 4348422 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
7982 : {
7983 3712608 : unsigned int index = byte / bytes_per_el32;
7984 3712608 : unsigned int subbyte = byte % bytes_per_el32;
7985 3712608 : unsigned int int_bytes = MIN (bytes_per_el32,
7986 : mode_bytes - index * bytes_per_el32);
7987 : /* Always constant because the inputs are. */
7988 3712608 : unsigned int lsb
7989 3712608 : = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
7990 3712608 : bytes.quick_push ((unsigned long) el32[index] >> lsb);
7991 : }
7992 635814 : return true;
7993 : }
7994 :
7995 30881 : if (GET_CODE (x) == CONST_FIXED)
7996 : {
7997 0 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
7998 : {
7999 : /* Always constant because the inputs are. */
8000 0 : unsigned int lsb
8001 0 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
8002 0 : unsigned HOST_WIDE_INT piece = CONST_FIXED_VALUE_LOW (x);
8003 0 : if (lsb >= HOST_BITS_PER_WIDE_INT)
8004 : {
8005 0 : lsb -= HOST_BITS_PER_WIDE_INT;
8006 0 : piece = CONST_FIXED_VALUE_HIGH (x);
8007 : }
8008 0 : bytes.quick_push (piece >> lsb);
8009 : }
8010 : return true;
8011 : }
8012 :
8013 : return false;
8014 : }
8015 :
8016 : /* Read a vector of mode MODE from the target memory image given by BYTES,
8017 : starting at byte FIRST_BYTE. The vector is known to be encodable using
8018 : NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each,
8019 : and BYTES is known to have enough bytes to supply NPATTERNS *
8020 : NELTS_PER_PATTERN vector elements. Each element of BYTES contains
8021 : BITS_PER_UNIT bits and the bytes are in target memory order.
8022 :
8023 : Return the vector on success, otherwise return NULL_RTX. */
8024 :
8025 : rtx
8026 231486 : native_decode_vector_rtx (machine_mode mode, const vec<target_unit> &bytes,
8027 : unsigned int first_byte, unsigned int npatterns,
8028 : unsigned int nelts_per_pattern)
8029 : {
8030 231486 : rtx_vector_builder builder (mode, npatterns, nelts_per_pattern);
8031 :
8032 462972 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
8033 : GET_MODE_NUNITS (mode));
8034 231486 : if (elt_bits < BITS_PER_UNIT)
8035 : {
8036 : /* This is the only case in which elements can be smaller than a byte.
8037 : Element 0 is always in the lsb of the containing byte. */
8038 0 : gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
8039 0 : for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
8040 : {
8041 0 : unsigned int bit_index = first_byte * BITS_PER_UNIT + i * elt_bits;
8042 0 : unsigned int byte_index = bit_index / BITS_PER_UNIT;
8043 0 : unsigned int lsb = bit_index % BITS_PER_UNIT;
8044 0 : unsigned int value = bytes[byte_index] >> lsb;
8045 0 : builder.quick_push (gen_int_mode (value, GET_MODE_INNER (mode)));
8046 : }
8047 : }
8048 : else
8049 : {
8050 930074 : for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
8051 : {
8052 1397176 : rtx x = native_decode_rtx (GET_MODE_INNER (mode), bytes, first_byte);
8053 698588 : if (!x)
8054 0 : return NULL_RTX;
8055 698588 : builder.quick_push (x);
8056 698588 : first_byte += elt_bits / BITS_PER_UNIT;
8057 : }
8058 : }
8059 231486 : return builder.build ();
8060 231486 : }
8061 :
8062 : /* Extract a PRECISION-bit integer from bytes [FIRST_BYTE, FIRST_BYTE + SIZE)
8063 : of target memory image BYTES. */
8064 :
8065 : wide_int
8066 10837479 : native_decode_int (const vec<target_unit> &bytes, unsigned int first_byte,
8067 : unsigned int size, unsigned int precision)
8068 : {
8069 : /* Pull the bytes msb first, so that we can use simple
8070 : shift-and-insert wide_int operations. */
8071 10837479 : wide_int result (wi::zero (precision));
8072 49781284 : for (unsigned int i = 0; i < size; ++i)
8073 : {
8074 38943805 : unsigned int lsb = (size - i - 1) * BITS_PER_UNIT;
8075 : /* Always constant because the inputs are. */
8076 38943805 : unsigned int subbyte
8077 38943805 : = subreg_size_offset_from_lsb (1, size, lsb).to_constant ();
8078 38943805 : result <<= BITS_PER_UNIT;
8079 38943805 : result |= bytes[first_byte + subbyte];
8080 : }
8081 10837479 : return result;
8082 : }
8083 :
8084 : /* Read an rtx of mode MODE from the target memory image given by BYTES,
8085 : starting at byte FIRST_BYTE. Each element of BYTES contains BITS_PER_UNIT
8086 : bits and the bytes are in target memory order. The image has enough
8087 : values to specify all bytes of MODE.
8088 :
8089 : Return the rtx on success, otherwise return NULL_RTX. */
8090 :
8091 : rtx
8092 11135216 : native_decode_rtx (machine_mode mode, const vec<target_unit> &bytes,
8093 : unsigned int first_byte)
8094 : {
8095 11135216 : if (VECTOR_MODE_P (mode))
8096 : {
8097 : /* If we know at compile time how many elements there are,
8098 : pull each element directly from BYTES. */
8099 59338 : unsigned int nelts;
8100 118676 : if (GET_MODE_NUNITS (mode).is_constant (&nelts))
8101 59338 : return native_decode_vector_rtx (mode, bytes, first_byte, nelts, 1);
8102 : return NULL_RTX;
8103 : }
8104 :
8105 11075878 : scalar_int_mode imode;
8106 11075878 : if (is_a <scalar_int_mode> (mode, &imode)
8107 10837479 : && GET_MODE_PRECISION (imode) <= MAX_BITSIZE_MODE_ANY_INT)
8108 : {
8109 10837479 : auto result = native_decode_int (bytes, first_byte,
8110 10837479 : GET_MODE_SIZE (imode),
8111 21674958 : GET_MODE_PRECISION (imode));
8112 10837479 : return immed_wide_int_const (result, imode);
8113 10837479 : }
8114 :
8115 238399 : scalar_float_mode fmode;
8116 238399 : if (is_a <scalar_float_mode> (mode, &fmode))
8117 : {
8118 : /* We need to build an array of integers in target memory order.
8119 : All integers before the last one have 32 bits; the last one may
8120 : have 32 bits or fewer, depending on whether the mode bitsize
8121 : is divisible by 32. */
8122 238369 : long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
8123 238369 : unsigned int num_el32 = CEIL (GET_MODE_BITSIZE (fmode), 32);
8124 238369 : memset (el32, 0, num_el32 * sizeof (long));
8125 :
8126 : /* The (maximum) number of target bytes per element of el32. */
8127 238369 : unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
8128 238369 : gcc_assert (bytes_per_el32 != 0);
8129 :
8130 238369 : unsigned int mode_bytes = GET_MODE_SIZE (fmode);
8131 1657093 : for (unsigned int byte = 0; byte < mode_bytes; ++byte)
8132 : {
8133 1418724 : unsigned int index = byte / bytes_per_el32;
8134 1418724 : unsigned int subbyte = byte % bytes_per_el32;
8135 1418724 : unsigned int int_bytes = MIN (bytes_per_el32,
8136 : mode_bytes - index * bytes_per_el32);
8137 : /* Always constant because the inputs are. */
8138 1418724 : unsigned int lsb
8139 1418724 : = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
8140 1418724 : el32[index] |= (unsigned long) bytes[first_byte + byte] << lsb;
8141 : }
8142 238369 : REAL_VALUE_TYPE r;
8143 238369 : real_from_target (&r, el32, fmode);
8144 238369 : return const_double_from_real_value (r, fmode);
8145 : }
8146 :
8147 30 : if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
8148 : {
8149 0 : scalar_mode smode = as_a <scalar_mode> (mode);
8150 0 : FIXED_VALUE_TYPE f;
8151 0 : f.data.low = 0;
8152 0 : f.data.high = 0;
8153 0 : f.mode = smode;
8154 :
8155 0 : unsigned int mode_bytes = GET_MODE_SIZE (smode);
8156 0 : for (unsigned int byte = 0; byte < mode_bytes; ++byte)
8157 : {
8158 : /* Always constant because the inputs are. */
8159 0 : unsigned int lsb
8160 0 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
8161 0 : unsigned HOST_WIDE_INT unit = bytes[first_byte + byte];
8162 0 : if (lsb >= HOST_BITS_PER_WIDE_INT)
8163 0 : f.data.high |= unit << (lsb - HOST_BITS_PER_WIDE_INT);
8164 : else
8165 0 : f.data.low |= unit << lsb;
8166 : }
8167 0 : return CONST_FIXED_FROM_FIXED_VALUE (f, mode);
8168 : }
8169 :
8170 : return NULL_RTX;
8171 : }
8172 :
8173 : /* Simplify a byte offset BYTE into CONST_VECTOR X. The main purpose
8174 : is to convert a runtime BYTE value into a constant one. */
8175 :
8176 : static poly_uint64
8177 282672 : simplify_const_vector_byte_offset (rtx x, poly_uint64 byte)
8178 : {
8179 : /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
8180 282672 : machine_mode mode = GET_MODE (x);
8181 565344 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
8182 : GET_MODE_NUNITS (mode));
8183 : /* The number of bits needed to encode one element from each pattern. */
8184 282672 : unsigned int sequence_bits = CONST_VECTOR_NPATTERNS (x) * elt_bits;
8185 :
8186 : /* Identify the start point in terms of a sequence number and a byte offset
8187 : within that sequence. */
8188 282672 : poly_uint64 first_sequence;
8189 282672 : unsigned HOST_WIDE_INT subbit;
8190 282672 : if (can_div_trunc_p (byte * BITS_PER_UNIT, sequence_bits,
8191 : &first_sequence, &subbit))
8192 : {
8193 282672 : unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
8194 282672 : if (nelts_per_pattern == 1)
8195 : /* This is a duplicated vector, so the value of FIRST_SEQUENCE
8196 : doesn't matter. */
8197 230168 : byte = subbit / BITS_PER_UNIT;
8198 52504 : else if (nelts_per_pattern == 2 && known_gt (first_sequence, 0U))
8199 : {
8200 : /* The subreg drops the first element from each pattern and
8201 : only uses the second element. Find the first sequence
8202 : that starts on a byte boundary. */
8203 5568 : subbit += least_common_multiple (sequence_bits, BITS_PER_UNIT);
8204 5568 : byte = subbit / BITS_PER_UNIT;
8205 : }
8206 : }
8207 282672 : return byte;
8208 : }
8209 :
8210 : /* Subroutine of simplify_subreg in which:
8211 :
8212 : - X is known to be a CONST_VECTOR
8213 : - OUTERMODE is known to be a vector mode
8214 :
8215 : Try to handle the subreg by operating on the CONST_VECTOR encoding
8216 : rather than on each individual element of the CONST_VECTOR.
8217 :
8218 : Return the simplified subreg on success, otherwise return NULL_RTX. */
8219 :
8220 : static rtx
8221 179994 : simplify_const_vector_subreg (machine_mode outermode, rtx x,
8222 : machine_mode innermode, unsigned int first_byte)
8223 : {
8224 : /* Paradoxical subregs of vectors have dubious semantics. */
8225 179994 : if (paradoxical_subreg_p (outermode, innermode))
8226 : return NULL_RTX;
8227 :
8228 : /* We can only preserve the semantics of a stepped pattern if the new
8229 : vector element is the same as the original one. */
8230 179848 : if (CONST_VECTOR_STEPPED_P (x)
8231 200472 : && GET_MODE_INNER (outermode) != GET_MODE_INNER (innermode))
8232 : return NULL_RTX;
8233 :
8234 : /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
8235 172148 : unsigned int x_elt_bits
8236 172148 : = vector_element_size (GET_MODE_PRECISION (innermode),
8237 : GET_MODE_NUNITS (innermode));
8238 172148 : unsigned int out_elt_bits
8239 172148 : = vector_element_size (GET_MODE_PRECISION (outermode),
8240 : GET_MODE_NUNITS (outermode));
8241 :
8242 : /* The number of bits needed to encode one element from every pattern
8243 : of the original vector. */
8244 172148 : unsigned int x_sequence_bits = CONST_VECTOR_NPATTERNS (x) * x_elt_bits;
8245 :
8246 : /* The number of bits needed to encode one element from every pattern
8247 : of the result. */
8248 172148 : unsigned int out_sequence_bits
8249 172148 : = least_common_multiple (x_sequence_bits, out_elt_bits);
8250 :
8251 : /* Work out the number of interleaved patterns in the output vector
8252 : and the number of encoded elements per pattern. */
8253 172148 : unsigned int out_npatterns = out_sequence_bits / out_elt_bits;
8254 172148 : unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
8255 :
8256 : /* The encoding scheme requires the number of elements to be a multiple
8257 : of the number of patterns, so that each pattern appears at least once
8258 : and so that the same number of elements appear from each pattern. */
8259 344296 : bool ok_p = multiple_p (GET_MODE_NUNITS (outermode), out_npatterns);
8260 172148 : unsigned int const_nunits;
8261 344296 : if (GET_MODE_NUNITS (outermode).is_constant (&const_nunits)
8262 172148 : && (!ok_p || out_npatterns * nelts_per_pattern > const_nunits))
8263 : {
8264 : /* Either the encoding is invalid, or applying it would give us
8265 : more elements than we need. Just encode each element directly. */
8266 : out_npatterns = const_nunits;
8267 : nelts_per_pattern = 1;
8268 : }
8269 : else if (!ok_p)
8270 : return NULL_RTX;
8271 :
8272 : /* Get enough bytes of X to form the new encoding. */
8273 172148 : unsigned int buffer_bits = out_npatterns * nelts_per_pattern * out_elt_bits;
8274 172148 : unsigned int buffer_bytes = CEIL (buffer_bits, BITS_PER_UNIT);
8275 172148 : auto_vec<target_unit, 128> buffer (buffer_bytes);
8276 172148 : if (!native_encode_rtx (innermode, x, buffer, first_byte, buffer_bytes))
8277 : return NULL_RTX;
8278 :
8279 : /* Reencode the bytes as OUTERMODE. */
8280 172148 : return native_decode_vector_rtx (outermode, buffer, 0, out_npatterns,
8281 172148 : nelts_per_pattern);
8282 172148 : }
8283 :
8284 : /* Try to simplify a subreg of a constant by encoding the subreg region
8285 : as a sequence of target bytes and reading them back in the new mode.
8286 : Return the new value on success, otherwise return null.
8287 :
8288 : The subreg has outer mode OUTERMODE, inner mode INNERMODE, inner value X
8289 : and byte offset FIRST_BYTE. */
8290 :
8291 : static rtx
8292 10148556 : simplify_immed_subreg (fixed_size_mode outermode, rtx x,
8293 : machine_mode innermode, unsigned int first_byte)
8294 : {
8295 10148556 : unsigned int buffer_bytes = GET_MODE_SIZE (outermode);
8296 10148556 : auto_vec<target_unit, 128> buffer (buffer_bytes);
8297 :
8298 : /* Some ports misuse CCmode. */
8299 10148556 : if (GET_MODE_CLASS (outermode) == MODE_CC && CONST_INT_P (x))
8300 : return x;
8301 :
8302 : /* Paradoxical subregs read undefined values for bytes outside of the
8303 : inner value. However, we have traditionally always sign-extended
8304 : integer constants and zero-extended others. */
8305 10146616 : unsigned int inner_bytes = buffer_bytes;
8306 10146616 : if (paradoxical_subreg_p (outermode, innermode))
8307 : {
8308 742472 : if (!GET_MODE_SIZE (innermode).is_constant (&inner_bytes))
8309 0 : return NULL_RTX;
8310 :
8311 371236 : target_unit filler = 0;
8312 371236 : if (CONST_SCALAR_INT_P (x) && wi::neg_p (rtx_mode_t (x, innermode)))
8313 43515 : filler = -1;
8314 :
8315 : /* Add any leading bytes due to big-endian layout. The number of
8316 : bytes must be constant because both modes have constant size. */
8317 371236 : unsigned int leading_bytes
8318 371236 : = -byte_lowpart_offset (outermode, innermode).to_constant ();
8319 371236 : for (unsigned int i = 0; i < leading_bytes; ++i)
8320 0 : buffer.quick_push (filler);
8321 :
8322 371236 : if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
8323 0 : return NULL_RTX;
8324 :
8325 : /* Add any trailing bytes due to little-endian layout. */
8326 4537048 : while (buffer.length () < buffer_bytes)
8327 1897288 : buffer.quick_push (filler);
8328 : }
8329 9775380 : else if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
8330 : return NULL_RTX;
8331 10146616 : rtx ret = native_decode_rtx (outermode, buffer, 0);
8332 10146616 : if (ret && FLOAT_MODE_P (outermode))
8333 : {
8334 124366 : auto_vec<target_unit, 128> buffer2 (buffer_bytes);
8335 124366 : if (!native_encode_rtx (outermode, ret, buffer2, 0, buffer_bytes))
8336 : return NULL_RTX;
8337 1382569 : for (unsigned int i = 0; i < buffer_bytes; ++i)
8338 1258238 : if (buffer[i] != buffer2[i])
8339 : return NULL_RTX;
8340 124366 : }
8341 : return ret;
8342 10148556 : }
8343 :
8344 : /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
8345 : Return 0 if no simplifications are possible. */
8346 : rtx
8347 66954262 : simplify_context::simplify_subreg (machine_mode outermode, rtx op,
8348 : machine_mode innermode, poly_uint64 byte)
8349 : {
8350 : /* Little bit of sanity checking. */
8351 66954262 : gcc_assert (innermode != VOIDmode);
8352 66954262 : gcc_assert (outermode != VOIDmode);
8353 66954262 : gcc_assert (innermode != BLKmode);
8354 66954262 : gcc_assert (outermode != BLKmode);
8355 :
8356 66954262 : gcc_assert (GET_MODE (op) == innermode
8357 : || GET_MODE (op) == VOIDmode);
8358 :
8359 133908524 : poly_uint64 outersize = GET_MODE_SIZE (outermode);
8360 66954262 : if (!multiple_p (byte, outersize))
8361 : return NULL_RTX;
8362 :
8363 133908484 : poly_uint64 innersize = GET_MODE_SIZE (innermode);
8364 66954242 : if (maybe_ge (byte, innersize))
8365 : return NULL_RTX;
8366 :
8367 66954242 : if (outermode == innermode && known_eq (byte, 0U))
8368 4592928 : return op;
8369 :
8370 62361314 : if (GET_CODE (op) == CONST_VECTOR)
8371 282672 : byte = simplify_const_vector_byte_offset (op, byte);
8372 :
8373 124722628 : if (multiple_p (byte, GET_MODE_UNIT_SIZE (innermode)))
8374 : {
8375 56624946 : rtx elt;
8376 :
8377 48035949 : if (VECTOR_MODE_P (outermode)
8378 25766991 : && GET_MODE_INNER (outermode) == GET_MODE_INNER (innermode)
8379 58341914 : && vec_duplicate_p (op, &elt))
8380 12085 : return gen_vec_duplicate (outermode, elt);
8381 :
8382 56621201 : if (outermode == GET_MODE_INNER (innermode)
8383 56621201 : && vec_duplicate_p (op, &elt))
8384 8340 : return elt;
8385 : }
8386 :
8387 62349229 : if (CONST_SCALAR_INT_P (op)
8388 52361362 : || CONST_DOUBLE_AS_FLOAT_P (op)
8389 52304401 : || CONST_FIXED_P (op)
8390 52304401 : || GET_CODE (op) == CONST_VECTOR)
8391 : {
8392 10320704 : unsigned HOST_WIDE_INT cbyte;
8393 10320704 : if (byte.is_constant (&cbyte))
8394 : {
8395 10320704 : if (GET_CODE (op) == CONST_VECTOR && VECTOR_MODE_P (outermode))
8396 : {
8397 179994 : rtx tmp = simplify_const_vector_subreg (outermode, op,
8398 : innermode, cbyte);
8399 179994 : if (tmp)
8400 10320704 : return tmp;
8401 : }
8402 :
8403 10148556 : fixed_size_mode fs_outermode;
8404 10148556 : if (is_a <fixed_size_mode> (outermode, &fs_outermode))
8405 10148556 : return simplify_immed_subreg (fs_outermode, op, innermode, cbyte);
8406 : }
8407 : }
8408 :
8409 : /* Changing mode twice with SUBREG => just change it once,
8410 : or not at all if changing back op starting mode. */
8411 52028525 : if (GET_CODE (op) == SUBREG)
8412 : {
8413 1336607 : machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
8414 2673214 : poly_uint64 innermostsize = GET_MODE_SIZE (innermostmode);
8415 1336607 : rtx newx;
8416 :
8417 : /* Make sure that the relationship between the two subregs is
8418 : known at compile time. */
8419 1336607 : if (!ordered_p (outersize, innermostsize))
8420 : return NULL_RTX;
8421 :
8422 1336607 : if (outermode == innermostmode
8423 771767 : && known_eq (byte, subreg_lowpart_offset (outermode, innermode))
8424 2108373 : && known_eq (SUBREG_BYTE (op),
8425 : subreg_lowpart_offset (innermode, innermostmode)))
8426 771766 : return SUBREG_REG (op);
8427 :
8428 : /* Work out the memory offset of the final OUTERMODE value relative
8429 : to the inner value of OP. */
8430 564841 : poly_int64 mem_offset = subreg_memory_offset (outermode,
8431 : innermode, byte);
8432 564841 : poly_int64 op_mem_offset = subreg_memory_offset (op);
8433 564841 : poly_int64 final_offset = mem_offset + op_mem_offset;
8434 :
8435 : /* See whether resulting subreg will be paradoxical. */
8436 564841 : if (!paradoxical_subreg_p (outermode, innermostmode))
8437 : {
8438 : /* Bail out in case resulting subreg would be incorrect. */
8439 918030 : if (maybe_lt (final_offset, 0)
8440 918021 : || maybe_ge (poly_uint64 (final_offset), innermostsize)
8441 918029 : || !multiple_p (final_offset, outersize))
8442 9 : return NULL_RTX;
8443 : }
8444 : else
8445 : {
8446 105826 : poly_int64 required_offset = subreg_memory_offset (outermode,
8447 : innermostmode, 0);
8448 105826 : if (maybe_ne (final_offset, required_offset))
8449 0 : return NULL_RTX;
8450 : /* Paradoxical subregs always have byte offset 0. */
8451 105826 : final_offset = 0;
8452 : }
8453 :
8454 : /* Recurse for further possible simplifications. */
8455 564832 : newx = simplify_subreg (outermode, SUBREG_REG (op), innermostmode,
8456 564832 : final_offset);
8457 564832 : if (newx)
8458 : return newx;
8459 564453 : if (validate_subreg (outermode, innermostmode,
8460 564453 : SUBREG_REG (op), final_offset))
8461 : {
8462 505918 : newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
8463 505918 : if (SUBREG_PROMOTED_VAR_P (op)
8464 610 : && SUBREG_PROMOTED_SIGN (op) >= 0
8465 610 : && GET_MODE_CLASS (outermode) == MODE_INT
8466 606 : && known_ge (outersize, innersize)
8467 392 : && known_le (outersize, innermostsize)
8468 505928 : && subreg_lowpart_p (newx))
8469 : {
8470 10 : SUBREG_PROMOTED_VAR_P (newx) = 1;
8471 10 : SUBREG_PROMOTED_SET (newx, SUBREG_PROMOTED_GET (op));
8472 : }
8473 505918 : return newx;
8474 : }
8475 : return NULL_RTX;
8476 : }
8477 :
8478 : /* SUBREG of a hard register => just change the register number
8479 : and/or mode. If the hard register is not valid in that mode,
8480 : suppress this simplification. If the hard register is the stack,
8481 : frame, or argument pointer, leave this as a SUBREG. */
8482 :
8483 50691918 : if (REG_P (op) && HARD_REGISTER_P (op))
8484 : {
8485 10608616 : unsigned int regno, final_regno;
8486 :
8487 10608616 : regno = REGNO (op);
8488 10608616 : final_regno = simplify_subreg_regno (regno, innermode, byte, outermode);
8489 10608616 : if (HARD_REGISTER_NUM_P (final_regno))
8490 : {
8491 10583519 : rtx x = gen_rtx_REG_offset (op, outermode, final_regno,
8492 : subreg_memory_offset (outermode,
8493 : innermode, byte));
8494 :
8495 : /* Propagate original regno. We don't have any way to specify
8496 : the offset inside original regno, so do so only for lowpart.
8497 : The information is used only by alias analysis that cannot
8498 : grog partial register anyway. */
8499 :
8500 10583519 : if (known_eq (subreg_lowpart_offset (outermode, innermode), byte))
8501 7927663 : ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op);
8502 10583519 : return x;
8503 : }
8504 : }
8505 :
8506 : /* If we have a SUBREG of a register that we are replacing and we are
8507 : replacing it with a MEM, make a new MEM and try replacing the
8508 : SUBREG with it. Don't do this if the MEM has a mode-dependent address
8509 : or if we would be widening it. */
8510 :
8511 40108399 : if (MEM_P (op)
8512 1692914 : && ! mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op))
8513 : /* Allow splitting of volatile memory references in case we don't
8514 : have instruction to move the whole thing. */
8515 1692911 : && (! MEM_VOLATILE_P (op)
8516 44289 : || ! have_insn_for (SET, innermode))
8517 : && !(STRICT_ALIGNMENT && MEM_ALIGN (op) < GET_MODE_ALIGNMENT (outermode))
8518 41757021 : && known_le (outersize, innersize))
8519 809821 : return adjust_address_nv (op, outermode, byte);
8520 :
8521 : /* Handle complex or vector values represented as CONCAT or VEC_CONCAT
8522 : of two parts. */
8523 39298578 : if (GET_CODE (op) == CONCAT
8524 39298578 : || GET_CODE (op) == VEC_CONCAT)
8525 : {
8526 195834 : poly_uint64 final_offset;
8527 195834 : rtx part, res;
8528 :
8529 195834 : machine_mode part_mode = GET_MODE (XEXP (op, 0));
8530 195834 : if (part_mode == VOIDmode)
8531 11 : part_mode = GET_MODE_INNER (GET_MODE (op));
8532 391668 : poly_uint64 part_size = GET_MODE_SIZE (part_mode);
8533 195834 : if (known_lt (byte, part_size))
8534 : {
8535 194278 : part = XEXP (op, 0);
8536 194278 : final_offset = byte;
8537 : }
8538 1556 : else if (known_ge (byte, part_size))
8539 : {
8540 1556 : part = XEXP (op, 1);
8541 1556 : final_offset = byte - part_size;
8542 : }
8543 : else
8544 : return NULL_RTX;
8545 :
8546 195834 : if (maybe_gt (final_offset + outersize, part_size))
8547 : return NULL_RTX;
8548 :
8549 128645 : part_mode = GET_MODE (part);
8550 128645 : if (part_mode == VOIDmode)
8551 0 : part_mode = GET_MODE_INNER (GET_MODE (op));
8552 128645 : res = simplify_subreg (outermode, part, part_mode, final_offset);
8553 128645 : if (res)
8554 : return res;
8555 295 : if (GET_MODE (part) != VOIDmode
8556 295 : && validate_subreg (outermode, part_mode, part, final_offset))
8557 295 : return gen_rtx_SUBREG (outermode, part, final_offset);
8558 0 : return NULL_RTX;
8559 : }
8560 :
8561 : /* Simplify
8562 : (subreg (vec_merge (X)
8563 : (vector)
8564 : (const_int ((1 << N) | M)))
8565 : (N * sizeof (outermode)))
8566 : to
8567 : (subreg (X) (N * sizeof (outermode)))
8568 : */
8569 39102744 : unsigned int idx;
8570 78205488 : if (constant_multiple_p (byte, GET_MODE_SIZE (outermode), &idx)
8571 39102744 : && idx < HOST_BITS_PER_WIDE_INT
8572 39102744 : && GET_CODE (op) == VEC_MERGE
8573 632760 : && GET_MODE_INNER (innermode) == outermode
8574 4887 : && CONST_INT_P (XEXP (op, 2))
8575 39107049 : && (UINTVAL (XEXP (op, 2)) & (HOST_WIDE_INT_1U << idx)) != 0)
8576 4296 : return simplify_gen_subreg (outermode, XEXP (op, 0), innermode, byte);
8577 :
8578 : /* A SUBREG resulting from a zero extension may fold to zero if
8579 : it extracts higher bits that the ZERO_EXTEND's source bits. */
8580 39098448 : if (GET_CODE (op) == ZERO_EXTEND && SCALAR_INT_MODE_P (innermode))
8581 : {
8582 219060 : poly_uint64 bitpos = subreg_lsb_1 (outermode, innermode, byte);
8583 219060 : if (known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (XEXP (op, 0)))))
8584 53983 : return CONST0_RTX (outermode);
8585 : }
8586 :
8587 : /* Optimize SUBREGS of scalar integral ASHIFT by a valid constant. */
8588 39044465 : if (GET_CODE (op) == ASHIFT
8589 702125 : && SCALAR_INT_MODE_P (innermode)
8590 674737 : && CONST_INT_P (XEXP (op, 1))
8591 595333 : && INTVAL (XEXP (op, 1)) > 0
8592 40341873 : && known_gt (GET_MODE_BITSIZE (innermode), INTVAL (XEXP (op, 1))))
8593 : {
8594 595283 : HOST_WIDE_INT val = INTVAL (XEXP (op, 1));
8595 : /* A lowpart SUBREG of a ASHIFT by a constant may fold to zero. */
8596 595283 : if (known_eq (subreg_lowpart_offset (outermode, innermode), byte)
8597 1154014 : && known_le (GET_MODE_BITSIZE (outermode), val))
8598 188927 : return CONST0_RTX (outermode);
8599 : /* Optimize the highpart SUBREG of a suitable ASHIFT (ZERO_EXTEND). */
8600 440361 : if (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
8601 34702 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == outermode
8602 69090 : && known_eq (GET_MODE_BITSIZE (outermode), val)
8603 68010 : && known_eq (GET_MODE_BITSIZE (innermode), 2 * val)
8604 475063 : && known_eq (subreg_highpart_offset (outermode, innermode), byte))
8605 34005 : return XEXP (XEXP (op, 0), 0);
8606 : }
8607 :
8608 40289017 : auto distribute_subreg = [&](rtx op)
8609 : {
8610 1433479 : return simplify_subreg (outermode, op, innermode, byte);
8611 38855538 : };
8612 :
8613 : /* Try distributing the subreg through logic operations, if that
8614 : leads to all subexpressions being simplified. For example,
8615 : distributing the outer subreg in:
8616 :
8617 : (subreg:SI (not:QI (subreg:QI (reg:SI X) <lowpart>)) 0)
8618 :
8619 : gives:
8620 :
8621 : (not:SI (reg:SI X))
8622 :
8623 : This should be a win if the outermode is word_mode, since logical
8624 : operations on word_mode should (a) be no more expensive than logical
8625 : operations on subword modes and (b) are likely to be cheaper than
8626 : logical operations on multiword modes.
8627 :
8628 : Otherwise, handle the case where the subreg is non-narrowing and does
8629 : not change the number of words. The non-narrowing condition ensures
8630 : that we don't convert word_mode operations to subword operations. */
8631 38855538 : scalar_int_mode int_outermode, int_innermode;
8632 38855538 : if (is_a <scalar_int_mode> (outermode, &int_outermode)
8633 32015389 : && is_a <scalar_int_mode> (innermode, &int_innermode)
8634 69680884 : && (outermode == word_mode
8635 17453389 : || ((GET_MODE_PRECISION (int_outermode)
8636 17453389 : >= GET_MODE_PRECISION (int_innermode))
8637 4230359 : && (CEIL (GET_MODE_SIZE (int_outermode), UNITS_PER_WORD)
8638 4142286 : <= CEIL (GET_MODE_SIZE (int_innermode), UNITS_PER_WORD)))))
8639 17454968 : switch (GET_CODE (op))
8640 : {
8641 31958 : case NOT:
8642 31958 : if (rtx op0 = distribute_subreg (XEXP (op, 0)))
8643 1918 : return simplify_gen_unary (GET_CODE (op), outermode, op0, outermode);
8644 : break;
8645 :
8646 454162 : case AND:
8647 454162 : case IOR:
8648 454162 : case XOR:
8649 454162 : if (rtx op0 = distribute_subreg (XEXP (op, 0)))
8650 200703 : if (rtx op1 = distribute_subreg (XEXP (op, 1)))
8651 195658 : return simplify_gen_binary (GET_CODE (op), outermode, op0, op1);
8652 : break;
8653 :
8654 : default:
8655 : break;
8656 : }
8657 :
8658 38657962 : if (is_a <scalar_int_mode> (outermode, &int_outermode)
8659 31817813 : && is_a <scalar_int_mode> (innermode, &int_innermode)
8660 70475775 : && known_eq (byte, subreg_lowpart_offset (int_outermode, int_innermode)))
8661 : {
8662 : /* Handle polynomial integers. The upper bits of a paradoxical
8663 : subreg are undefined, so this is safe regardless of whether
8664 : we're truncating or extending. */
8665 28512461 : if (CONST_POLY_INT_P (op))
8666 : {
8667 : poly_wide_int val
8668 : = poly_wide_int::from (const_poly_int_value (op),
8669 : GET_MODE_PRECISION (int_outermode),
8670 : SIGNED);
8671 : return immed_wide_int_const (val, int_outermode);
8672 : }
8673 :
8674 28512461 : if (GET_MODE_PRECISION (int_outermode)
8675 28512461 : < GET_MODE_PRECISION (int_innermode))
8676 : {
8677 16465001 : rtx tem = simplify_truncation (int_outermode, op, int_innermode);
8678 16465001 : if (tem)
8679 : return tem;
8680 : }
8681 : }
8682 :
8683 : /* If the outer mode is not integral, try taking a subreg with the equivalent
8684 : integer outer mode and then bitcasting the result.
8685 : Other simplifications rely on integer to integer subregs and we'd
8686 : potentially miss out on optimizations otherwise. */
8687 75443350 : if (known_gt (GET_MODE_SIZE (innermode),
8688 : GET_MODE_SIZE (outermode))
8689 18892688 : && SCALAR_INT_MODE_P (innermode)
8690 17732920 : && !SCALAR_INT_MODE_P (outermode)
8691 56792157 : && int_mode_for_size (GET_MODE_BITSIZE (outermode),
8692 88897 : 0).exists (&int_outermode))
8693 : {
8694 88897 : rtx tem = simplify_subreg (int_outermode, op, innermode, byte);
8695 88897 : if (tem)
8696 1984 : return lowpart_subreg (outermode, tem, int_outermode);
8697 : }
8698 :
8699 : /* If OP is a vector comparison and the subreg is not changing the
8700 : number of elements or the size of the elements, change the result
8701 : of the comparison to the new mode. */
8702 37719691 : if (COMPARISON_P (op)
8703 271848 : && VECTOR_MODE_P (outermode)
8704 198918 : && VECTOR_MODE_P (innermode)
8705 596730 : && known_eq (GET_MODE_NUNITS (outermode), GET_MODE_NUNITS (innermode))
8706 38090965 : && known_eq (GET_MODE_UNIT_SIZE (outermode),
8707 : GET_MODE_UNIT_SIZE (innermode)))
8708 123414 : return simplify_gen_relational (GET_CODE (op), outermode, innermode,
8709 123414 : XEXP (op, 0), XEXP (op, 1));
8710 :
8711 : /* Distribute non-paradoxical subregs through logic ops in cases where
8712 : one term disappears.
8713 :
8714 : (subreg:M1 (and:M2 X C1)) -> (subreg:M1 X)
8715 : (subreg:M1 (ior:M2 X C1)) -> (subreg:M1 C1)
8716 : (subreg:M1 (xor:M2 X C1)) -> (subreg:M1 (not:M2 X))
8717 :
8718 : if M2 is no smaller than M1 and (subreg:M1 C1) is all-ones.
8719 :
8720 : (subreg:M1 (and:M2 X C2)) -> (subreg:M1 C2)
8721 : (subreg:M1 (ior/xor:M2 X C2)) -> (subreg:M1 X)
8722 :
8723 : if M2 is no smaller than M1 and (subreg:M1 C2) is zero. */
8724 37596277 : if (known_ge (innersize, outersize)
8725 25058691 : && GET_MODE_CLASS (outermode) == GET_MODE_CLASS (innermode)
8726 23001578 : && (GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR)
8727 39125421 : && CONSTANT_P (XEXP (op, 1)))
8728 : {
8729 739454 : rtx op1_subreg = distribute_subreg (XEXP (op, 1));
8730 739454 : if (op1_subreg == CONSTM1_RTX (outermode))
8731 : {
8732 114919 : if (GET_CODE (op) == IOR)
8733 : return op1_subreg;
8734 114685 : rtx op0 = XEXP (op, 0);
8735 114685 : if (GET_CODE (op) == XOR)
8736 893 : op0 = simplify_gen_unary (NOT, innermode, op0, innermode);
8737 114685 : return simplify_gen_subreg (outermode, op0, innermode, byte);
8738 : }
8739 :
8740 624535 : if (op1_subreg == CONST0_RTX (outermode))
8741 12332 : return (GET_CODE (op) == AND
8742 12332 : ? op1_subreg
8743 7202 : : distribute_subreg (XEXP (op, 0)));
8744 : }
8745 :
8746 : return NULL_RTX;
8747 : }
8748 :
8749 : /* Make a SUBREG operation or equivalent if it folds. */
8750 :
8751 : rtx
8752 41912221 : simplify_context::simplify_gen_subreg (machine_mode outermode, rtx op,
8753 : machine_mode innermode,
8754 : poly_uint64 byte)
8755 : {
8756 41912221 : rtx newx;
8757 :
8758 41912221 : newx = simplify_subreg (outermode, op, innermode, byte);
8759 41912221 : if (newx)
8760 : return newx;
8761 :
8762 19456373 : if (GET_CODE (op) == SUBREG
8763 19456373 : || GET_CODE (op) == CONCAT
8764 19421711 : || CONST_SCALAR_INT_P (op)
8765 19421685 : || CONST_DOUBLE_AS_FLOAT_P (op)
8766 19421685 : || CONST_FIXED_P (op)
8767 19421685 : || GET_CODE (op) == CONST_VECTOR)
8768 : return NULL_RTX;
8769 :
8770 19421675 : if (validate_subreg (outermode, innermode, op, byte))
8771 19390411 : return gen_rtx_SUBREG (outermode, op, byte);
8772 :
8773 : return NULL_RTX;
8774 : }
8775 :
8776 : /* Generates a subreg to get the least significant part of EXPR (in mode
8777 : INNER_MODE) to OUTER_MODE. */
8778 :
8779 : rtx
8780 31103708 : simplify_context::lowpart_subreg (machine_mode outer_mode, rtx expr,
8781 : machine_mode inner_mode)
8782 : {
8783 31103708 : return simplify_gen_subreg (outer_mode, expr, inner_mode,
8784 31103708 : subreg_lowpart_offset (outer_mode, inner_mode));
8785 : }
8786 :
8787 : /* Generate RTX to select element at INDEX out of vector OP. */
8788 :
8789 : rtx
8790 641519 : simplify_context::simplify_gen_vec_select (rtx op, unsigned int index)
8791 : {
8792 641519 : gcc_assert (VECTOR_MODE_P (GET_MODE (op)));
8793 :
8794 641519 : scalar_mode imode = GET_MODE_INNER (GET_MODE (op));
8795 :
8796 1283038 : if (known_eq (index * GET_MODE_SIZE (imode),
8797 : subreg_lowpart_offset (imode, GET_MODE (op))))
8798 : {
8799 641369 : rtx res = lowpart_subreg (imode, op, GET_MODE (op));
8800 641369 : if (res)
8801 : return res;
8802 : }
8803 :
8804 472 : rtx tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, GEN_INT (index)));
8805 472 : return gen_rtx_VEC_SELECT (imode, op, tmp);
8806 : }
8807 :
8808 :
8809 : /* Simplify X, an rtx expression.
8810 :
8811 : Return the simplified expression or NULL if no simplifications
8812 : were possible.
8813 :
8814 : This is the preferred entry point into the simplification routines;
8815 : however, we still allow passes to call the more specific routines.
8816 :
8817 : Right now GCC has three (yes, three) major bodies of RTL simplification
8818 : code that need to be unified.
8819 :
8820 : 1. fold_rtx in cse.cc. This code uses various CSE specific
8821 : information to aid in RTL simplification.
8822 :
8823 : 2. simplify_rtx in combine.cc. Similar to fold_rtx, except that
8824 : it uses combine specific information to aid in RTL
8825 : simplification.
8826 :
8827 : 3. The routines in this file.
8828 :
8829 :
8830 : Long term we want to only have one body of simplification code; to
8831 : get to that state I recommend the following steps:
8832 :
8833 : 1. Pour over fold_rtx & simplify_rtx and move any simplifications
8834 : which are not pass dependent state into these routines.
8835 :
8836 : 2. As code is moved by #1, change fold_rtx & simplify_rtx to
8837 : use this routine whenever possible.
8838 :
8839 : 3. Allow for pass dependent state to be provided to these
8840 : routines and add simplifications based on the pass dependent
8841 : state. Remove code from cse.cc & combine.cc that becomes
8842 : redundant/dead.
8843 :
8844 : It will take time, but ultimately the compiler will be easier to
8845 : maintain and improve. It's totally silly that when we add a
8846 : simplification that it needs to be added to 4 places (3 for RTL
8847 : simplification and 1 for tree simplification. */
8848 :
8849 : rtx
8850 46435126 : simplify_rtx (const_rtx x)
8851 : {
8852 46435126 : const enum rtx_code code = GET_CODE (x);
8853 46435126 : const machine_mode mode = GET_MODE (x);
8854 :
8855 46435126 : switch (GET_RTX_CLASS (code))
8856 : {
8857 880668 : case RTX_UNARY:
8858 1761336 : return simplify_unary_operation (code, mode,
8859 880668 : XEXP (x, 0), GET_MODE (XEXP (x, 0)));
8860 26852505 : case RTX_COMM_ARITH:
8861 26852505 : if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
8862 540618 : return simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
8863 :
8864 : /* Fall through. */
8865 :
8866 32369370 : case RTX_BIN_ARITH:
8867 32369370 : return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
8868 :
8869 69713 : case RTX_TERNARY:
8870 69713 : case RTX_BITFIELD_OPS:
8871 69713 : return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
8872 69713 : XEXP (x, 0), XEXP (x, 1),
8873 69713 : XEXP (x, 2));
8874 :
8875 176886 : case RTX_COMPARE:
8876 176886 : case RTX_COMM_COMPARE:
8877 176886 : return simplify_relational_operation (code, mode,
8878 176886 : ((GET_MODE (XEXP (x, 0))
8879 : != VOIDmode)
8880 : ? GET_MODE (XEXP (x, 0))
8881 441 : : GET_MODE (XEXP (x, 1))),
8882 176886 : XEXP (x, 0),
8883 353772 : XEXP (x, 1));
8884 :
8885 230920 : case RTX_EXTRA:
8886 230920 : if (code == SUBREG)
8887 2443 : return simplify_subreg (mode, SUBREG_REG (x),
8888 2443 : GET_MODE (SUBREG_REG (x)),
8889 2443 : SUBREG_BYTE (x));
8890 : break;
8891 :
8892 6459706 : case RTX_OBJ:
8893 6459706 : if (code == LO_SUM)
8894 : {
8895 : /* Convert (lo_sum (high FOO) FOO) to FOO. */
8896 0 : if (GET_CODE (XEXP (x, 0)) == HIGH
8897 0 : && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
8898 0 : return XEXP (x, 1);
8899 : }
8900 : break;
8901 :
8902 : default:
8903 : break;
8904 : }
8905 : return NULL;
8906 : }
8907 :
8908 : #if CHECKING_P
8909 :
8910 : namespace selftest {
8911 :
8912 : /* Make a unique pseudo REG of mode MODE for use by selftests. */
8913 :
8914 : static rtx
8915 2672 : make_test_reg (machine_mode mode)
8916 : {
8917 2672 : static int test_reg_num = LAST_VIRTUAL_REGISTER + 1;
8918 :
8919 2672 : return gen_rtx_REG (mode, test_reg_num++);
8920 : }
8921 :
8922 : static void
8923 40 : test_scalar_int_ops (machine_mode mode)
8924 : {
8925 40 : rtx op0 = make_test_reg (mode);
8926 40 : rtx op1 = make_test_reg (mode);
8927 40 : rtx six = GEN_INT (6);
8928 :
8929 40 : rtx neg_op0 = simplify_gen_unary (NEG, mode, op0, mode);
8930 40 : rtx not_op0 = simplify_gen_unary (NOT, mode, op0, mode);
8931 40 : rtx bswap_op0 = simplify_gen_unary (BSWAP, mode, op0, mode);
8932 :
8933 40 : rtx and_op0_op1 = simplify_gen_binary (AND, mode, op0, op1);
8934 40 : rtx ior_op0_op1 = simplify_gen_binary (IOR, mode, op0, op1);
8935 40 : rtx xor_op0_op1 = simplify_gen_binary (XOR, mode, op0, op1);
8936 :
8937 40 : rtx and_op0_6 = simplify_gen_binary (AND, mode, op0, six);
8938 40 : rtx and_op1_6 = simplify_gen_binary (AND, mode, op1, six);
8939 :
8940 : /* Test some binary identities. */
8941 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, op0, const0_rtx));
8942 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, const0_rtx, op0));
8943 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MINUS, mode, op0, const0_rtx));
8944 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, op0, const1_rtx));
8945 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, const1_rtx, op0));
8946 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (DIV, mode, op0, const1_rtx));
8947 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, constm1_rtx));
8948 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, constm1_rtx, op0));
8949 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, const0_rtx));
8950 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, const0_rtx, op0));
8951 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, op0, const0_rtx));
8952 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, const0_rtx, op0));
8953 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFT, mode, op0, const0_rtx));
8954 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATE, mode, op0, const0_rtx));
8955 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFTRT, mode, op0, const0_rtx));
8956 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (LSHIFTRT, mode, op0, const0_rtx));
8957 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATERT, mode, op0, const0_rtx));
8958 :
8959 : /* Test some self-inverse operations. */
8960 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (NEG, mode, neg_op0, mode));
8961 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (NOT, mode, not_op0, mode));
8962 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (BSWAP, mode, bswap_op0, mode));
8963 :
8964 : /* Test some reflexive operations. */
8965 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, op0));
8966 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, op0));
8967 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (SMIN, mode, op0, op0));
8968 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (SMAX, mode, op0, op0));
8969 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (UMIN, mode, op0, op0));
8970 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (UMAX, mode, op0, op0));
8971 :
8972 40 : ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (MINUS, mode, op0, op0));
8973 40 : ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (XOR, mode, op0, op0));
8974 :
8975 : /* Test simplify_distributive_operation. */
8976 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, xor_op0_op1, six),
8977 : simplify_gen_binary (XOR, mode, and_op0_6, and_op1_6));
8978 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, ior_op0_op1, six),
8979 : simplify_gen_binary (IOR, mode, and_op0_6, and_op1_6));
8980 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, and_op0_op1, six),
8981 : simplify_gen_binary (AND, mode, and_op0_6, and_op1_6));
8982 :
8983 : /* Test useless extensions are eliminated. */
8984 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (TRUNCATE, mode, op0, mode));
8985 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (ZERO_EXTEND, mode, op0, mode));
8986 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (SIGN_EXTEND, mode, op0, mode));
8987 40 : ASSERT_RTX_EQ (op0, lowpart_subreg (mode, op0, mode));
8988 40 : }
8989 :
8990 : /* Verify some simplifications of integer extension/truncation.
8991 : Machine mode BMODE is the guaranteed wider than SMODE. */
8992 :
8993 : static void
8994 24 : test_scalar_int_ext_ops (machine_mode bmode, machine_mode smode)
8995 : {
8996 24 : rtx sreg = make_test_reg (smode);
8997 :
8998 : /* Check truncation of extension. */
8999 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9000 : simplify_gen_unary (ZERO_EXTEND, bmode,
9001 : sreg, smode),
9002 : bmode),
9003 : sreg);
9004 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9005 : simplify_gen_unary (SIGN_EXTEND, bmode,
9006 : sreg, smode),
9007 : bmode),
9008 : sreg);
9009 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9010 : lowpart_subreg (bmode, sreg, smode),
9011 : bmode),
9012 : sreg);
9013 :
9014 : /* Test extensions, followed by logic ops, followed by truncations. */
9015 24 : rtx bsubreg = lowpart_subreg (bmode, sreg, smode);
9016 24 : rtx smask = gen_int_mode (GET_MODE_MASK (smode), bmode);
9017 24 : rtx inv_smask = gen_int_mode (~GET_MODE_MASK (smode), bmode);
9018 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9019 : simplify_gen_binary (AND, bmode,
9020 : bsubreg, smask),
9021 : bmode),
9022 : sreg);
9023 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9024 : simplify_gen_binary (AND, bmode,
9025 : bsubreg, inv_smask),
9026 : bmode),
9027 : const0_rtx);
9028 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9029 : simplify_gen_binary (IOR, bmode,
9030 : bsubreg, smask),
9031 : bmode),
9032 : constm1_rtx);
9033 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9034 : simplify_gen_binary (IOR, bmode,
9035 : bsubreg, inv_smask),
9036 : bmode),
9037 : sreg);
9038 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9039 : simplify_gen_binary (XOR, bmode,
9040 : bsubreg, smask),
9041 : bmode),
9042 : lowpart_subreg (smode,
9043 : gen_rtx_NOT (bmode, bsubreg),
9044 : bmode));
9045 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9046 : simplify_gen_binary (XOR, bmode,
9047 : bsubreg, inv_smask),
9048 : bmode),
9049 : sreg);
9050 :
9051 24 : if (known_le (GET_MODE_PRECISION (bmode), BITS_PER_WORD))
9052 : {
9053 24 : rtx breg1 = make_test_reg (bmode);
9054 24 : rtx breg2 = make_test_reg (bmode);
9055 24 : rtx ssubreg1 = lowpart_subreg (smode, breg1, bmode);
9056 24 : rtx ssubreg2 = lowpart_subreg (smode, breg2, bmode);
9057 24 : rtx not_1 = simplify_gen_unary (NOT, smode, ssubreg1, smode);
9058 24 : rtx and_12 = simplify_gen_binary (AND, smode, ssubreg1, ssubreg2);
9059 24 : rtx ior_12 = simplify_gen_binary (IOR, smode, ssubreg1, ssubreg2);
9060 24 : rtx xor_12 = simplify_gen_binary (XOR, smode, ssubreg1, ssubreg2);
9061 24 : rtx and_n12 = simplify_gen_binary (AND, smode, not_1, ssubreg2);
9062 24 : rtx ior_n12 = simplify_gen_binary (IOR, smode, not_1, ssubreg2);
9063 24 : rtx xor_12_c = simplify_gen_binary (XOR, smode, xor_12, const1_rtx);
9064 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, not_1, smode),
9065 : gen_rtx_NOT (bmode, breg1));
9066 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, and_12, smode),
9067 : gen_rtx_AND (bmode, breg1, breg2));
9068 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, ior_12, smode),
9069 : gen_rtx_IOR (bmode, breg1, breg2));
9070 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, xor_12, smode),
9071 : gen_rtx_XOR (bmode, breg1, breg2));
9072 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, and_n12, smode),
9073 : gen_rtx_AND (bmode, gen_rtx_NOT (bmode, breg1), breg2));
9074 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, ior_n12, smode),
9075 : gen_rtx_IOR (bmode, gen_rtx_NOT (bmode, breg1), breg2));
9076 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, xor_12_c, smode),
9077 : gen_rtx_XOR (bmode,
9078 : gen_rtx_XOR (bmode, breg1, breg2),
9079 : const1_rtx));
9080 : }
9081 24 : }
9082 :
9083 : /* Verify more simplifications of integer extension/truncation.
9084 : BMODE is wider than MMODE which is wider than SMODE. */
9085 :
9086 : static void
9087 16 : test_scalar_int_ext_ops2 (machine_mode bmode, machine_mode mmode,
9088 : machine_mode smode)
9089 : {
9090 16 : rtx breg = make_test_reg (bmode);
9091 16 : rtx mreg = make_test_reg (mmode);
9092 16 : rtx sreg = make_test_reg (smode);
9093 :
9094 : /* Check truncate of truncate. */
9095 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9096 : simplify_gen_unary (TRUNCATE, mmode,
9097 : breg, bmode),
9098 : mmode),
9099 : simplify_gen_unary (TRUNCATE, smode, breg, bmode));
9100 :
9101 : /* Check extension of extension. */
9102 16 : ASSERT_RTX_EQ (simplify_gen_unary (ZERO_EXTEND, bmode,
9103 : simplify_gen_unary (ZERO_EXTEND, mmode,
9104 : sreg, smode),
9105 : mmode),
9106 : simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
9107 16 : ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
9108 : simplify_gen_unary (SIGN_EXTEND, mmode,
9109 : sreg, smode),
9110 : mmode),
9111 : simplify_gen_unary (SIGN_EXTEND, bmode, sreg, smode));
9112 16 : ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
9113 : simplify_gen_unary (ZERO_EXTEND, mmode,
9114 : sreg, smode),
9115 : mmode),
9116 : simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
9117 :
9118 : /* Check truncation of extension. */
9119 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9120 : simplify_gen_unary (ZERO_EXTEND, bmode,
9121 : mreg, mmode),
9122 : bmode),
9123 : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
9124 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9125 : simplify_gen_unary (SIGN_EXTEND, bmode,
9126 : mreg, mmode),
9127 : bmode),
9128 : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
9129 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9130 : lowpart_subreg (bmode, mreg, mmode),
9131 : bmode),
9132 : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
9133 16 : }
9134 :
9135 : /* Test comparisons of comparisons, with the inner comparisons being
9136 : between values of mode MODE2 and producing results of mode MODE1,
9137 : and with the outer comparisons producing results of mode MODE0. */
9138 :
9139 : static void
9140 4 : test_comparisons (machine_mode mode0, machine_mode mode1, machine_mode mode2)
9141 : {
9142 4 : rtx reg0 = make_test_reg (mode2);
9143 4 : rtx reg1 = make_test_reg (mode2);
9144 :
9145 4 : static const rtx_code codes[] = {
9146 : EQ, NE, LT, LTU, LE, LEU, GE, GEU, GT, GTU
9147 : };
9148 4 : constexpr auto num_codes = ARRAY_SIZE (codes);
9149 4 : rtx cmps[num_codes];
9150 4 : rtx vals[] = { constm1_rtx, const0_rtx, const1_rtx };
9151 :
9152 44 : for (unsigned int i = 0; i < num_codes; ++i)
9153 40 : cmps[i] = gen_rtx_fmt_ee (codes[i], mode1, reg0, reg1);
9154 :
9155 44 : for (auto code : codes)
9156 440 : for (unsigned int i0 = 0; i0 < num_codes; ++i0)
9157 4400 : for (unsigned int i1 = 0; i1 < num_codes; ++i1)
9158 : {
9159 4000 : rtx cmp_res = simplify_relational_operation (code, mode0, mode1,
9160 : cmps[i0], cmps[i1]);
9161 4000 : if (i0 >= 2 && i1 >= 2 && (i0 ^ i1) & 1)
9162 1280 : ASSERT_TRUE (cmp_res == NULL_RTX);
9163 : else
9164 : {
9165 2720 : ASSERT_TRUE (cmp_res != NULL_RTX
9166 : && (CONSTANT_P (cmp_res)
9167 : || (COMPARISON_P (cmp_res)
9168 : && GET_MODE (cmp_res) == mode0
9169 : && REG_P (XEXP (cmp_res, 0))
9170 : && REG_P (XEXP (cmp_res, 1)))));
9171 10880 : for (rtx reg0_val : vals)
9172 32640 : for (rtx reg1_val : vals)
9173 : {
9174 24480 : rtx val0 = simplify_const_relational_operation
9175 24480 : (codes[i0], mode1, reg0_val, reg1_val);
9176 24480 : rtx val1 = simplify_const_relational_operation
9177 24480 : (codes[i1], mode1, reg0_val, reg1_val);
9178 24480 : rtx val = simplify_const_relational_operation
9179 24480 : (code, mode0, val0, val1);
9180 24480 : rtx folded = cmp_res;
9181 24480 : if (COMPARISON_P (cmp_res))
9182 16704 : folded = simplify_const_relational_operation
9183 16704 : (GET_CODE (cmp_res), mode0,
9184 16704 : XEXP (cmp_res, 0) == reg0 ? reg0_val : reg1_val,
9185 16704 : XEXP (cmp_res, 1) == reg0 ? reg0_val : reg1_val);
9186 24480 : ASSERT_RTX_EQ (val, folded);
9187 : }
9188 : }
9189 : }
9190 4 : }
9191 :
9192 :
9193 : /* Verify some simplifications involving scalar expressions. */
9194 :
9195 : static void
9196 4 : test_scalar_ops ()
9197 : {
9198 500 : for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
9199 : {
9200 496 : machine_mode mode = (machine_mode) i;
9201 496 : if (SCALAR_INT_MODE_P (mode) && mode != BImode)
9202 40 : test_scalar_int_ops (mode);
9203 : }
9204 :
9205 4 : test_scalar_int_ext_ops (HImode, QImode);
9206 4 : test_scalar_int_ext_ops (SImode, QImode);
9207 4 : test_scalar_int_ext_ops (SImode, HImode);
9208 4 : test_scalar_int_ext_ops (DImode, QImode);
9209 4 : test_scalar_int_ext_ops (DImode, HImode);
9210 4 : test_scalar_int_ext_ops (DImode, SImode);
9211 :
9212 4 : test_scalar_int_ext_ops2 (SImode, HImode, QImode);
9213 4 : test_scalar_int_ext_ops2 (DImode, HImode, QImode);
9214 4 : test_scalar_int_ext_ops2 (DImode, SImode, QImode);
9215 4 : test_scalar_int_ext_ops2 (DImode, SImode, HImode);
9216 :
9217 4 : test_comparisons (QImode, HImode, SImode);
9218 4 : }
9219 :
9220 : /* Test vector simplifications involving VEC_DUPLICATE in which the
9221 : operands and result have vector mode MODE. SCALAR_REG is a pseudo
9222 : register that holds one element of MODE. */
9223 :
9224 : static void
9225 224 : test_vector_ops_duplicate (machine_mode mode, rtx scalar_reg)
9226 : {
9227 224 : scalar_mode inner_mode = GET_MODE_INNER (mode);
9228 224 : rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
9229 448 : poly_uint64 nunits = GET_MODE_NUNITS (mode);
9230 224 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
9231 : {
9232 : /* Test some simple unary cases with VEC_DUPLICATE arguments. */
9233 124 : rtx not_scalar_reg = gen_rtx_NOT (inner_mode, scalar_reg);
9234 124 : rtx duplicate_not = gen_rtx_VEC_DUPLICATE (mode, not_scalar_reg);
9235 124 : ASSERT_RTX_EQ (duplicate,
9236 : simplify_unary_operation (NOT, mode,
9237 : duplicate_not, mode));
9238 :
9239 124 : rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
9240 124 : rtx duplicate_neg = gen_rtx_VEC_DUPLICATE (mode, neg_scalar_reg);
9241 124 : ASSERT_RTX_EQ (duplicate,
9242 : simplify_unary_operation (NEG, mode,
9243 : duplicate_neg, mode));
9244 :
9245 : /* Test some simple binary cases with VEC_DUPLICATE arguments. */
9246 124 : ASSERT_RTX_EQ (duplicate,
9247 : simplify_binary_operation (PLUS, mode, duplicate,
9248 : CONST0_RTX (mode)));
9249 :
9250 124 : ASSERT_RTX_EQ (duplicate,
9251 : simplify_binary_operation (MINUS, mode, duplicate,
9252 : CONST0_RTX (mode)));
9253 :
9254 124 : ASSERT_RTX_PTR_EQ (CONST0_RTX (mode),
9255 : simplify_binary_operation (MINUS, mode, duplicate,
9256 : duplicate));
9257 : }
9258 :
9259 : /* Test a scalar VEC_SELECT of a VEC_DUPLICATE. */
9260 224 : rtx zero_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const0_rtx));
9261 224 : ASSERT_RTX_PTR_EQ (scalar_reg,
9262 : simplify_binary_operation (VEC_SELECT, inner_mode,
9263 : duplicate, zero_par));
9264 :
9265 224 : unsigned HOST_WIDE_INT const_nunits;
9266 224 : if (nunits.is_constant (&const_nunits))
9267 : {
9268 : /* And again with the final element. */
9269 224 : rtx last_index = gen_int_mode (const_nunits - 1, word_mode);
9270 224 : rtx last_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, last_index));
9271 224 : ASSERT_RTX_PTR_EQ (scalar_reg,
9272 : simplify_binary_operation (VEC_SELECT, inner_mode,
9273 : duplicate, last_par));
9274 :
9275 : /* Test a scalar subreg of a VEC_MERGE of a VEC_DUPLICATE. */
9276 : /* Skip this test for vectors of booleans, because offset is in bytes,
9277 : while vec_merge indices are in elements (usually bits). */
9278 224 : if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
9279 : {
9280 224 : rtx vector_reg = make_test_reg (mode);
9281 3508 : for (unsigned HOST_WIDE_INT i = 0; i < const_nunits; i++)
9282 : {
9283 3288 : if (i >= HOST_BITS_PER_WIDE_INT)
9284 : break;
9285 3284 : rtx mask = GEN_INT ((HOST_WIDE_INT_1U << i) | (i + 1));
9286 3284 : rtx vm = gen_rtx_VEC_MERGE (mode, duplicate, vector_reg, mask);
9287 6568 : poly_uint64 offset = i * GET_MODE_SIZE (inner_mode);
9288 :
9289 3284 : ASSERT_RTX_EQ (scalar_reg,
9290 : simplify_gen_subreg (inner_mode, vm,
9291 : mode, offset));
9292 : }
9293 : }
9294 : }
9295 :
9296 : /* Test a scalar subreg of a VEC_DUPLICATE. */
9297 224 : poly_uint64 offset = subreg_lowpart_offset (inner_mode, mode);
9298 224 : ASSERT_RTX_EQ (scalar_reg,
9299 : simplify_gen_subreg (inner_mode, duplicate,
9300 : mode, offset));
9301 :
9302 224 : machine_mode narrower_mode;
9303 224 : if (maybe_ne (nunits, 2U)
9304 184 : && multiple_p (nunits, 2)
9305 396 : && mode_for_vector (inner_mode, 2).exists (&narrower_mode)
9306 396 : && VECTOR_MODE_P (narrower_mode))
9307 : {
9308 : /* Test VEC_DUPLICATE of a vector. */
9309 172 : rtx_vector_builder nbuilder (narrower_mode, 2, 1);
9310 172 : nbuilder.quick_push (const0_rtx);
9311 172 : nbuilder.quick_push (const1_rtx);
9312 172 : rtx_vector_builder builder (mode, 2, 1);
9313 172 : builder.quick_push (const0_rtx);
9314 172 : builder.quick_push (const1_rtx);
9315 172 : ASSERT_RTX_EQ (builder.build (),
9316 : simplify_unary_operation (VEC_DUPLICATE, mode,
9317 : nbuilder.build (),
9318 : narrower_mode));
9319 :
9320 : /* Test VEC_SELECT of a vector. */
9321 172 : rtx vec_par
9322 172 : = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, const1_rtx, const0_rtx));
9323 172 : rtx narrower_duplicate
9324 172 : = gen_rtx_VEC_DUPLICATE (narrower_mode, scalar_reg);
9325 172 : ASSERT_RTX_EQ (narrower_duplicate,
9326 : simplify_binary_operation (VEC_SELECT, narrower_mode,
9327 : duplicate, vec_par));
9328 :
9329 : /* Test a vector subreg of a VEC_DUPLICATE. */
9330 172 : poly_uint64 offset = subreg_lowpart_offset (narrower_mode, mode);
9331 172 : ASSERT_RTX_EQ (narrower_duplicate,
9332 : simplify_gen_subreg (narrower_mode, duplicate,
9333 : mode, offset));
9334 172 : }
9335 224 : }
9336 :
9337 : /* Test vector simplifications involving VEC_SERIES in which the
9338 : operands and result have vector mode MODE. SCALAR_REG is a pseudo
9339 : register that holds one element of MODE. */
9340 :
9341 : static void
9342 92 : test_vector_ops_series (machine_mode mode, rtx scalar_reg)
9343 : {
9344 : /* Test unary cases with VEC_SERIES arguments. */
9345 92 : scalar_mode inner_mode = GET_MODE_INNER (mode);
9346 92 : rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
9347 92 : rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
9348 92 : rtx series_0_r = gen_rtx_VEC_SERIES (mode, const0_rtx, scalar_reg);
9349 92 : rtx series_0_nr = gen_rtx_VEC_SERIES (mode, const0_rtx, neg_scalar_reg);
9350 92 : rtx series_nr_1 = gen_rtx_VEC_SERIES (mode, neg_scalar_reg, const1_rtx);
9351 92 : rtx series_r_m1 = gen_rtx_VEC_SERIES (mode, scalar_reg, constm1_rtx);
9352 92 : rtx series_r_r = gen_rtx_VEC_SERIES (mode, scalar_reg, scalar_reg);
9353 92 : rtx series_nr_nr = gen_rtx_VEC_SERIES (mode, neg_scalar_reg,
9354 : neg_scalar_reg);
9355 92 : ASSERT_RTX_EQ (series_0_r,
9356 : simplify_unary_operation (NEG, mode, series_0_nr, mode));
9357 92 : ASSERT_RTX_EQ (series_r_m1,
9358 : simplify_unary_operation (NEG, mode, series_nr_1, mode));
9359 92 : ASSERT_RTX_EQ (series_r_r,
9360 : simplify_unary_operation (NEG, mode, series_nr_nr, mode));
9361 :
9362 : /* Test that a VEC_SERIES with a zero step is simplified away. */
9363 92 : ASSERT_RTX_EQ (duplicate,
9364 : simplify_binary_operation (VEC_SERIES, mode,
9365 : scalar_reg, const0_rtx));
9366 :
9367 : /* Test PLUS and MINUS with VEC_SERIES. */
9368 92 : rtx series_0_1 = gen_const_vec_series (mode, const0_rtx, const1_rtx);
9369 92 : rtx series_0_m1 = gen_const_vec_series (mode, const0_rtx, constm1_rtx);
9370 92 : rtx series_r_1 = gen_rtx_VEC_SERIES (mode, scalar_reg, const1_rtx);
9371 92 : ASSERT_RTX_EQ (series_r_r,
9372 : simplify_binary_operation (PLUS, mode, series_0_r,
9373 : duplicate));
9374 92 : ASSERT_RTX_EQ (series_r_1,
9375 : simplify_binary_operation (PLUS, mode, duplicate,
9376 : series_0_1));
9377 92 : ASSERT_RTX_EQ (series_r_m1,
9378 : simplify_binary_operation (PLUS, mode, duplicate,
9379 : series_0_m1));
9380 92 : ASSERT_RTX_EQ (series_0_r,
9381 : simplify_binary_operation (MINUS, mode, series_r_r,
9382 : duplicate));
9383 92 : ASSERT_RTX_EQ (series_r_m1,
9384 : simplify_binary_operation (MINUS, mode, duplicate,
9385 : series_0_1));
9386 92 : ASSERT_RTX_EQ (series_r_1,
9387 : simplify_binary_operation (MINUS, mode, duplicate,
9388 : series_0_m1));
9389 92 : ASSERT_RTX_EQ (series_0_m1,
9390 : simplify_binary_operation (VEC_SERIES, mode, const0_rtx,
9391 : constm1_rtx));
9392 :
9393 : /* Test NEG on constant vector series. */
9394 92 : ASSERT_RTX_EQ (series_0_m1,
9395 : simplify_unary_operation (NEG, mode, series_0_1, mode));
9396 92 : ASSERT_RTX_EQ (series_0_1,
9397 : simplify_unary_operation (NEG, mode, series_0_m1, mode));
9398 :
9399 : /* Test PLUS and MINUS on constant vector series. */
9400 92 : rtx scalar2 = gen_int_mode (2, inner_mode);
9401 92 : rtx scalar3 = gen_int_mode (3, inner_mode);
9402 92 : rtx series_1_1 = gen_const_vec_series (mode, const1_rtx, const1_rtx);
9403 92 : rtx series_0_2 = gen_const_vec_series (mode, const0_rtx, scalar2);
9404 92 : rtx series_1_3 = gen_const_vec_series (mode, const1_rtx, scalar3);
9405 92 : ASSERT_RTX_EQ (series_1_1,
9406 : simplify_binary_operation (PLUS, mode, series_0_1,
9407 : CONST1_RTX (mode)));
9408 92 : ASSERT_RTX_EQ (series_0_m1,
9409 : simplify_binary_operation (PLUS, mode, CONST0_RTX (mode),
9410 : series_0_m1));
9411 92 : ASSERT_RTX_EQ (series_1_3,
9412 : simplify_binary_operation (PLUS, mode, series_1_1,
9413 : series_0_2));
9414 92 : ASSERT_RTX_EQ (series_0_1,
9415 : simplify_binary_operation (MINUS, mode, series_1_1,
9416 : CONST1_RTX (mode)));
9417 92 : ASSERT_RTX_EQ (series_1_1,
9418 : simplify_binary_operation (MINUS, mode, CONST1_RTX (mode),
9419 : series_0_m1));
9420 92 : ASSERT_RTX_EQ (series_1_1,
9421 : simplify_binary_operation (MINUS, mode, series_1_3,
9422 : series_0_2));
9423 :
9424 : /* Test MULT between constant vectors. */
9425 92 : rtx vec2 = gen_const_vec_duplicate (mode, scalar2);
9426 92 : rtx vec3 = gen_const_vec_duplicate (mode, scalar3);
9427 92 : rtx scalar9 = gen_int_mode (9, inner_mode);
9428 92 : rtx series_3_9 = gen_const_vec_series (mode, scalar3, scalar9);
9429 92 : ASSERT_RTX_EQ (series_0_2,
9430 : simplify_binary_operation (MULT, mode, series_0_1, vec2));
9431 92 : ASSERT_RTX_EQ (series_3_9,
9432 : simplify_binary_operation (MULT, mode, vec3, series_1_3));
9433 92 : if (!GET_MODE_NUNITS (mode).is_constant ())
9434 : ASSERT_FALSE (simplify_binary_operation (MULT, mode, series_0_1,
9435 : series_0_1));
9436 :
9437 : /* Test ASHIFT between constant vectors. */
9438 92 : ASSERT_RTX_EQ (series_0_2,
9439 : simplify_binary_operation (ASHIFT, mode, series_0_1,
9440 : CONST1_RTX (mode)));
9441 92 : if (!GET_MODE_NUNITS (mode).is_constant ())
9442 : ASSERT_FALSE (simplify_binary_operation (ASHIFT, mode, CONST1_RTX (mode),
9443 : series_0_1));
9444 92 : }
9445 :
9446 : static rtx
9447 3136 : simplify_merge_mask (rtx x, rtx mask, int op)
9448 : {
9449 0 : return simplify_context ().simplify_merge_mask (x, mask, op);
9450 : }
9451 :
9452 : /* Verify simplify_merge_mask works correctly. */
9453 :
9454 : static void
9455 224 : test_vec_merge (machine_mode mode)
9456 : {
9457 224 : rtx op0 = make_test_reg (mode);
9458 224 : rtx op1 = make_test_reg (mode);
9459 224 : rtx op2 = make_test_reg (mode);
9460 224 : rtx op3 = make_test_reg (mode);
9461 224 : rtx op4 = make_test_reg (mode);
9462 224 : rtx op5 = make_test_reg (mode);
9463 224 : rtx mask1 = make_test_reg (SImode);
9464 224 : rtx mask2 = make_test_reg (SImode);
9465 224 : rtx vm1 = gen_rtx_VEC_MERGE (mode, op0, op1, mask1);
9466 224 : rtx vm2 = gen_rtx_VEC_MERGE (mode, op2, op3, mask1);
9467 224 : rtx vm3 = gen_rtx_VEC_MERGE (mode, op4, op5, mask1);
9468 :
9469 : /* Simple vec_merge. */
9470 224 : ASSERT_EQ (op0, simplify_merge_mask (vm1, mask1, 0));
9471 224 : ASSERT_EQ (op1, simplify_merge_mask (vm1, mask1, 1));
9472 224 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 0));
9473 224 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 1));
9474 :
9475 : /* Nested vec_merge.
9476 : It's tempting to make this simplify right down to opN, but we don't
9477 : because all the simplify_* functions assume that the operands have
9478 : already been simplified. */
9479 224 : rtx nvm = gen_rtx_VEC_MERGE (mode, vm1, vm2, mask1);
9480 224 : ASSERT_EQ (vm1, simplify_merge_mask (nvm, mask1, 0));
9481 224 : ASSERT_EQ (vm2, simplify_merge_mask (nvm, mask1, 1));
9482 :
9483 : /* Intermediate unary op. */
9484 224 : rtx unop = gen_rtx_NOT (mode, vm1);
9485 224 : ASSERT_RTX_EQ (gen_rtx_NOT (mode, op0),
9486 : simplify_merge_mask (unop, mask1, 0));
9487 224 : ASSERT_RTX_EQ (gen_rtx_NOT (mode, op1),
9488 : simplify_merge_mask (unop, mask1, 1));
9489 :
9490 : /* Intermediate binary op. */
9491 224 : rtx binop = gen_rtx_PLUS (mode, vm1, vm2);
9492 224 : ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op0, op2),
9493 : simplify_merge_mask (binop, mask1, 0));
9494 224 : ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op1, op3),
9495 : simplify_merge_mask (binop, mask1, 1));
9496 :
9497 : /* Intermediate ternary op. */
9498 224 : rtx tenop = gen_rtx_FMA (mode, vm1, vm2, vm3);
9499 224 : ASSERT_RTX_EQ (gen_rtx_FMA (mode, op0, op2, op4),
9500 : simplify_merge_mask (tenop, mask1, 0));
9501 224 : ASSERT_RTX_EQ (gen_rtx_FMA (mode, op1, op3, op5),
9502 : simplify_merge_mask (tenop, mask1, 1));
9503 :
9504 : /* Side effects. */
9505 224 : rtx badop0 = gen_rtx_PRE_INC (mode, op0);
9506 224 : rtx badvm = gen_rtx_VEC_MERGE (mode, badop0, op1, mask1);
9507 224 : ASSERT_EQ (badop0, simplify_merge_mask (badvm, mask1, 0));
9508 224 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (badvm, mask1, 1));
9509 :
9510 : /* Called indirectly. */
9511 224 : ASSERT_RTX_EQ (gen_rtx_VEC_MERGE (mode, op0, op3, mask1),
9512 : simplify_rtx (nvm));
9513 224 : }
9514 :
9515 : /* Test that vector rotate formation works at RTL level. Try various
9516 : combinations of (REG << C) [|,^,+] (REG >> (<bitwidth> - C)). */
9517 :
9518 : static void
9519 92 : test_vector_rotate (rtx reg)
9520 : {
9521 92 : machine_mode mode = GET_MODE (reg);
9522 92 : unsigned bitwidth = GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT;
9523 92 : rtx plus_rtx = gen_rtx_PLUS (mode, reg, reg);
9524 92 : rtx lshftrt_amnt = GEN_INT (bitwidth - 1);
9525 92 : lshftrt_amnt = gen_const_vec_duplicate (mode, lshftrt_amnt);
9526 92 : rtx lshiftrt_rtx = gen_rtx_LSHIFTRT (mode, reg, lshftrt_amnt);
9527 92 : rtx rotate_rtx = gen_rtx_ROTATE (mode, reg, CONST1_RTX (mode));
9528 : /* Test explicitly the case where ASHIFT (x, 1) is a PLUS (x, x). */
9529 92 : ASSERT_RTX_EQ (rotate_rtx,
9530 : simplify_rtx (gen_rtx_IOR (mode, plus_rtx, lshiftrt_rtx)));
9531 92 : ASSERT_RTX_EQ (rotate_rtx,
9532 : simplify_rtx (gen_rtx_XOR (mode, plus_rtx, lshiftrt_rtx)));
9533 92 : ASSERT_RTX_EQ (rotate_rtx,
9534 : simplify_rtx (gen_rtx_PLUS (mode, plus_rtx, lshiftrt_rtx)));
9535 :
9536 : /* Don't go through every possible rotate amount to save execution time.
9537 : Multiple of BITS_PER_UNIT amounts could conceivably be simplified to
9538 : other bswap operations sometimes. Go through just the odd amounts. */
9539 1380 : for (unsigned i = 3; i < bitwidth - 2; i += 2)
9540 : {
9541 1288 : rtx rot_amnt = gen_const_vec_duplicate (mode, GEN_INT (i));
9542 1288 : rtx ashift_rtx = gen_rtx_ASHIFT (mode, reg, rot_amnt);
9543 1288 : lshftrt_amnt = gen_const_vec_duplicate (mode, GEN_INT (bitwidth - i));
9544 1288 : lshiftrt_rtx = gen_rtx_LSHIFTRT (mode, reg, lshftrt_amnt);
9545 1288 : rotate_rtx = gen_rtx_ROTATE (mode, reg, rot_amnt);
9546 1288 : ASSERT_RTX_EQ (rotate_rtx,
9547 : simplify_rtx (gen_rtx_IOR (mode, ashift_rtx, lshiftrt_rtx)));
9548 1288 : ASSERT_RTX_EQ (rotate_rtx,
9549 : simplify_rtx (gen_rtx_XOR (mode, ashift_rtx, lshiftrt_rtx)));
9550 1288 : ASSERT_RTX_EQ (rotate_rtx,
9551 : simplify_rtx (gen_rtx_PLUS (mode, ashift_rtx, lshiftrt_rtx)));
9552 : }
9553 92 : }
9554 :
9555 : /* Test subregs of integer vector constant X, trying elements in
9556 : the range [ELT_BIAS, ELT_BIAS + constant_lower_bound (NELTS)),
9557 : where NELTS is the number of elements in X. Subregs involving
9558 : elements [ELT_BIAS, ELT_BIAS + FIRST_VALID) are expected to fail. */
9559 :
9560 : static void
9561 276 : test_vector_subregs_modes (rtx x, poly_uint64 elt_bias = 0,
9562 : unsigned int first_valid = 0)
9563 : {
9564 276 : machine_mode inner_mode = GET_MODE (x);
9565 276 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9566 :
9567 34500 : for (unsigned int modei = 0; modei < NUM_MACHINE_MODES; ++modei)
9568 : {
9569 34224 : machine_mode outer_mode = (machine_mode) modei;
9570 34224 : if (!VECTOR_MODE_P (outer_mode))
9571 18768 : continue;
9572 :
9573 15456 : unsigned int outer_nunits;
9574 15456 : if (GET_MODE_INNER (outer_mode) == int_mode
9575 1932 : && GET_MODE_NUNITS (outer_mode).is_constant (&outer_nunits)
9576 20412 : && multiple_p (GET_MODE_NUNITS (inner_mode), outer_nunits))
9577 : {
9578 : /* Test subregs in which the outer mode is a smaller,
9579 : constant-sized vector of the same element type. */
9580 1092 : unsigned int limit
9581 1092 : = constant_lower_bound (GET_MODE_NUNITS (inner_mode));
9582 8028 : for (unsigned int elt = 0; elt < limit; elt += outer_nunits)
9583 : {
9584 6936 : rtx expected = NULL_RTX;
9585 6936 : if (elt >= first_valid)
9586 : {
9587 6936 : rtx_vector_builder builder (outer_mode, outer_nunits, 1);
9588 39768 : for (unsigned int i = 0; i < outer_nunits; ++i)
9589 32832 : builder.quick_push (CONST_VECTOR_ELT (x, elt + i));
9590 6936 : expected = builder.build ();
9591 6936 : }
9592 13872 : poly_uint64 byte = (elt_bias + elt) * GET_MODE_SIZE (int_mode);
9593 6936 : ASSERT_RTX_EQ (expected,
9594 : simplify_subreg (outer_mode, x,
9595 : inner_mode, byte));
9596 : }
9597 : }
9598 28728 : else if (known_eq (GET_MODE_SIZE (outer_mode),
9599 : GET_MODE_SIZE (inner_mode))
9600 2040 : && known_eq (elt_bias, 0U)
9601 2040 : && (GET_MODE_CLASS (outer_mode) != MODE_VECTOR_BOOL
9602 0 : || known_eq (GET_MODE_BITSIZE (outer_mode),
9603 : GET_MODE_NUNITS (outer_mode)))
9604 2040 : && (!FLOAT_MODE_P (outer_mode)
9605 15876 : || (FLOAT_MODE_FORMAT (outer_mode)->ieee_bits
9606 1104 : == GET_MODE_UNIT_PRECISION (outer_mode)))
9607 14364 : && (GET_MODE_SIZE (inner_mode).is_constant ()
9608 : || !CONST_VECTOR_STEPPED_P (x)))
9609 : {
9610 : /* Try converting to OUTER_MODE and back. */
9611 1800 : rtx outer_x = simplify_subreg (outer_mode, x, inner_mode, 0);
9612 1800 : ASSERT_TRUE (outer_x != NULL_RTX);
9613 1800 : ASSERT_RTX_EQ (x, simplify_subreg (inner_mode, outer_x,
9614 : outer_mode, 0));
9615 : }
9616 : }
9617 :
9618 276 : if (BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
9619 : {
9620 : /* Test each byte in the element range. */
9621 276 : unsigned int limit
9622 276 : = constant_lower_bound (GET_MODE_SIZE (inner_mode));
9623 14604 : for (unsigned int i = 0; i < limit; ++i)
9624 : {
9625 14328 : unsigned int elt = i / GET_MODE_SIZE (int_mode);
9626 14328 : rtx expected = NULL_RTX;
9627 14328 : if (elt >= first_valid)
9628 : {
9629 14328 : unsigned int byte_shift = i % GET_MODE_SIZE (int_mode);
9630 14328 : if (BYTES_BIG_ENDIAN)
9631 : byte_shift = GET_MODE_SIZE (int_mode) - byte_shift - 1;
9632 14328 : rtx_mode_t vec_elt (CONST_VECTOR_ELT (x, elt), int_mode);
9633 14328 : wide_int shifted_elt
9634 14328 : = wi::lrshift (vec_elt, byte_shift * BITS_PER_UNIT);
9635 14328 : expected = immed_wide_int_const (shifted_elt, QImode);
9636 14328 : }
9637 28656 : poly_uint64 byte = elt_bias * GET_MODE_SIZE (int_mode) + i;
9638 14328 : ASSERT_RTX_EQ (expected,
9639 : simplify_subreg (QImode, x, inner_mode, byte));
9640 : }
9641 : }
9642 276 : }
9643 :
9644 : /* Test constant subregs of integer vector mode INNER_MODE, using 1
9645 : element per pattern. */
9646 :
9647 : static void
9648 92 : test_vector_subregs_repeating (machine_mode inner_mode)
9649 : {
9650 184 : poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
9651 92 : unsigned int min_nunits = constant_lower_bound (nunits);
9652 92 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9653 92 : unsigned int count = gcd (min_nunits, 8);
9654 :
9655 92 : rtx_vector_builder builder (inner_mode, count, 1);
9656 684 : for (unsigned int i = 0; i < count; ++i)
9657 592 : builder.quick_push (gen_int_mode (8 - i, int_mode));
9658 92 : rtx x = builder.build ();
9659 :
9660 92 : test_vector_subregs_modes (x);
9661 92 : if (!nunits.is_constant ())
9662 : test_vector_subregs_modes (x, nunits - min_nunits);
9663 92 : }
9664 :
9665 : /* Test constant subregs of integer vector mode INNER_MODE, using 2
9666 : elements per pattern. */
9667 :
9668 : static void
9669 92 : test_vector_subregs_fore_back (machine_mode inner_mode)
9670 : {
9671 184 : poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
9672 92 : unsigned int min_nunits = constant_lower_bound (nunits);
9673 92 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9674 92 : unsigned int count = gcd (min_nunits, 4);
9675 :
9676 92 : rtx_vector_builder builder (inner_mode, count, 2);
9677 444 : for (unsigned int i = 0; i < count; ++i)
9678 352 : builder.quick_push (gen_int_mode (i, int_mode));
9679 444 : for (unsigned int i = 0; i < count; ++i)
9680 352 : builder.quick_push (gen_int_mode (-1 - (int) i, int_mode));
9681 92 : rtx x = builder.build ();
9682 :
9683 92 : test_vector_subregs_modes (x);
9684 92 : if (!nunits.is_constant ())
9685 : test_vector_subregs_modes (x, nunits - min_nunits, count);
9686 92 : }
9687 :
9688 : /* Test constant subregs of integer vector mode INNER_MODE, using 3
9689 : elements per pattern. */
9690 :
9691 : static void
9692 92 : test_vector_subregs_stepped (machine_mode inner_mode)
9693 : {
9694 : /* Build { 0, 1, 2, 3, ... }. */
9695 92 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9696 92 : rtx_vector_builder builder (inner_mode, 1, 3);
9697 368 : for (unsigned int i = 0; i < 3; ++i)
9698 276 : builder.quick_push (gen_int_mode (i, int_mode));
9699 92 : rtx x = builder.build ();
9700 :
9701 92 : test_vector_subregs_modes (x);
9702 92 : }
9703 :
9704 : /* Test constant subregs of integer vector mode INNER_MODE. */
9705 :
9706 : static void
9707 92 : test_vector_subregs (machine_mode inner_mode)
9708 : {
9709 92 : test_vector_subregs_repeating (inner_mode);
9710 92 : test_vector_subregs_fore_back (inner_mode);
9711 92 : test_vector_subregs_stepped (inner_mode);
9712 92 : }
9713 :
9714 : /* Verify some simplifications involving vectors. */
9715 :
9716 : static void
9717 4 : test_vector_ops ()
9718 : {
9719 500 : for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
9720 : {
9721 496 : machine_mode mode = (machine_mode) i;
9722 496 : if (VECTOR_MODE_P (mode))
9723 : {
9724 448 : rtx scalar_reg = make_test_reg (GET_MODE_INNER (mode));
9725 224 : test_vector_ops_duplicate (mode, scalar_reg);
9726 224 : rtx vector_reg = make_test_reg (mode);
9727 224 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
9728 348 : && maybe_gt (GET_MODE_NUNITS (mode), 2))
9729 : {
9730 92 : test_vector_ops_series (mode, scalar_reg);
9731 92 : test_vector_subregs (mode);
9732 92 : test_vector_rotate (vector_reg);
9733 : }
9734 224 : test_vec_merge (mode);
9735 : }
9736 : }
9737 4 : }
9738 :
9739 : template<unsigned int N>
9740 : struct simplify_const_poly_int_tests
9741 : {
9742 : static void run ();
9743 : };
9744 :
9745 : template<>
9746 : struct simplify_const_poly_int_tests<1>
9747 : {
9748 : static void run () {}
9749 : };
9750 :
9751 : /* Test various CONST_POLY_INT properties. */
9752 :
9753 : template<unsigned int N>
9754 : void
9755 : simplify_const_poly_int_tests<N>::run ()
9756 : {
9757 : using poly_int64 = poly_int<N, HOST_WIDE_INT>;
9758 : rtx x1 = gen_int_mode (poly_int64 (1, 1), QImode);
9759 : rtx x2 = gen_int_mode (poly_int64 (-80, 127), QImode);
9760 : rtx x3 = gen_int_mode (poly_int64 (-79, -128), QImode);
9761 : rtx x4 = gen_int_mode (poly_int64 (5, 4), QImode);
9762 : rtx x5 = gen_int_mode (poly_int64 (30, 24), QImode);
9763 : rtx x6 = gen_int_mode (poly_int64 (20, 16), QImode);
9764 : rtx x7 = gen_int_mode (poly_int64 (7, 4), QImode);
9765 : rtx x8 = gen_int_mode (poly_int64 (30, 24), HImode);
9766 : rtx x9 = gen_int_mode (poly_int64 (-30, -24), HImode);
9767 : rtx x10 = gen_int_mode (poly_int64 (-31, -24), HImode);
9768 : rtx two = GEN_INT (2);
9769 : rtx six = GEN_INT (6);
9770 : poly_uint64 offset = subreg_lowpart_offset (QImode, HImode);
9771 :
9772 : /* These tests only try limited operation combinations. Fuller arithmetic
9773 : testing is done directly on poly_ints. */
9774 : ASSERT_EQ (simplify_unary_operation (NEG, HImode, x8, HImode), x9);
9775 : ASSERT_EQ (simplify_unary_operation (NOT, HImode, x8, HImode), x10);
9776 : ASSERT_EQ (simplify_unary_operation (TRUNCATE, QImode, x8, HImode), x5);
9777 : ASSERT_EQ (simplify_binary_operation (PLUS, QImode, x1, x2), x3);
9778 : ASSERT_EQ (simplify_binary_operation (MINUS, QImode, x3, x1), x2);
9779 : ASSERT_EQ (simplify_binary_operation (MULT, QImode, x4, six), x5);
9780 : ASSERT_EQ (simplify_binary_operation (MULT, QImode, six, x4), x5);
9781 : ASSERT_EQ (simplify_binary_operation (ASHIFT, QImode, x4, two), x6);
9782 : ASSERT_EQ (simplify_binary_operation (IOR, QImode, x4, two), x7);
9783 : ASSERT_EQ (simplify_subreg (HImode, x5, QImode, 0), x8);
9784 : ASSERT_EQ (simplify_subreg (QImode, x8, HImode, offset), x5);
9785 : }
9786 :
9787 : /* Run all of the selftests within this file. */
9788 :
9789 : void
9790 4 : simplify_rtx_cc_tests ()
9791 : {
9792 4 : test_scalar_ops ();
9793 4 : test_vector_ops ();
9794 4 : simplify_const_poly_int_tests<NUM_POLY_INT_COEFFS>::run ();
9795 4 : }
9796 :
9797 : } // namespace selftest
9798 :
9799 : #endif /* CHECKING_P */
|