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 9154886 : neg_poly_int_rtx (machine_mode mode, const_rtx i)
56 : {
57 9154886 : 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 6244173 : mode_signbit_p (machine_mode mode, const_rtx x)
65 : {
66 6244173 : unsigned HOST_WIDE_INT val;
67 6244173 : unsigned int width;
68 6244173 : scalar_int_mode int_mode;
69 :
70 6244173 : if (!is_int_mode (mode, &int_mode))
71 : return false;
72 :
73 6244165 : width = GET_MODE_PRECISION (int_mode);
74 6244165 : if (width == 0)
75 : return false;
76 :
77 6244165 : if (width <= HOST_BITS_PER_WIDE_INT
78 6242630 : && CONST_INT_P (x))
79 6093035 : val = INTVAL (x);
80 : #if TARGET_SUPPORTS_WIDE_INT
81 151130 : else if (CONST_WIDE_INT_P (x))
82 : {
83 483 : unsigned int i;
84 483 : unsigned int elts = CONST_WIDE_INT_NUNITS (x);
85 483 : if (elts != (width + HOST_BITS_PER_WIDE_INT - 1) / HOST_BITS_PER_WIDE_INT)
86 : return false;
87 906 : for (i = 0; i < elts - 1; i++)
88 483 : if (CONST_WIDE_INT_ELT (x, i) != 0)
89 : return false;
90 423 : val = CONST_WIDE_INT_ELT (x, elts - 1);
91 423 : width %= HOST_BITS_PER_WIDE_INT;
92 423 : if (width == 0)
93 : width = HOST_BITS_PER_WIDE_INT;
94 : }
95 : #else
96 : else if (width <= HOST_BITS_PER_DOUBLE_INT
97 : && CONST_DOUBLE_AS_INT_P (x)
98 : && CONST_DOUBLE_LOW (x) == 0)
99 : {
100 : val = CONST_DOUBLE_HIGH (x);
101 : width -= HOST_BITS_PER_WIDE_INT;
102 : }
103 : #endif
104 : else
105 : /* X is not an integer constant. */
106 : return false;
107 :
108 6093035 : if (width < HOST_BITS_PER_WIDE_INT)
109 5548105 : val &= (HOST_WIDE_INT_1U << width) - 1;
110 6093458 : 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 3800315 : val_signbit_p (machine_mode mode, unsigned HOST_WIDE_INT val)
119 : {
120 3800315 : unsigned int width;
121 3800315 : scalar_int_mode int_mode;
122 :
123 3800315 : if (!is_int_mode (mode, &int_mode))
124 : return false;
125 :
126 3800279 : width = GET_MODE_PRECISION (int_mode);
127 3800279 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
128 : return false;
129 :
130 3795365 : val &= GET_MODE_MASK (int_mode);
131 3795365 : 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 2614408 : val_signbit_known_set_p (machine_mode mode, unsigned HOST_WIDE_INT val)
138 : {
139 2614408 : unsigned int width;
140 :
141 2614408 : scalar_int_mode int_mode;
142 2614408 : if (!is_int_mode (mode, &int_mode))
143 : return false;
144 :
145 2567954 : width = GET_MODE_PRECISION (int_mode);
146 2567954 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
147 : return false;
148 :
149 2567954 : val &= HOST_WIDE_INT_1U << (width - 1);
150 2567954 : 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 7873927 : val_signbit_known_clear_p (machine_mode mode, unsigned HOST_WIDE_INT val)
157 : {
158 7873927 : unsigned int width;
159 :
160 7873927 : scalar_int_mode int_mode;
161 7873927 : if (!is_int_mode (mode, &int_mode))
162 : return false;
163 :
164 7511094 : width = GET_MODE_PRECISION (int_mode);
165 7511094 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
166 : return false;
167 :
168 7400519 : val &= HOST_WIDE_INT_1U << (width - 1);
169 7400519 : 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 122269918 : simplify_context::simplify_gen_binary (rtx_code code, machine_mode mode,
177 : rtx op0, rtx op1)
178 : {
179 122269918 : rtx tem;
180 :
181 : /* If this simplifies, do it. */
182 122269918 : tem = simplify_binary_operation (code, mode, op0, op1);
183 122269918 : if (tem)
184 : return tem;
185 :
186 : /* Put complex operands first and constants second if commutative. */
187 77649159 : if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
188 77649159 : && swap_commutative_operands_p (op0, op1))
189 : std::swap (op0, op1);
190 :
191 77649159 : 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 2784801864 : avoid_constant_pool_reference (rtx x)
198 : {
199 2784801864 : rtx c, tmp, addr;
200 2784801864 : machine_mode cmode;
201 2784801864 : poly_int64 offset = 0;
202 :
203 2784801864 : switch (GET_CODE (x))
204 : {
205 266636714 : case MEM:
206 266636714 : break;
207 :
208 916195 : case FLOAT_EXTEND:
209 : /* Handle float extensions of constant pool references. */
210 916195 : tmp = XEXP (x, 0);
211 916195 : c = avoid_constant_pool_reference (tmp);
212 916195 : if (c != tmp && CONST_DOUBLE_AS_FLOAT_P (c))
213 125111 : return const_double_from_real_value (*CONST_DOUBLE_REAL_VALUE (c),
214 125111 : GET_MODE (x));
215 : return x;
216 :
217 : default:
218 : return x;
219 : }
220 :
221 266636714 : if (GET_MODE (x) == BLKmode)
222 : return x;
223 :
224 262545701 : addr = XEXP (x, 0);
225 :
226 : /* Call target hook to avoid the effects of -fpic etc.... */
227 262545701 : addr = targetm.delegitimize_address (addr);
228 :
229 : /* Split the address into a base and integer offset. */
230 262545701 : addr = strip_offset (addr, &offset);
231 :
232 262545701 : 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 262545701 : if (GET_CODE (addr) == SYMBOL_REF
238 262545701 : && CONSTANT_POOL_ADDRESS_P (addr))
239 : {
240 5406076 : c = get_pool_constant (addr);
241 5406076 : 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 5406076 : if (known_eq (offset, 0) && cmode == GET_MODE (x))
247 : return c;
248 45324 : else if (known_in_range_p (offset, 0, GET_MODE_SIZE (cmode)))
249 : {
250 15108 : rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset);
251 15108 : if (tem && CONSTANT_P (tem))
252 14991 : 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 3572909126 : 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 3572909126 : if (MEM_P (x)
269 62923166 : && MEM_EXPR (x)
270 3611896879 : && MEM_OFFSET_KNOWN_P (x))
271 : {
272 35995132 : tree decl = MEM_EXPR (x);
273 35995132 : machine_mode mode = GET_MODE (x);
274 35995132 : poly_int64 offset = 0;
275 :
276 35995132 : switch (TREE_CODE (decl))
277 : {
278 : default:
279 : decl = NULL;
280 : break;
281 :
282 : case VAR_DECL:
283 : break;
284 :
285 10194184 : case ARRAY_REF:
286 10194184 : case ARRAY_RANGE_REF:
287 10194184 : case COMPONENT_REF:
288 10194184 : case BIT_FIELD_REF:
289 10194184 : case REALPART_EXPR:
290 10194184 : case IMAGPART_EXPR:
291 10194184 : case VIEW_CONVERT_EXPR:
292 10194184 : {
293 10194184 : poly_int64 bitsize, bitpos, bytepos, toffset_val = 0;
294 10194184 : tree toffset;
295 10194184 : int unsignedp, reversep, volatilep = 0;
296 :
297 10194184 : decl
298 10194184 : = get_inner_reference (decl, &bitsize, &bitpos, &toffset, &mode,
299 : &unsignedp, &reversep, &volatilep);
300 20388368 : if (maybe_ne (bitsize, GET_MODE_BITSIZE (mode))
301 10486808 : || !multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
302 19947717 : || (toffset && !poly_int_tree_p (toffset, &toffset_val)))
303 : decl = NULL;
304 : else
305 9460909 : offset += bytepos + toffset_val;
306 10194184 : break;
307 : }
308 : }
309 :
310 733275 : if (decl
311 21084982 : && mode == GET_MODE (x)
312 20813239 : && VAR_P (decl)
313 13534171 : && (TREE_STATIC (decl)
314 12302583 : || DECL_THREAD_LOCAL_P (decl))
315 1268548 : && DECL_RTL_SET_P (decl)
316 10729011 : && MEM_P (DECL_RTL (decl)))
317 : {
318 1268102 : rtx newx;
319 :
320 1268102 : offset += MEM_OFFSET (x);
321 :
322 1268102 : newx = DECL_RTL (decl);
323 :
324 1268102 : if (MEM_P (newx))
325 : {
326 1268102 : rtx n = XEXP (newx, 0), o = XEXP (x, 0);
327 1268102 : 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 1268102 : n = strip_offset (n, &n_offset);
336 1268102 : o = strip_offset (o, &o_offset);
337 2508352 : if (!(known_eq (o_offset, n_offset + offset)
338 1240250 : && rtx_equal_p (o, n)))
339 212751 : 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 3572909126 : 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 7129709 : simplify_context::simplify_gen_unary (rtx_code code, machine_mode mode, rtx op,
355 : machine_mode op_mode)
356 : {
357 7129709 : rtx tem;
358 :
359 : /* If this simplifies, use it. */
360 7129709 : if ((tem = simplify_unary_operation (code, mode, op, op_mode)) != 0)
361 : return tem;
362 :
363 2440662 : return gen_rtx_fmt_e (code, mode, op);
364 : }
365 :
366 : /* Likewise for ternary operations. */
367 :
368 : rtx
369 2437994 : 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 2437994 : rtx tem;
374 :
375 : /* If this simplifies, use it. */
376 2437994 : if ((tem = simplify_ternary_operation (code, mode, op0_mode,
377 : op0, op1, op2)) != 0)
378 : return tem;
379 :
380 2185986 : 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 21828175 : simplify_context::simplify_gen_relational (rtx_code code, machine_mode mode,
388 : machine_mode cmp_mode,
389 : rtx op0, rtx op1)
390 : {
391 21828175 : rtx tem;
392 :
393 21828175 : if ((tem = simplify_relational_operation (code, mode, cmp_mode,
394 : op0, op1)) != 0)
395 : return tem;
396 :
397 19663557 : 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 503671962 : simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
407 : rtx (*fn) (rtx, const_rtx, void *), void *data)
408 : {
409 503671962 : enum rtx_code code = GET_CODE (x);
410 503671962 : machine_mode mode = GET_MODE (x);
411 503671962 : machine_mode op_mode;
412 503671962 : const char *fmt;
413 503671962 : rtx op0, op1, op2, newx, op;
414 503671962 : rtvec vec, newvec;
415 503671962 : int i, j;
416 :
417 503671962 : if (UNLIKELY (fn != NULL))
418 : {
419 441342785 : newx = fn (x, old_rtx, data);
420 441342785 : if (newx)
421 : return newx;
422 : }
423 62329177 : else if (rtx_equal_p (x, old_rtx))
424 5206014 : return copy_rtx ((rtx) data);
425 :
426 397106464 : switch (GET_RTX_CLASS (code))
427 : {
428 2054117 : case RTX_UNARY:
429 2054117 : op0 = XEXP (x, 0);
430 2054117 : op_mode = GET_MODE (op0);
431 2054117 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
432 2054117 : if (op0 == XEXP (x, 0))
433 : return x;
434 650812 : return simplify_gen_unary (code, mode, op0, op_mode);
435 :
436 76471761 : case RTX_BIN_ARITH:
437 76471761 : case RTX_COMM_ARITH:
438 76471761 : op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
439 76471761 : op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
440 76471761 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
441 : return x;
442 23633789 : return simplify_gen_binary (code, mode, op0, op1);
443 :
444 9757651 : case RTX_COMPARE:
445 9757651 : case RTX_COMM_COMPARE:
446 9757651 : op0 = XEXP (x, 0);
447 9757651 : op1 = XEXP (x, 1);
448 9757651 : op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
449 9757651 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
450 9757651 : op1 = simplify_replace_fn_rtx (op1, old_rtx, fn, data);
451 9757651 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
452 : return x;
453 2305978 : return simplify_gen_relational (code, mode, op_mode, op0, op1);
454 :
455 5852096 : case RTX_TERNARY:
456 5852096 : case RTX_BITFIELD_OPS:
457 5852096 : op0 = XEXP (x, 0);
458 5852096 : op_mode = GET_MODE (op0);
459 5852096 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
460 5852096 : op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
461 5852096 : op2 = simplify_replace_fn_rtx (XEXP (x, 2), old_rtx, fn, data);
462 5852096 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2))
463 : return x;
464 1680567 : if (op_mode == VOIDmode)
465 1656952 : op_mode = GET_MODE (op0);
466 1680567 : return simplify_gen_ternary (code, mode, op_mode, op0, op1, op2);
467 :
468 90330650 : case RTX_EXTRA:
469 90330650 : if (code == SUBREG)
470 : {
471 613846 : op0 = simplify_replace_fn_rtx (SUBREG_REG (x), old_rtx, fn, data);
472 613846 : if (op0 == SUBREG_REG (x))
473 : return x;
474 132780 : op0 = simplify_gen_subreg (GET_MODE (x), op0,
475 66390 : GET_MODE (SUBREG_REG (x)),
476 66390 : SUBREG_BYTE (x));
477 66390 : return op0 ? op0 : x;
478 : }
479 : break;
480 :
481 63214218 : case RTX_OBJ:
482 63214218 : if (code == MEM)
483 : {
484 10892628 : op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
485 10892628 : if (op0 == XEXP (x, 0))
486 : return x;
487 160649 : return replace_equiv_address_nv (x, op0);
488 : }
489 52321590 : 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 291464365 : newx = x;
515 291464365 : fmt = GET_RTX_FORMAT (code);
516 630319462 : for (i = 0; fmt[i]; i++)
517 338855097 : switch (fmt[i])
518 : {
519 3247047 : case 'E':
520 3247047 : vec = XVEC (x, i);
521 3247047 : newvec = XVEC (newx, i);
522 13508327 : for (j = 0; j < GET_NUM_ELEM (vec); j++)
523 : {
524 10261280 : op = simplify_replace_fn_rtx (RTVEC_ELT (vec, j),
525 : old_rtx, fn, data);
526 10261280 : if (op != RTVEC_ELT (vec, j))
527 : {
528 357667 : if (newvec == vec)
529 : {
530 342694 : newvec = shallow_copy_rtvec (vec);
531 342694 : if (x == newx)
532 342694 : newx = shallow_copy_rtx (x);
533 342694 : XVEC (newx, i) = newvec;
534 : }
535 357667 : RTVEC_ELT (newvec, j) = op;
536 : }
537 : }
538 : break;
539 :
540 81727275 : case 'e':
541 81727275 : if (XEXP (x, i))
542 : {
543 81727226 : op = simplify_replace_fn_rtx (XEXP (x, i), old_rtx, fn, data);
544 81727226 : if (op != XEXP (x, i))
545 : {
546 4643295 : if (x == newx)
547 4640075 : newx = shallow_copy_rtx (x);
548 4643295 : 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 12831469 : simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx)
561 : {
562 12831469 : 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 23466507 : simplify_context::simplify_truncation (machine_mode mode, rtx op,
614 : machine_mode op_mode)
615 : {
616 23466507 : unsigned int precision = GET_MODE_UNIT_PRECISION (mode);
617 23466507 : unsigned int op_precision = GET_MODE_UNIT_PRECISION (op_mode);
618 23466507 : scalar_int_mode int_mode, int_op_mode, subreg_mode;
619 :
620 23466507 : gcc_assert (precision <= op_precision);
621 :
622 : /* Optimize truncations of zero and sign extended values. */
623 23466507 : if (GET_CODE (op) == ZERO_EXTEND
624 23466507 : || 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 374249 : machine_mode origmode = GET_MODE (XEXP (op, 0));
633 374249 : if (mode == origmode)
634 : return XEXP (op, 0);
635 26894 : else if (precision <= GET_MODE_UNIT_PRECISION (origmode))
636 10516 : return simplify_gen_unary (TRUNCATE, mode,
637 10516 : XEXP (op, 0), origmode);
638 : else
639 2931 : return simplify_gen_unary (GET_CODE (op), mode,
640 2931 : 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 23092258 : if (1
647 : && (!WORD_REGISTER_OPERATIONS || precision >= BITS_PER_WORD)
648 : && (GET_CODE (op) == PLUS
649 : || GET_CODE (op) == MINUS
650 23092258 : || GET_CODE (op) == MULT))
651 : {
652 1399550 : rtx op0 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0), op_mode);
653 1399550 : if (op0)
654 : {
655 1399550 : rtx op1 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 1), op_mode);
656 1399550 : if (op1)
657 1399550 : 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 21692708 : if ((GET_CODE (op) == LSHIFTRT
665 21692708 : || 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 1916537 : && 2 * precision <= op_precision
671 1916537 : && CONST_INT_P (XEXP (op, 1))
672 1815194 : && 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 21692684 : if ((GET_CODE (op) == LSHIFTRT
682 : || GET_CODE (op) == ASHIFTRT)
683 1916513 : && CONST_INT_P (XEXP (op, 1))
684 1815170 : && GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
685 819 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
686 819 : && UINTVAL (XEXP (op, 1)) < precision)
687 802 : return simplify_gen_binary (LSHIFTRT, mode,
688 802 : 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 21691882 : if (GET_CODE (op) == ASHIFT
694 842366 : && CONST_INT_P (XEXP (op, 1))
695 782821 : && (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
696 782821 : || GET_CODE (XEXP (op, 0)) == SIGN_EXTEND)
697 671 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
698 663 : && UINTVAL (XEXP (op, 1)) < precision)
699 618 : return simplify_gen_binary (ASHIFT, mode,
700 618 : 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 21691264 : if (GET_CODE (op) == AND
706 795203 : && (GET_CODE (XEXP (op, 0)) == LSHIFTRT
707 795203 : || GET_CODE (XEXP (op, 0)) == ASHIFTRT)
708 47663 : && CONST_INT_P (XEXP (XEXP (op, 0), 1))
709 47561 : && CONST_INT_P (XEXP (op, 1)))
710 : {
711 47528 : rtx op0 = (XEXP (XEXP (op, 0), 0));
712 47528 : rtx shift_op = XEXP (XEXP (op, 0), 1);
713 47528 : rtx mask_op = XEXP (op, 1);
714 47528 : unsigned HOST_WIDE_INT shift = UINTVAL (shift_op);
715 47528 : unsigned HOST_WIDE_INT mask = UINTVAL (mask_op);
716 :
717 47528 : if (shift < precision
718 : /* If doing this transform works for an X with all bits set,
719 : it works for any X. */
720 31600 : && ((GET_MODE_MASK (mode) >> shift) & mask)
721 31600 : == ((GET_MODE_MASK (op_mode) >> shift) & mask)
722 6821 : && (op0 = simplify_gen_unary (TRUNCATE, mode, op0, op_mode))
723 54349 : && (op0 = simplify_gen_binary (LSHIFTRT, mode, op0, shift_op)))
724 : {
725 6821 : mask_op = GEN_INT (trunc_int_for_mode (mask, mode));
726 6821 : return simplify_gen_binary (AND, mode, op0, mask_op);
727 : }
728 : }
729 :
730 : /* Turn (truncate:M1 (*_extract:M2 (reg:M3) (len) (pos))) into
731 : (*_extract:M1 (truncate:M1 (reg:M3)) (len) (pos')) if possible. */
732 21684443 : if ((GET_CODE (op) == ZERO_EXTRACT || GET_CODE (op) == SIGN_EXTRACT)
733 1128108 : && precision <= GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (op, 0)))
734 562307 : && CONST_INT_P (XEXP (op, 1))
735 22246750 : && CONST_INT_P (XEXP (op, 2)))
736 : {
737 527141 : rtx op0 = XEXP (op, 0);
738 527141 : unsigned HOST_WIDE_INT len = UINTVAL (XEXP (op, 1));
739 527141 : unsigned HOST_WIDE_INT pos = UINTVAL (XEXP (op, 2));
740 527141 : if (BITS_BIG_ENDIAN && pos >= op_precision - precision)
741 : {
742 : if (GET_MODE (op0) != mode)
743 : op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
744 : if (op0)
745 : {
746 : pos -= op_precision - precision;
747 : return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
748 : XEXP (op, 1), GEN_INT (pos));
749 : }
750 : }
751 527141 : else if (!BITS_BIG_ENDIAN && precision >= len + pos)
752 : {
753 178133 : if (GET_MODE (op0) != mode)
754 136294 : op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
755 136294 : if (op0)
756 178133 : return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
757 178133 : XEXP (op, 1), XEXP (op, 2));
758 : }
759 : }
760 :
761 : /* Recognize a word extraction from a multi-word subreg. */
762 21506310 : if ((GET_CODE (op) == LSHIFTRT
763 21506310 : || GET_CODE (op) == ASHIFTRT)
764 1915711 : && SCALAR_INT_MODE_P (mode)
765 1912494 : && SCALAR_INT_MODE_P (op_mode)
766 2049874 : && precision >= BITS_PER_WORD
767 61337 : && 2 * precision <= op_precision
768 61337 : && CONST_INT_P (XEXP (op, 1))
769 51853 : && (INTVAL (XEXP (op, 1)) & (precision - 1)) == 0
770 1740 : && UINTVAL (XEXP (op, 1)) < op_precision)
771 : {
772 1740 : poly_int64 byte = subreg_lowpart_offset (mode, op_mode);
773 1740 : int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
774 1740 : return simplify_gen_subreg (mode, XEXP (op, 0), op_mode,
775 : (WORDS_BIG_ENDIAN
776 1740 : ? byte - shifted_bytes
777 1740 : : 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 21504570 : if ((GET_CODE (op) == LSHIFTRT
784 : || GET_CODE (op) == ASHIFTRT)
785 1910754 : && is_a <scalar_int_mode> (mode, &int_mode)
786 21503894 : && is_a <scalar_int_mode> (op_mode, &int_op_mode)
787 1910754 : && MEM_P (XEXP (op, 0))
788 11160 : && CONST_INT_P (XEXP (op, 1))
789 20544 : && INTVAL (XEXP (op, 1)) % GET_MODE_BITSIZE (int_mode) == 0
790 719 : && INTVAL (XEXP (op, 1)) > 0
791 1438 : && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (int_op_mode)
792 719 : && ! mode_dependent_address_p (XEXP (XEXP (op, 0), 0),
793 719 : MEM_ADDR_SPACE (XEXP (op, 0)))
794 719 : && ! MEM_VOLATILE_P (XEXP (op, 0))
795 21504570 : && (GET_MODE_SIZE (int_mode) >= UNITS_PER_WORD
796 : || WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN))
797 : {
798 676 : poly_int64 byte = subreg_lowpart_offset (int_mode, int_op_mode);
799 676 : int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
800 676 : 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 21503894 : if ((GET_CODE (op) == ABS
809 21503894 : || GET_CODE (op) == NEG)
810 21231 : && (GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
811 21231 : || GET_CODE (XEXP (op, 0)) == ZERO_EXTEND)
812 17 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
813 1 : return simplify_gen_unary (GET_CODE (op), mode,
814 1 : XEXP (XEXP (op, 0), 0), mode);
815 :
816 : /* Simplifications of (truncate:A (subreg:B X 0)). */
817 21503893 : if (GET_CODE (op) == SUBREG
818 21504443 : && is_a <scalar_int_mode> (mode, &int_mode)
819 118489 : && SCALAR_INT_MODE_P (op_mode)
820 118489 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &subreg_mode)
821 21621888 : && subreg_lowpart_p (op))
822 : {
823 : /* (truncate:A (subreg:B (truncate:C X) 0)) is (truncate:A X). */
824 117975 : 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 117975 : if (is_a <scalar_int_mode> (op_mode, &int_op_mode))
841 : {
842 117975 : unsigned int int_op_prec = GET_MODE_PRECISION (int_op_mode);
843 117975 : unsigned int subreg_prec = GET_MODE_PRECISION (subreg_mode);
844 117975 : if (int_op_prec > subreg_prec)
845 : {
846 87599 : if (int_mode == subreg_mode)
847 : return SUBREG_REG (op);
848 63 : 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 30376 : else if (int_op_prec < subreg_prec
855 30376 : && GET_MODE_PRECISION (int_mode) < int_op_prec)
856 30376 : return simplify_gen_unary (TRUNCATE, int_mode,
857 30376 : SUBREG_REG (op), subreg_mode);
858 : }
859 : }
860 :
861 : /* (truncate:A (truncate:B X)) is (truncate:A X). */
862 21385954 : 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 21385954 : if (GET_CODE (op) == IOR
869 36128 : && SCALAR_INT_MODE_P (mode)
870 36128 : && SCALAR_INT_MODE_P (op_mode)
871 36128 : && CONST_INT_P (XEXP (op, 1))
872 21394676 : && 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 29748654 : simplify_context::simplify_unary_operation (rtx_code code, machine_mode mode,
883 : rtx op, machine_mode op_mode)
884 : {
885 29748654 : rtx trueop, tem;
886 :
887 29748654 : trueop = avoid_constant_pool_reference (op);
888 :
889 29748654 : tem = simplify_const_unary_operation (code, mode, trueop, op_mode);
890 29748654 : if (tem)
891 : return tem;
892 :
893 24330091 : 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 2800 : exact_int_to_float_conversion_p (const_rtx op)
901 : {
902 2800 : 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 2800 : if (op0_mode == VOIDmode)
906 : return false;
907 5598 : int out_bits = significand_size (GET_MODE_INNER (GET_MODE (op)));
908 2799 : int in_prec = GET_MODE_UNIT_PRECISION (op0_mode);
909 2799 : int in_bits = in_prec;
910 2799 : if (HWI_COMPUTABLE_MODE_P (op0_mode))
911 : {
912 2709 : unsigned HOST_WIDE_INT nonzero = nonzero_bits (XEXP (op, 0), op0_mode);
913 2709 : if (GET_CODE (op) == FLOAT)
914 2588 : in_bits -= num_sign_bit_copies (XEXP (op, 0), op0_mode);
915 121 : else if (GET_CODE (op) == UNSIGNED_FLOAT)
916 121 : in_bits = wi::min_precision (wi::uhwi (nonzero, in_prec), UNSIGNED);
917 : else
918 0 : gcc_unreachable ();
919 2709 : in_bits -= wi::ctz (wi::uhwi (nonzero, in_prec));
920 : }
921 2799 : 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 24330091 : simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
928 : rtx op)
929 : {
930 24330091 : enum rtx_code reversed;
931 24330091 : rtx temp, elt, base, step;
932 24330091 : scalar_int_mode inner, int_mode, op_mode, op0_mode;
933 :
934 24330091 : switch (code)
935 : {
936 2327210 : case NOT:
937 : /* (not (not X)) == X. */
938 2327210 : if (GET_CODE (op) == NOT)
939 3165 : 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 2324045 : if (COMPARISON_P (op)
944 17218 : && ((SCALAR_INT_MODE_P (mode) && STORE_FLAG_VALUE == -1)
945 : #ifdef VECTOR_STORE_FLAG_VALUE
946 17218 : || (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
947 : && VECTOR_STORE_FLAG_VALUE (mode) == constm1_rtx)
948 : #endif
949 11944 : || mode == BImode)
950 2329319 : && ((reversed = reversed_comparison_code (op, NULL)) != UNKNOWN))
951 5109 : return simplify_gen_relational (reversed, mode, VOIDmode,
952 5109 : XEXP (op, 0), XEXP (op, 1));
953 :
954 : /* (not (neg (eq X Y))) is (neg (ne X Y)), etc. if the result of
955 : the comparison is one. */
956 2318936 : if (GET_CODE (op) == NEG
957 70325 : && COMPARISON_P (XEXP (op, 0))
958 6 : && ((SCALAR_INT_MODE_P (mode) && STORE_FLAG_VALUE == 1)
959 : #ifdef VECTOR_STORE_FLAG_VALUE
960 0 : || (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
961 0 : && VECTOR_STORE_FLAG_VALUE (mode) == const1_rtx)
962 : #endif
963 : )
964 2318942 : && ((reversed = reversed_comparison_code (XEXP (op, 0), NULL))
965 : != UNKNOWN))
966 : {
967 12 : temp = simplify_gen_relational (reversed, mode, VOIDmode,
968 : XEXP (XEXP (op, 0), 0),
969 6 : XEXP (XEXP (op, 0), 1));
970 6 : return simplify_gen_unary (NEG, mode, temp, mode);
971 : }
972 :
973 : /* (not (plus X -1)) can become (neg X). */
974 2318930 : if (GET_CODE (op) == PLUS
975 246662 : && XEXP (op, 1) == constm1_rtx)
976 4562 : return simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
977 :
978 : /* Similarly, (not (neg X)) is (plus X -1). Only do this for
979 : modes that have CONSTM1_RTX, i.e. MODE_INT, MODE_PARTIAL_INT
980 : and MODE_VECTOR_INT. */
981 2314368 : if (GET_CODE (op) == NEG && CONSTM1_RTX (mode))
982 70316 : return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
983 70316 : CONSTM1_RTX (mode));
984 :
985 : /* (not (xor X C)) for C constant is (xor X D) with D = ~C. */
986 2244052 : if (GET_CODE (op) == XOR
987 19326 : && CONST_INT_P (XEXP (op, 1))
988 2248677 : && (temp = simplify_unary_operation (NOT, mode,
989 : XEXP (op, 1), mode)) != 0)
990 4625 : return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
991 :
992 : /* (not (plus X C)) for signbit C is (xor X D) with D = ~C. */
993 2239427 : if (GET_CODE (op) == PLUS
994 242100 : && CONST_INT_P (XEXP (op, 1))
995 135710 : && mode_signbit_p (mode, XEXP (op, 1))
996 2243253 : && (temp = simplify_unary_operation (NOT, mode,
997 : XEXP (op, 1), mode)) != 0)
998 3826 : return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
999 :
1000 :
1001 : /* (not (ashift 1 X)) is (rotate ~1 X). We used to do this for
1002 : operands other than 1, but that is not valid. We could do a
1003 : similar simplification for (not (lshiftrt C X)) where C is
1004 : just the sign bit, but this doesn't seem common enough to
1005 : bother with. */
1006 2235601 : if (GET_CODE (op) == ASHIFT
1007 31564 : && XEXP (op, 0) == const1_rtx)
1008 : {
1009 1140 : temp = simplify_gen_unary (NOT, mode, const1_rtx, mode);
1010 1140 : return simplify_gen_binary (ROTATE, mode, temp, XEXP (op, 1));
1011 : }
1012 :
1013 : /* (not (ashiftrt foo C)) where C is the number of bits in FOO
1014 : minus 1 is (ge foo (const_int 0)) if STORE_FLAG_VALUE is -1,
1015 : so we can perform the above simplification. */
1016 2234461 : if (STORE_FLAG_VALUE == -1
1017 : && is_a <scalar_int_mode> (mode, &int_mode)
1018 : && GET_CODE (op) == ASHIFTRT
1019 : && CONST_INT_P (XEXP (op, 1))
1020 : && INTVAL (XEXP (op, 1)) == GET_MODE_PRECISION (int_mode) - 1)
1021 : return simplify_gen_relational (GE, int_mode, VOIDmode,
1022 : XEXP (op, 0), const0_rtx);
1023 :
1024 :
1025 2234461 : if (partial_subreg_p (op)
1026 602505 : && subreg_lowpart_p (op)
1027 602193 : && GET_CODE (SUBREG_REG (op)) == ASHIFT
1028 620263 : && XEXP (SUBREG_REG (op), 0) == const1_rtx)
1029 : {
1030 147 : machine_mode inner_mode = GET_MODE (SUBREG_REG (op));
1031 147 : rtx x;
1032 :
1033 147 : x = gen_rtx_ROTATE (inner_mode,
1034 : simplify_gen_unary (NOT, inner_mode, const1_rtx,
1035 : inner_mode),
1036 : XEXP (SUBREG_REG (op), 1));
1037 147 : temp = rtl_hooks.gen_lowpart_no_emit (mode, x);
1038 147 : if (temp)
1039 : return temp;
1040 : }
1041 :
1042 : /* Apply De Morgan's laws to reduce number of patterns for machines
1043 : with negating logical insns (and-not, nand, etc.). If result has
1044 : only one NOT, put it first, since that is how the patterns are
1045 : coded. */
1046 2234314 : if (GET_CODE (op) == IOR || GET_CODE (op) == AND)
1047 : {
1048 14194 : rtx in1 = XEXP (op, 0), in2 = XEXP (op, 1);
1049 14194 : machine_mode op_mode;
1050 :
1051 14194 : op_mode = GET_MODE (in1);
1052 14194 : in1 = simplify_gen_unary (NOT, op_mode, in1, op_mode);
1053 :
1054 14194 : op_mode = GET_MODE (in2);
1055 14194 : if (op_mode == VOIDmode)
1056 5443 : op_mode = mode;
1057 14194 : in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode);
1058 :
1059 14194 : if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT)
1060 : std::swap (in1, in2);
1061 :
1062 28388 : return gen_rtx_fmt_ee (GET_CODE (op) == IOR ? AND : IOR,
1063 : mode, in1, in2);
1064 : }
1065 :
1066 : /* (not (bswap x)) -> (bswap (not x)). */
1067 2220120 : if (GET_CODE (op) == BSWAP || GET_CODE (op) == BITREVERSE)
1068 : {
1069 0 : rtx x = simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1070 0 : return simplify_gen_unary (GET_CODE (op), mode, x, mode);
1071 : }
1072 : break;
1073 :
1074 1803011 : case NEG:
1075 : /* (neg (neg X)) == X. */
1076 1803011 : if (GET_CODE (op) == NEG)
1077 6818 : return XEXP (op, 0);
1078 :
1079 : /* (neg (x ? (neg y) : y)) == !x ? (neg y) : y.
1080 : If comparison is not reversible use
1081 : x ? y : (neg y). */
1082 1796193 : if (GET_CODE (op) == IF_THEN_ELSE)
1083 : {
1084 3298 : rtx cond = XEXP (op, 0);
1085 3298 : rtx true_rtx = XEXP (op, 1);
1086 3298 : rtx false_rtx = XEXP (op, 2);
1087 :
1088 3298 : if ((GET_CODE (true_rtx) == NEG
1089 0 : && rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
1090 3298 : || (GET_CODE (false_rtx) == NEG
1091 0 : && rtx_equal_p (XEXP (false_rtx, 0), true_rtx)))
1092 : {
1093 0 : if (reversed_comparison_code (cond, NULL) != UNKNOWN)
1094 0 : temp = reversed_comparison (cond, mode);
1095 : else
1096 : {
1097 : temp = cond;
1098 : std::swap (true_rtx, false_rtx);
1099 : }
1100 0 : return simplify_gen_ternary (IF_THEN_ELSE, mode,
1101 0 : mode, temp, true_rtx, false_rtx);
1102 : }
1103 : }
1104 :
1105 : /* (neg (plus X 1)) can become (not X). */
1106 1796193 : if (GET_CODE (op) == PLUS
1107 139138 : && XEXP (op, 1) == const1_rtx)
1108 53774 : return simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1109 :
1110 : /* Similarly, (neg (not X)) is (plus X 1). */
1111 1742419 : if (GET_CODE (op) == NOT)
1112 261 : return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
1113 261 : CONST1_RTX (mode));
1114 :
1115 : /* (neg (minus X Y)) can become (minus Y X). This transformation
1116 : isn't safe for modes with signed zeros, since if X and Y are
1117 : both +0, (minus Y X) is the same as (minus X Y). If the
1118 : rounding mode is towards +infinity (or -infinity) then the two
1119 : expressions will be rounded differently. */
1120 1742158 : if (GET_CODE (op) == MINUS
1121 24769 : && !HONOR_SIGNED_ZEROS (mode)
1122 1765517 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1123 23359 : return simplify_gen_binary (MINUS, mode, XEXP (op, 1), XEXP (op, 0));
1124 :
1125 1718799 : if (GET_CODE (op) == PLUS
1126 85364 : && !HONOR_SIGNED_ZEROS (mode)
1127 1803727 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1128 : {
1129 : /* (neg (plus A C)) is simplified to (minus -C A). */
1130 84928 : if (CONST_SCALAR_INT_P (XEXP (op, 1))
1131 5283 : || CONST_DOUBLE_AS_FLOAT_P (XEXP (op, 1)))
1132 : {
1133 79645 : temp = simplify_unary_operation (NEG, mode, XEXP (op, 1), mode);
1134 79645 : if (temp)
1135 79645 : return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 0));
1136 : }
1137 :
1138 : /* (neg (plus A B)) is canonicalized to (minus (neg A) B). */
1139 5283 : temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
1140 5283 : return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 1));
1141 : }
1142 :
1143 : /* (neg (mult A B)) becomes (mult A (neg B)).
1144 : This works even for floating-point values. */
1145 1633871 : if (GET_CODE (op) == MULT
1146 1633871 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1147 : {
1148 25117 : temp = simplify_gen_unary (NEG, mode, XEXP (op, 1), mode);
1149 25117 : return simplify_gen_binary (MULT, mode, XEXP (op, 0), temp);
1150 : }
1151 :
1152 : /* NEG commutes with ASHIFT since it is multiplication. Only do
1153 : this if we can then eliminate the NEG (e.g., if the operand
1154 : is a constant). */
1155 1608754 : if (GET_CODE (op) == ASHIFT)
1156 : {
1157 50148 : temp = simplify_unary_operation (NEG, mode, XEXP (op, 0), mode);
1158 50148 : if (temp)
1159 10198 : return simplify_gen_binary (ASHIFT, mode, temp, XEXP (op, 1));
1160 : }
1161 :
1162 : /* (neg (ashiftrt X C)) can be replaced by (lshiftrt X C) when
1163 : C is equal to the width of MODE minus 1. */
1164 1598556 : if (GET_CODE (op) == ASHIFTRT
1165 30214 : && CONST_INT_P (XEXP (op, 1))
1166 1658876 : && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1167 776 : return simplify_gen_binary (LSHIFTRT, mode,
1168 776 : XEXP (op, 0), XEXP (op, 1));
1169 :
1170 : /* (neg (lshiftrt X C)) can be replaced by (ashiftrt X C) when
1171 : C is equal to the width of MODE minus 1. */
1172 1597780 : if (GET_CODE (op) == LSHIFTRT
1173 8958 : && CONST_INT_P (XEXP (op, 1))
1174 1615552 : && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1175 3581 : return simplify_gen_binary (ASHIFTRT, mode,
1176 3581 : XEXP (op, 0), XEXP (op, 1));
1177 :
1178 : /* (neg (xor A 1)) is (plus A -1) if A is known to be either 0 or 1. */
1179 1594199 : if (GET_CODE (op) == XOR
1180 10773 : && XEXP (op, 1) == const1_rtx
1181 1594276 : && nonzero_bits (XEXP (op, 0), mode) == 1)
1182 34 : return plus_constant (mode, XEXP (op, 0), -1);
1183 :
1184 : /* (neg (lt x 0)) is (ashiftrt X C) if STORE_FLAG_VALUE is 1. */
1185 : /* (neg (lt x 0)) is (lshiftrt X C) if STORE_FLAG_VALUE is -1. */
1186 1594165 : if (GET_CODE (op) == LT
1187 3147 : && XEXP (op, 1) == const0_rtx
1188 1596484 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op, 0)), &inner))
1189 : {
1190 495 : int_mode = as_a <scalar_int_mode> (mode);
1191 495 : int isize = GET_MODE_PRECISION (inner);
1192 495 : if (STORE_FLAG_VALUE == 1)
1193 : {
1194 495 : temp = simplify_gen_binary (ASHIFTRT, inner, XEXP (op, 0),
1195 : gen_int_shift_amount (inner,
1196 495 : isize - 1));
1197 495 : if (int_mode == inner)
1198 : return temp;
1199 266 : if (GET_MODE_PRECISION (int_mode) > isize)
1200 187 : return simplify_gen_unary (SIGN_EXTEND, int_mode, temp, inner);
1201 79 : return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1202 : }
1203 : else if (STORE_FLAG_VALUE == -1)
1204 : {
1205 : temp = simplify_gen_binary (LSHIFTRT, inner, XEXP (op, 0),
1206 : gen_int_shift_amount (inner,
1207 : isize - 1));
1208 : if (int_mode == inner)
1209 : return temp;
1210 : if (GET_MODE_PRECISION (int_mode) > isize)
1211 : return simplify_gen_unary (ZERO_EXTEND, int_mode, temp, inner);
1212 : return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1213 : }
1214 : }
1215 :
1216 1593670 : if (vec_series_p (op, &base, &step))
1217 : {
1218 : /* Only create a new series if we can simplify both parts. In other
1219 : cases this isn't really a simplification, and it's not necessarily
1220 : a win to replace a vector operation with a scalar operation. */
1221 276 : scalar_mode inner_mode = GET_MODE_INNER (mode);
1222 276 : base = simplify_unary_operation (NEG, inner_mode, base, inner_mode);
1223 276 : if (base)
1224 : {
1225 276 : step = simplify_unary_operation (NEG, inner_mode,
1226 : step, inner_mode);
1227 276 : if (step)
1228 276 : return gen_vec_series (mode, base, step);
1229 : }
1230 : }
1231 : break;
1232 :
1233 2242945 : case TRUNCATE:
1234 : /* Don't optimize (lshiftrt (mult ...)) as it would interfere
1235 : with the umulXi3_highpart patterns. */
1236 2242945 : if (GET_CODE (op) == LSHIFTRT
1237 19924 : && GET_CODE (XEXP (op, 0)) == MULT)
1238 : break;
1239 :
1240 2235872 : if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
1241 : {
1242 12 : if (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
1243 : {
1244 12 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1245 12 : if (temp)
1246 : return temp;
1247 : }
1248 : /* We can't handle truncation to a partial integer mode here
1249 : because we don't know the real bitsize of the partial
1250 : integer mode. */
1251 : break;
1252 : }
1253 :
1254 2235860 : if (GET_MODE (op) != VOIDmode)
1255 : {
1256 2235860 : temp = simplify_truncation (mode, op, GET_MODE (op));
1257 2235860 : if (temp)
1258 : return temp;
1259 : }
1260 :
1261 : /* If we know that the value is already truncated, we can
1262 : replace the TRUNCATE with a SUBREG. */
1263 1935618 : if (known_eq (GET_MODE_NUNITS (mode), 1)
1264 1935618 : && (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op))
1265 0 : || truncated_to_mode (mode, op)))
1266 : {
1267 1923079 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1268 1923079 : if (temp)
1269 : return temp;
1270 : }
1271 :
1272 : /* A truncate of a comparison can be replaced with a subreg if
1273 : STORE_FLAG_VALUE permits. This is like the previous test,
1274 : but it works even if the comparison is done in a mode larger
1275 : than HOST_BITS_PER_WIDE_INT. */
1276 12708 : if (HWI_COMPUTABLE_MODE_P (mode)
1277 169 : && COMPARISON_P (op)
1278 0 : && (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0
1279 12708 : && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
1280 : {
1281 0 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1282 0 : if (temp)
1283 : return temp;
1284 : }
1285 :
1286 : /* A truncate of a memory is just loading the low part of the memory
1287 : if we are not changing the meaning of the address. */
1288 12708 : if (GET_CODE (op) == MEM
1289 289 : && !VECTOR_MODE_P (mode)
1290 167 : && !MEM_VOLATILE_P (op)
1291 12869 : && !mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op)))
1292 : {
1293 161 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1294 161 : if (temp)
1295 : return temp;
1296 : }
1297 :
1298 : /* Check for useless truncation. */
1299 12708 : if (GET_MODE (op) == mode)
1300 : return op;
1301 : break;
1302 :
1303 174370 : case FLOAT_TRUNCATE:
1304 : /* Check for useless truncation. */
1305 174370 : if (GET_MODE (op) == mode)
1306 : return op;
1307 :
1308 174370 : if (DECIMAL_FLOAT_MODE_P (mode))
1309 : break;
1310 :
1311 : /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF. */
1312 174216 : if (GET_CODE (op) == FLOAT_EXTEND
1313 5 : && GET_MODE (XEXP (op, 0)) == mode)
1314 : return XEXP (op, 0);
1315 :
1316 : /* (float_truncate:SF (float_truncate:DF foo:XF))
1317 : = (float_truncate:SF foo:XF).
1318 : This may eliminate double rounding, so it is unsafe.
1319 :
1320 : (float_truncate:SF (float_extend:XF foo:DF))
1321 : = (float_truncate:SF foo:DF).
1322 :
1323 : (float_truncate:DF (float_extend:XF foo:SF))
1324 : = (float_extend:DF foo:SF). */
1325 174214 : if ((GET_CODE (op) == FLOAT_TRUNCATE
1326 145 : && flag_unsafe_math_optimizations)
1327 174210 : || GET_CODE (op) == FLOAT_EXTEND)
1328 14 : return simplify_gen_unary (GET_MODE_UNIT_SIZE (GET_MODE (XEXP (op, 0)))
1329 7 : > GET_MODE_UNIT_SIZE (mode)
1330 : ? FLOAT_TRUNCATE : FLOAT_EXTEND,
1331 : mode,
1332 14 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1333 :
1334 : /* (float_truncate (float x)) is (float x) */
1335 174207 : if ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1336 174207 : && (flag_unsafe_math_optimizations
1337 1416 : || exact_int_to_float_conversion_p (op)))
1338 1415 : return simplify_gen_unary (GET_CODE (op), mode,
1339 : XEXP (op, 0),
1340 1415 : GET_MODE (XEXP (op, 0)));
1341 :
1342 : /* (float_truncate:SF (OP:DF (float_extend:DF foo:sf))) is
1343 : (OP:SF foo:SF) if OP is NEG or ABS. */
1344 172792 : if ((GET_CODE (op) == ABS
1345 172792 : || GET_CODE (op) == NEG)
1346 210 : && GET_CODE (XEXP (op, 0)) == FLOAT_EXTEND
1347 28 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
1348 28 : return simplify_gen_unary (GET_CODE (op), mode,
1349 28 : XEXP (XEXP (op, 0), 0), mode);
1350 :
1351 : /* (float_truncate:SF (subreg:DF (float_truncate:SF X) 0))
1352 : is (float_truncate:SF x). */
1353 172764 : if (GET_CODE (op) == SUBREG
1354 307 : && subreg_lowpart_p (op)
1355 173068 : && GET_CODE (SUBREG_REG (op)) == FLOAT_TRUNCATE)
1356 : return SUBREG_REG (op);
1357 : break;
1358 :
1359 600505 : case FLOAT_EXTEND:
1360 : /* Check for useless extension. */
1361 600505 : if (GET_MODE (op) == mode)
1362 : return op;
1363 :
1364 600505 : if (DECIMAL_FLOAT_MODE_P (mode))
1365 : break;
1366 :
1367 : /* (float_extend (float_extend x)) is (float_extend x)
1368 :
1369 : (float_extend (float x)) is (float x) assuming that double
1370 : rounding can't happen.
1371 : */
1372 600402 : if (GET_CODE (op) == FLOAT_EXTEND
1373 600402 : || ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1374 1384 : && exact_int_to_float_conversion_p (op)))
1375 551 : return simplify_gen_unary (GET_CODE (op), mode,
1376 : XEXP (op, 0),
1377 551 : GET_MODE (XEXP (op, 0)));
1378 :
1379 : break;
1380 :
1381 332246 : case ABS:
1382 : /* (abs (neg <foo>)) -> (abs <foo>) */
1383 332246 : if (GET_CODE (op) == NEG)
1384 18 : return simplify_gen_unary (ABS, mode, XEXP (op, 0),
1385 18 : GET_MODE (XEXP (op, 0)));
1386 :
1387 : /* If the mode of the operand is VOIDmode (i.e. if it is ASM_OPERANDS),
1388 : do nothing. */
1389 332228 : if (GET_MODE (op) == VOIDmode)
1390 : break;
1391 :
1392 : /* If operand is something known to be positive, ignore the ABS. */
1393 332228 : if (val_signbit_known_clear_p (GET_MODE (op),
1394 : nonzero_bits (op, GET_MODE (op))))
1395 : return op;
1396 :
1397 : /* Using nonzero_bits doesn't (currently) work for modes wider than
1398 : HOST_WIDE_INT, so the following transformations help simplify
1399 : ABS for TImode and wider. */
1400 332082 : switch (GET_CODE (op))
1401 : {
1402 : case ABS:
1403 : case CLRSB:
1404 : case FFS:
1405 : case PARITY:
1406 : case POPCOUNT:
1407 : case SS_ABS:
1408 : return op;
1409 :
1410 0 : case LSHIFTRT:
1411 0 : if (CONST_INT_P (XEXP (op, 1))
1412 0 : && INTVAL (XEXP (op, 1)) > 0
1413 332082 : && is_a <scalar_int_mode> (mode, &int_mode)
1414 0 : && INTVAL (XEXP (op, 1)) < GET_MODE_PRECISION (int_mode))
1415 : return op;
1416 : break;
1417 :
1418 : default:
1419 : break;
1420 : }
1421 :
1422 : /* If operand is known to be only -1 or 0, convert ABS to NEG. */
1423 332082 : if (is_a <scalar_int_mode> (mode, &int_mode)
1424 55148 : && (num_sign_bit_copies (op, int_mode)
1425 55148 : == GET_MODE_PRECISION (int_mode)))
1426 14 : return gen_rtx_NEG (int_mode, op);
1427 :
1428 : break;
1429 :
1430 0 : case FFS:
1431 : /* (ffs (*_extend <X>)) = (*_extend (ffs <X>)). */
1432 0 : if (GET_CODE (op) == SIGN_EXTEND
1433 0 : || GET_CODE (op) == ZERO_EXTEND)
1434 : {
1435 0 : temp = simplify_gen_unary (FFS, GET_MODE (XEXP (op, 0)),
1436 0 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1437 0 : return simplify_gen_unary (GET_CODE (op), mode, temp,
1438 0 : GET_MODE (temp));
1439 : }
1440 : break;
1441 :
1442 3441 : case POPCOUNT:
1443 3441 : switch (GET_CODE (op))
1444 : {
1445 0 : case BSWAP:
1446 0 : case BITREVERSE:
1447 : /* (popcount (bswap <X>)) = (popcount <X>). */
1448 0 : return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1449 0 : GET_MODE (XEXP (op, 0)));
1450 :
1451 44 : case ZERO_EXTEND:
1452 : /* (popcount (zero_extend <X>)) = (zero_extend (popcount <X>)). */
1453 88 : temp = simplify_gen_unary (POPCOUNT, GET_MODE (XEXP (op, 0)),
1454 44 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1455 44 : return simplify_gen_unary (ZERO_EXTEND, mode, temp,
1456 44 : GET_MODE (temp));
1457 :
1458 0 : case ROTATE:
1459 0 : case ROTATERT:
1460 : /* Rotations don't affect popcount. */
1461 0 : if (!side_effects_p (XEXP (op, 1)))
1462 0 : return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1463 0 : GET_MODE (XEXP (op, 0)));
1464 : break;
1465 :
1466 : default:
1467 : break;
1468 : }
1469 : break;
1470 :
1471 0 : case PARITY:
1472 0 : switch (GET_CODE (op))
1473 : {
1474 0 : case NOT:
1475 0 : case BSWAP:
1476 0 : case BITREVERSE:
1477 0 : return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1478 0 : GET_MODE (XEXP (op, 0)));
1479 :
1480 0 : case ZERO_EXTEND:
1481 0 : case SIGN_EXTEND:
1482 0 : temp = simplify_gen_unary (PARITY, GET_MODE (XEXP (op, 0)),
1483 0 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1484 0 : return simplify_gen_unary (GET_CODE (op), mode, temp,
1485 0 : GET_MODE (temp));
1486 :
1487 0 : case ROTATE:
1488 0 : case ROTATERT:
1489 : /* Rotations don't affect parity. */
1490 0 : if (!side_effects_p (XEXP (op, 1)))
1491 0 : return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1492 0 : GET_MODE (XEXP (op, 0)));
1493 : break;
1494 :
1495 : case PARITY:
1496 : /* (parity (parity x)) -> parity (x). */
1497 : return op;
1498 :
1499 : default:
1500 : break;
1501 : }
1502 : break;
1503 :
1504 31063 : case BSWAP:
1505 : /* (bswap (bswap x)) -> x. */
1506 31063 : if (GET_CODE (op) == BSWAP)
1507 184 : return XEXP (op, 0);
1508 : /* Canonicalize (bswap (bitreverse x)) as (bitreverse (bswap x)). */
1509 30879 : if (GET_CODE (op) == BITREVERSE)
1510 0 : return simplify_gen_unary (BITREVERSE, mode,
1511 : simplify_gen_unary (BSWAP, mode,
1512 : XEXP (op, 0), mode),
1513 0 : mode);
1514 : break;
1515 :
1516 0 : case BITREVERSE:
1517 : /* (bitreverse (bitreverse x)) -> x. */
1518 0 : if (GET_CODE (op) == BITREVERSE)
1519 0 : return XEXP (op, 0);
1520 : break;
1521 :
1522 904694 : case FLOAT:
1523 : /* (float (sign_extend <X>)) = (float <X>). */
1524 904694 : if (GET_CODE (op) == SIGN_EXTEND)
1525 9666 : return simplify_gen_unary (FLOAT, mode, XEXP (op, 0),
1526 9666 : GET_MODE (XEXP (op, 0)));
1527 : break;
1528 :
1529 3124086 : case SIGN_EXTEND:
1530 : /* Check for useless extension. */
1531 3124086 : if (GET_MODE (op) == mode)
1532 : return op;
1533 :
1534 : /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
1535 : becomes just the MINUS if its mode is MODE. This allows
1536 : folding switch statements on machines using casesi (such as
1537 : the VAX). */
1538 3124046 : if (GET_CODE (op) == TRUNCATE
1539 62 : && GET_MODE (XEXP (op, 0)) == mode
1540 62 : && GET_CODE (XEXP (op, 0)) == MINUS
1541 0 : && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
1542 0 : && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
1543 : return XEXP (op, 0);
1544 :
1545 : /* Extending a widening multiplication should be canonicalized to
1546 : a wider widening multiplication. */
1547 3124046 : if (GET_CODE (op) == MULT)
1548 : {
1549 67419 : rtx lhs = XEXP (op, 0);
1550 67419 : rtx rhs = XEXP (op, 1);
1551 67419 : enum rtx_code lcode = GET_CODE (lhs);
1552 67419 : enum rtx_code rcode = GET_CODE (rhs);
1553 :
1554 : /* Widening multiplies usually extend both operands, but sometimes
1555 : they use a shift to extract a portion of a register. */
1556 67419 : if ((lcode == SIGN_EXTEND
1557 67290 : || (lcode == ASHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1558 888 : && (rcode == SIGN_EXTEND
1559 868 : || (rcode == ASHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1560 : {
1561 105 : machine_mode lmode = GET_MODE (lhs);
1562 105 : machine_mode rmode = GET_MODE (rhs);
1563 105 : int bits;
1564 :
1565 105 : if (lcode == ASHIFTRT)
1566 : /* Number of bits not shifted off the end. */
1567 89 : bits = (GET_MODE_UNIT_PRECISION (lmode)
1568 89 : - INTVAL (XEXP (lhs, 1)));
1569 : else /* lcode == SIGN_EXTEND */
1570 : /* Size of inner mode. */
1571 32 : bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1572 :
1573 105 : if (rcode == ASHIFTRT)
1574 85 : bits += (GET_MODE_UNIT_PRECISION (rmode)
1575 85 : - INTVAL (XEXP (rhs, 1)));
1576 : else /* rcode == SIGN_EXTEND */
1577 40 : bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1578 :
1579 : /* We can only widen multiplies if the result is mathematiclly
1580 : equivalent. I.e. if overflow was impossible. */
1581 210 : if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1582 48 : return simplify_gen_binary
1583 48 : (MULT, mode,
1584 : simplify_gen_unary (SIGN_EXTEND, mode, lhs, lmode),
1585 48 : simplify_gen_unary (SIGN_EXTEND, mode, rhs, rmode));
1586 : }
1587 : }
1588 :
1589 : /* Check for a sign extension of a subreg of a promoted
1590 : variable, where the promotion is sign-extended, and the
1591 : target mode is the same as the variable's promotion. */
1592 3123998 : if (GET_CODE (op) == SUBREG
1593 215028 : && SUBREG_PROMOTED_VAR_P (op)
1594 3130146 : && SUBREG_PROMOTED_SIGNED_P (op))
1595 : {
1596 0 : rtx subreg = SUBREG_REG (op);
1597 0 : machine_mode subreg_mode = GET_MODE (subreg);
1598 0 : if (!paradoxical_subreg_p (mode, subreg_mode))
1599 : {
1600 0 : temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
1601 0 : if (temp)
1602 : {
1603 : /* Preserve SUBREG_PROMOTED_VAR_P. */
1604 0 : if (partial_subreg_p (temp))
1605 : {
1606 0 : SUBREG_PROMOTED_VAR_P (temp) = 1;
1607 0 : SUBREG_PROMOTED_SET (temp, SRP_SIGNED);
1608 : }
1609 : return temp;
1610 : }
1611 : }
1612 : else
1613 : /* Sign-extending a sign-extended subreg. */
1614 0 : return simplify_gen_unary (SIGN_EXTEND, mode,
1615 0 : subreg, subreg_mode);
1616 : }
1617 :
1618 : /* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
1619 : (sign_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1620 3123998 : if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND)
1621 : {
1622 20073 : gcc_assert (GET_MODE_UNIT_PRECISION (mode)
1623 : > GET_MODE_UNIT_PRECISION (GET_MODE (op)));
1624 6691 : return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0),
1625 6691 : GET_MODE (XEXP (op, 0)));
1626 : }
1627 :
1628 : /* (sign_extend:M (ashiftrt:N (ashift <X> (const_int I)) (const_int I)))
1629 : is (sign_extend:M (subreg:O <X>)) if there is mode with
1630 : GET_MODE_BITSIZE (N) - I bits.
1631 : (sign_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1632 : is similarly (zero_extend:M (subreg:O <X>)). */
1633 3117307 : if ((GET_CODE (op) == ASHIFTRT || GET_CODE (op) == LSHIFTRT)
1634 89878 : && GET_CODE (XEXP (op, 0)) == ASHIFT
1635 3119929 : && is_a <scalar_int_mode> (mode, &int_mode)
1636 5242 : && CONST_INT_P (XEXP (op, 1))
1637 5242 : && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1638 3122420 : && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1639 5113 : GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1640 : {
1641 5113 : scalar_int_mode tmode;
1642 5113 : gcc_assert (GET_MODE_PRECISION (int_mode)
1643 : > GET_MODE_PRECISION (op_mode));
1644 5113 : if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1645 7606 : - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1646 : {
1647 2620 : rtx inner =
1648 2620 : rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1649 2620 : if (inner)
1650 2620 : return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
1651 : ? SIGN_EXTEND : ZERO_EXTEND,
1652 2620 : int_mode, inner, tmode);
1653 : }
1654 : }
1655 :
1656 : /* (sign_extend:M (lshiftrt:N <X> (const_int I))) is better as
1657 : (zero_extend:M (lshiftrt:N <X> (const_int I))) if I is not 0. */
1658 3114687 : if (GET_CODE (op) == LSHIFTRT
1659 181 : && CONST_INT_P (XEXP (op, 1))
1660 181 : && XEXP (op, 1) != const0_rtx)
1661 181 : return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1662 :
1663 : /* (sign_extend:M (truncate:N (lshiftrt:O <X> (const_int I)))) where
1664 : I is GET_MODE_PRECISION(O) - GET_MODE_PRECISION(N), simplifies to
1665 : (ashiftrt:M <X> (const_int I)) if modes M and O are the same, and
1666 : (truncate:M (ashiftrt:O <X> (const_int I))) if M is narrower than
1667 : O, and (sign_extend:M (ashiftrt:O <X> (const_int I))) if M is
1668 : wider than O. */
1669 3114506 : if (GET_CODE (op) == TRUNCATE
1670 62 : && GET_CODE (XEXP (op, 0)) == LSHIFTRT
1671 0 : && CONST_INT_P (XEXP (XEXP (op, 0), 1)))
1672 : {
1673 0 : scalar_int_mode m_mode, n_mode, o_mode;
1674 0 : rtx old_shift = XEXP (op, 0);
1675 0 : if (is_a <scalar_int_mode> (mode, &m_mode)
1676 0 : && is_a <scalar_int_mode> (GET_MODE (op), &n_mode)
1677 0 : && is_a <scalar_int_mode> (GET_MODE (old_shift), &o_mode)
1678 0 : && GET_MODE_PRECISION (o_mode) - GET_MODE_PRECISION (n_mode)
1679 0 : == INTVAL (XEXP (old_shift, 1)))
1680 : {
1681 0 : rtx new_shift = simplify_gen_binary (ASHIFTRT,
1682 : GET_MODE (old_shift),
1683 : XEXP (old_shift, 0),
1684 : XEXP (old_shift, 1));
1685 0 : if (GET_MODE_PRECISION (m_mode) > GET_MODE_PRECISION (o_mode))
1686 0 : return simplify_gen_unary (SIGN_EXTEND, mode, new_shift,
1687 0 : GET_MODE (new_shift));
1688 0 : if (mode != GET_MODE (new_shift))
1689 0 : return simplify_gen_unary (TRUNCATE, mode, new_shift,
1690 0 : GET_MODE (new_shift));
1691 : return new_shift;
1692 : }
1693 : }
1694 :
1695 : /* We can canonicalize SIGN_EXTEND (op) as ZERO_EXTEND (op) when
1696 : we know the sign bit of OP must be clear. */
1697 3114506 : if (val_signbit_known_clear_p (GET_MODE (op),
1698 3114506 : nonzero_bits (op, GET_MODE (op))))
1699 40062 : return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1700 :
1701 : /* (sign_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1702 3074444 : if (GET_CODE (op) == SUBREG
1703 214744 : && subreg_lowpart_p (op)
1704 214632 : && GET_MODE (SUBREG_REG (op)) == mode
1705 3257784 : && is_a <scalar_int_mode> (mode, &int_mode)
1706 190118 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1707 190118 : && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
1708 188311 : && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
1709 3262755 : && (nonzero_bits (SUBREG_REG (op), mode)
1710 188311 : & ~(GET_MODE_MASK (op_mode) >> 1)) == 0)
1711 6778 : return SUBREG_REG (op);
1712 :
1713 : #if defined(POINTERS_EXTEND_UNSIGNED)
1714 : /* As we do not know which address space the pointer is referring to,
1715 : we can do this only if the target does not support different pointer
1716 : or address modes depending on the address space. */
1717 3067666 : if (target_default_pointer_address_modes_p ()
1718 : && ! POINTERS_EXTEND_UNSIGNED
1719 : && mode == Pmode && GET_MODE (op) == ptr_mode
1720 : && (CONSTANT_P (op)
1721 : || (GET_CODE (op) == SUBREG
1722 : && REG_P (SUBREG_REG (op))
1723 : && REG_POINTER (SUBREG_REG (op))
1724 : && GET_MODE (SUBREG_REG (op)) == Pmode))
1725 : && !targetm.have_ptr_extend ())
1726 : {
1727 : temp
1728 : = convert_memory_address_addr_space_1 (Pmode, op,
1729 : ADDR_SPACE_GENERIC, false,
1730 : true);
1731 : if (temp)
1732 : return temp;
1733 : }
1734 : #endif
1735 : break;
1736 :
1737 11632660 : case ZERO_EXTEND:
1738 : /* Check for useless extension. */
1739 11632660 : if (GET_MODE (op) == mode)
1740 : return op;
1741 :
1742 : /* (zero_extend:SI (and:QI X (const))) -> (and:SI (lowpart:SI X) const)
1743 : where const does not sign bit set. */
1744 11632618 : if (GET_CODE (op) == AND
1745 120559 : && CONST_INT_P (XEXP (op, 1))
1746 92197 : && INTVAL (XEXP (op, 1)) > 0)
1747 : {
1748 84818 : rtx tem = rtl_hooks.gen_lowpart_no_emit (mode, XEXP (op, 0));
1749 84818 : if (tem)
1750 68467 : return simplify_gen_binary (AND, mode, tem, XEXP (op, 1));
1751 : }
1752 :
1753 : /* Check for a zero extension of a subreg of a promoted
1754 : variable, where the promotion is zero-extended, and the
1755 : target mode is the same as the variable's promotion. */
1756 11564151 : if (GET_CODE (op) == SUBREG
1757 1671549 : && SUBREG_PROMOTED_VAR_P (op)
1758 11564657 : && SUBREG_PROMOTED_UNSIGNED_P (op))
1759 : {
1760 506 : rtx subreg = SUBREG_REG (op);
1761 506 : machine_mode subreg_mode = GET_MODE (subreg);
1762 506 : if (!paradoxical_subreg_p (mode, subreg_mode))
1763 : {
1764 320 : temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
1765 320 : if (temp)
1766 : {
1767 : /* Preserve SUBREG_PROMOTED_VAR_P. */
1768 320 : if (partial_subreg_p (temp))
1769 : {
1770 129 : SUBREG_PROMOTED_VAR_P (temp) = 1;
1771 129 : SUBREG_PROMOTED_SET (temp, SRP_UNSIGNED);
1772 : }
1773 : return temp;
1774 : }
1775 : }
1776 : else
1777 : /* Zero-extending a zero-extended subreg. */
1778 186 : return simplify_gen_unary (ZERO_EXTEND, mode,
1779 186 : subreg, subreg_mode);
1780 : }
1781 :
1782 : /* Extending a widening multiplication should be canonicalized to
1783 : a wider widening multiplication. */
1784 11563645 : if (GET_CODE (op) == MULT)
1785 : {
1786 184129 : rtx lhs = XEXP (op, 0);
1787 184129 : rtx rhs = XEXP (op, 1);
1788 184129 : enum rtx_code lcode = GET_CODE (lhs);
1789 184129 : enum rtx_code rcode = GET_CODE (rhs);
1790 :
1791 : /* Widening multiplies usually extend both operands, but sometimes
1792 : they use a shift to extract a portion of a register. */
1793 184129 : if ((lcode == ZERO_EXTEND
1794 183494 : || (lcode == LSHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1795 833 : && (rcode == ZERO_EXTEND
1796 783 : || (rcode == LSHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1797 : {
1798 62 : machine_mode lmode = GET_MODE (lhs);
1799 62 : machine_mode rmode = GET_MODE (rhs);
1800 62 : int bits;
1801 :
1802 62 : if (lcode == LSHIFTRT)
1803 : /* Number of bits not shifted off the end. */
1804 12 : bits = (GET_MODE_UNIT_PRECISION (lmode)
1805 12 : - INTVAL (XEXP (lhs, 1)));
1806 : else /* lcode == ZERO_EXTEND */
1807 : /* Size of inner mode. */
1808 100 : bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1809 :
1810 62 : if (rcode == LSHIFTRT)
1811 12 : bits += (GET_MODE_UNIT_PRECISION (rmode)
1812 12 : - INTVAL (XEXP (rhs, 1)));
1813 : else /* rcode == ZERO_EXTEND */
1814 100 : bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1815 :
1816 : /* We can only widen multiplies if the result is mathematiclly
1817 : equivalent. I.e. if overflow was impossible. */
1818 124 : if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1819 50 : return simplify_gen_binary
1820 50 : (MULT, mode,
1821 : simplify_gen_unary (ZERO_EXTEND, mode, lhs, lmode),
1822 50 : simplify_gen_unary (ZERO_EXTEND, mode, rhs, rmode));
1823 : }
1824 : }
1825 :
1826 : /* (zero_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1827 11563595 : if (GET_CODE (op) == ZERO_EXTEND)
1828 22012 : return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0),
1829 22012 : GET_MODE (XEXP (op, 0)));
1830 :
1831 : /* (zero_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1832 : is (zero_extend:M (subreg:O <X>)) if there is mode with
1833 : GET_MODE_PRECISION (N) - I bits. */
1834 11541583 : if (GET_CODE (op) == LSHIFTRT
1835 72027 : && GET_CODE (XEXP (op, 0)) == ASHIFT
1836 11541600 : && is_a <scalar_int_mode> (mode, &int_mode)
1837 17 : && CONST_INT_P (XEXP (op, 1))
1838 12 : && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1839 11541583 : && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1840 0 : GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1841 : {
1842 0 : scalar_int_mode tmode;
1843 0 : if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1844 0 : - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1845 : {
1846 0 : rtx inner =
1847 0 : rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1848 0 : if (inner)
1849 0 : return simplify_gen_unary (ZERO_EXTEND, int_mode,
1850 0 : inner, tmode);
1851 : }
1852 : }
1853 :
1854 : /* (zero_extend:M (subreg:N <X:O>)) is <X:O> (for M == O) or
1855 : (zero_extend:M <X:O>), if X doesn't have any non-zero bits outside
1856 : of mode N. E.g.
1857 : (zero_extend:SI (subreg:QI (and:SI (reg:SI) (const_int 63)) 0)) is
1858 : (and:SI (reg:SI) (const_int 63)). */
1859 11541583 : if (partial_subreg_p (op)
1860 13137380 : && is_a <scalar_int_mode> (mode, &int_mode)
1861 1618042 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &op0_mode)
1862 1617646 : && GET_MODE_PRECISION (op0_mode) <= HOST_BITS_PER_WIDE_INT
1863 1292100 : && GET_MODE_PRECISION (int_mode) >= GET_MODE_PRECISION (op0_mode)
1864 1270473 : && subreg_lowpart_p (op)
1865 2493483 : && (nonzero_bits (SUBREG_REG (op), op0_mode)
1866 822440 : & ~GET_MODE_MASK (GET_MODE (op))) == 0)
1867 : {
1868 22245 : if (GET_MODE_PRECISION (int_mode) == GET_MODE_PRECISION (op0_mode))
1869 14793 : return SUBREG_REG (op);
1870 7452 : return simplify_gen_unary (ZERO_EXTEND, int_mode, SUBREG_REG (op),
1871 7452 : op0_mode);
1872 : }
1873 :
1874 : /* (zero_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1875 11519338 : if (GET_CODE (op) == SUBREG
1876 1648798 : && subreg_lowpart_p (op)
1877 939930 : && GET_MODE (SUBREG_REG (op)) == mode
1878 12318430 : && is_a <scalar_int_mode> (mode, &int_mode)
1879 799092 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1880 799092 : && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
1881 735425 : && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
1882 12254763 : && (nonzero_bits (SUBREG_REG (op), mode)
1883 735425 : & ~GET_MODE_MASK (op_mode)) == 0)
1884 0 : return SUBREG_REG (op);
1885 :
1886 : /* Trying to optimize:
1887 : (zero_extend:M (subreg:N (not:M (X:M)))) ->
1888 : (xor:M (zero_extend:M (subreg:N (X:M)), mask))
1889 : where the mask is GET_MODE_MASK (N).
1890 : For the cases when X:M doesn't have any non-zero bits
1891 : outside of mode N, (zero_extend:M (subreg:N (X:M))
1892 : will be simplified to just (X:M)
1893 : and whole optimization will be -> (xor:M (X:M, mask)). */
1894 11519338 : if (partial_subreg_p (op)
1895 1595797 : && GET_CODE (XEXP (op, 0)) == NOT
1896 1437 : && GET_MODE (XEXP (op, 0)) == mode
1897 1419 : && subreg_lowpart_p (op)
1898 11519689 : && HWI_COMPUTABLE_MODE_P (mode)
1899 352 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1900 1649150 : && (nonzero_bits (XEXP (XEXP (op, 0), 0), mode)
1901 352 : & ~GET_MODE_MASK (op_mode)) == 0)
1902 : {
1903 1 : unsigned HOST_WIDE_INT mask = GET_MODE_MASK (op_mode);
1904 2 : return simplify_gen_binary (XOR, mode,
1905 1 : XEXP (XEXP (op, 0), 0),
1906 1 : gen_int_mode (mask, mode));
1907 : }
1908 :
1909 : #if defined(POINTERS_EXTEND_UNSIGNED)
1910 : /* As we do not know which address space the pointer is referring to,
1911 : we can do this only if the target does not support different pointer
1912 : or address modes depending on the address space. */
1913 11519337 : if (target_default_pointer_address_modes_p ()
1914 : && POINTERS_EXTEND_UNSIGNED > 0
1915 13144403 : && mode == Pmode && GET_MODE (op) == ptr_mode
1916 977 : && (CONSTANT_P (op)
1917 956 : || (GET_CODE (op) == SUBREG
1918 0 : && REG_P (SUBREG_REG (op))
1919 0 : && REG_POINTER (SUBREG_REG (op))
1920 0 : && GET_MODE (SUBREG_REG (op)) == Pmode))
1921 11519358 : && !targetm.have_ptr_extend ())
1922 : {
1923 21 : temp
1924 21 : = convert_memory_address_addr_space_1 (Pmode, op,
1925 : ADDR_SPACE_GENERIC, false,
1926 : true);
1927 21 : if (temp)
1928 : return temp;
1929 : }
1930 : #endif
1931 : break;
1932 :
1933 776518 : case VEC_DUPLICATE:
1934 776518 : if (GET_CODE (op) == VEC_DUPLICATE)
1935 2 : return simplify_gen_unary (VEC_DUPLICATE, mode, XEXP (op, 0),
1936 2 : GET_MODE (XEXP (op, 0)));
1937 : break;
1938 :
1939 : default:
1940 : break;
1941 : }
1942 :
1943 19769958 : if (VECTOR_MODE_P (mode)
1944 1838421 : && vec_duplicate_p (op, &elt)
1945 21614328 : && code != VEC_DUPLICATE)
1946 : {
1947 5949 : if (code == SIGN_EXTEND || code == ZERO_EXTEND)
1948 : /* Enforce a canonical order of VEC_DUPLICATE wrt other unary
1949 : operations by promoting VEC_DUPLICATE to the root of the expression
1950 : (as far as possible). */
1951 4898 : temp = simplify_gen_unary (code, GET_MODE_INNER (mode),
1952 9796 : elt, GET_MODE_INNER (GET_MODE (op)));
1953 : else
1954 : /* Try applying the operator to ELT and see if that simplifies.
1955 : We can duplicate the result if so.
1956 :
1957 : The reason we traditionally haven't used simplify_gen_unary
1958 : for these codes is that it didn't necessarily seem to be a
1959 : win to convert things like:
1960 :
1961 : (neg:V (vec_duplicate:V (reg:S R)))
1962 :
1963 : to:
1964 :
1965 : (vec_duplicate:V (neg:S (reg:S R)))
1966 :
1967 : The first might be done entirely in vector registers while the
1968 : second might need a move between register files.
1969 :
1970 : However, there also cases where promoting the vec_duplicate is
1971 : more efficient, and there is definite value in having a canonical
1972 : form when matching instruction patterns. We should consider
1973 : extending the simplify_gen_unary code above to more cases. */
1974 1051 : temp = simplify_unary_operation (code, GET_MODE_INNER (mode),
1975 2102 : elt, GET_MODE_INNER (GET_MODE (op)));
1976 5949 : if (temp)
1977 5478 : return gen_vec_duplicate (mode, temp);
1978 : }
1979 :
1980 : return 0;
1981 : }
1982 :
1983 : /* Try to compute the value of a unary operation CODE whose output mode is to
1984 : be MODE with input operand OP whose mode was originally OP_MODE.
1985 : Return zero if the value cannot be computed. */
1986 : rtx
1987 29749640 : simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
1988 : rtx op, machine_mode op_mode)
1989 : {
1990 29749640 : scalar_int_mode result_mode;
1991 :
1992 29749640 : if (code == VEC_DUPLICATE)
1993 : {
1994 1923349 : gcc_assert (VECTOR_MODE_P (mode));
1995 1923349 : if (GET_MODE (op) != VOIDmode)
1996 : {
1997 817331 : if (!VECTOR_MODE_P (GET_MODE (op)))
1998 1621284 : gcc_assert (GET_MODE_INNER (mode) == GET_MODE (op));
1999 : else
2000 20067 : gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER
2001 : (GET_MODE (op)));
2002 : }
2003 1923349 : if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op))
2004 1146075 : return gen_const_vec_duplicate (mode, op);
2005 777274 : if (GET_CODE (op) == CONST_VECTOR
2006 777274 : && (CONST_VECTOR_DUPLICATE_P (op)
2007 756 : || CONST_VECTOR_NUNITS (op).is_constant ()))
2008 : {
2009 756 : unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op)
2010 756 : ? CONST_VECTOR_NPATTERNS (op)
2011 1510 : : CONST_VECTOR_NUNITS (op).to_constant ());
2012 2268 : gcc_assert (multiple_p (GET_MODE_NUNITS (mode), npatterns));
2013 756 : rtx_vector_builder builder (mode, npatterns, 1);
2014 3888 : for (unsigned i = 0; i < npatterns; i++)
2015 2376 : builder.quick_push (CONST_VECTOR_ELT (op, i));
2016 756 : return builder.build ();
2017 756 : }
2018 : }
2019 :
2020 27080939 : if (VECTOR_MODE_P (mode)
2021 1887011 : && GET_CODE (op) == CONST_VECTOR
2022 28707161 : && known_eq (GET_MODE_NUNITS (mode), CONST_VECTOR_NUNITS (op)))
2023 : {
2024 34784 : gcc_assert (GET_MODE (op) == op_mode);
2025 :
2026 34784 : rtx_vector_builder builder;
2027 34784 : if (!builder.new_unary_operation (mode, op, false))
2028 : return 0;
2029 :
2030 34784 : unsigned int count = builder.encoded_nelts ();
2031 154502 : for (unsigned int i = 0; i < count; i++)
2032 : {
2033 240474 : rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
2034 : CONST_VECTOR_ELT (op, i),
2035 240474 : GET_MODE_INNER (op_mode));
2036 120237 : if (!x || !valid_for_const_vector_p (mode, x))
2037 519 : return 0;
2038 119718 : builder.quick_push (x);
2039 : }
2040 34265 : return builder.build ();
2041 34784 : }
2042 :
2043 : /* The order of these tests is critical so that, for example, we don't
2044 : check the wrong mode (input vs. output) for a conversion operation,
2045 : such as FIX. At some point, this should be simplified. */
2046 :
2047 28568025 : if (code == FLOAT && CONST_SCALAR_INT_P (op))
2048 : {
2049 7979 : REAL_VALUE_TYPE d;
2050 :
2051 7979 : if (op_mode == VOIDmode)
2052 : {
2053 : /* CONST_INT have VOIDmode as the mode. We assume that all
2054 : the bits of the constant are significant, though, this is
2055 : a dangerous assumption as many times CONST_INTs are
2056 : created and used with garbage in the bits outside of the
2057 : precision of the implied mode of the const_int. */
2058 64 : op_mode = MAX_MODE_INT;
2059 : }
2060 :
2061 7979 : real_from_integer (&d, mode, rtx_mode_t (op, op_mode), SIGNED);
2062 :
2063 : /* Avoid the folding if flag_signaling_nans is on and
2064 : operand is a signaling NaN. */
2065 7979 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2066 : return 0;
2067 :
2068 7979 : d = real_value_truncate (mode, d);
2069 :
2070 : /* Avoid the folding if flag_rounding_math is on and the
2071 : conversion is not exact. */
2072 7979 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2073 : {
2074 1011 : bool fail = false;
2075 1011 : wide_int w = real_to_integer (&d, &fail,
2076 : GET_MODE_PRECISION
2077 1011 : (as_a <scalar_int_mode> (op_mode)));
2078 2022 : if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
2079 905 : return 0;
2080 1011 : }
2081 :
2082 7074 : return const_double_from_real_value (d, mode);
2083 : }
2084 28560046 : else if (code == UNSIGNED_FLOAT && CONST_SCALAR_INT_P (op))
2085 : {
2086 2134 : REAL_VALUE_TYPE d;
2087 :
2088 2134 : if (op_mode == VOIDmode)
2089 : {
2090 : /* CONST_INT have VOIDmode as the mode. We assume that all
2091 : the bits of the constant are significant, though, this is
2092 : a dangerous assumption as many times CONST_INTs are
2093 : created and used with garbage in the bits outside of the
2094 : precision of the implied mode of the const_int. */
2095 8 : op_mode = MAX_MODE_INT;
2096 : }
2097 :
2098 2134 : real_from_integer (&d, mode, rtx_mode_t (op, op_mode), UNSIGNED);
2099 :
2100 : /* Avoid the folding if flag_signaling_nans is on and
2101 : operand is a signaling NaN. */
2102 2134 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2103 : return 0;
2104 :
2105 2134 : d = real_value_truncate (mode, d);
2106 :
2107 : /* Avoid the folding if flag_rounding_math is on and the
2108 : conversion is not exact. */
2109 2134 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2110 : {
2111 16 : bool fail = false;
2112 16 : wide_int w = real_to_integer (&d, &fail,
2113 : GET_MODE_PRECISION
2114 16 : (as_a <scalar_int_mode> (op_mode)));
2115 28 : if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
2116 16 : return 0;
2117 16 : }
2118 :
2119 2118 : return const_double_from_real_value (d, mode);
2120 : }
2121 :
2122 28557912 : if (CONST_SCALAR_INT_P (op) && is_a <scalar_int_mode> (mode, &result_mode))
2123 : {
2124 3818247 : unsigned int width = GET_MODE_PRECISION (result_mode);
2125 3818247 : if (width > MAX_BITSIZE_MODE_ANY_INT)
2126 : return 0;
2127 :
2128 3818247 : wide_int result;
2129 3818247 : scalar_int_mode imode = (op_mode == VOIDmode
2130 3818247 : ? result_mode
2131 3818013 : : as_a <scalar_int_mode> (op_mode));
2132 3818247 : rtx_mode_t op0 = rtx_mode_t (op, imode);
2133 3818247 : int int_value;
2134 :
2135 : #if TARGET_SUPPORTS_WIDE_INT == 0
2136 : /* This assert keeps the simplification from producing a result
2137 : that cannot be represented in a CONST_DOUBLE but a lot of
2138 : upstream callers expect that this function never fails to
2139 : simplify something and so you if you added this to the test
2140 : above the code would die later anyway. If this assert
2141 : happens, you just need to make the port support wide int. */
2142 : gcc_assert (width <= HOST_BITS_PER_DOUBLE_INT);
2143 : #endif
2144 :
2145 3818247 : switch (code)
2146 : {
2147 177038 : case NOT:
2148 177038 : result = wi::bit_not (op0);
2149 177038 : break;
2150 :
2151 1863147 : case NEG:
2152 1863147 : result = wi::neg (op0);
2153 1863147 : break;
2154 :
2155 7083 : case ABS:
2156 7083 : result = wi::abs (op0);
2157 7083 : break;
2158 :
2159 0 : case FFS:
2160 0 : result = wi::shwi (wi::ffs (op0), result_mode);
2161 0 : break;
2162 :
2163 168 : case CLZ:
2164 168 : if (wi::ne_p (op0, 0))
2165 38 : int_value = wi::clz (op0);
2166 260 : else if (! CLZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2167 : return NULL_RTX;
2168 38 : result = wi::shwi (int_value, result_mode);
2169 38 : break;
2170 :
2171 0 : case CLRSB:
2172 0 : result = wi::shwi (wi::clrsb (op0), result_mode);
2173 0 : break;
2174 :
2175 0 : case CTZ:
2176 0 : if (wi::ne_p (op0, 0))
2177 0 : int_value = wi::ctz (op0);
2178 0 : else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2179 : return NULL_RTX;
2180 0 : result = wi::shwi (int_value, result_mode);
2181 0 : break;
2182 :
2183 160 : case POPCOUNT:
2184 160 : result = wi::shwi (wi::popcount (op0), result_mode);
2185 160 : break;
2186 :
2187 0 : case PARITY:
2188 0 : result = wi::shwi (wi::parity (op0), result_mode);
2189 0 : break;
2190 :
2191 1736 : case BSWAP:
2192 1736 : result = wi::bswap (op0);
2193 1736 : break;
2194 :
2195 0 : case BITREVERSE:
2196 0 : result = wi::bitreverse (op0);
2197 0 : break;
2198 :
2199 1589294 : case TRUNCATE:
2200 1589294 : case ZERO_EXTEND:
2201 1589294 : result = wide_int::from (op0, width, UNSIGNED);
2202 1589294 : break;
2203 :
2204 14450 : case US_TRUNCATE:
2205 14450 : case SS_TRUNCATE:
2206 14450 : {
2207 14450 : signop sgn = code == US_TRUNCATE ? UNSIGNED : SIGNED;
2208 14450 : wide_int nmax
2209 14450 : = wide_int::from (wi::max_value (width, sgn),
2210 28900 : GET_MODE_PRECISION (imode), sgn);
2211 14450 : wide_int nmin
2212 14450 : = wide_int::from (wi::min_value (width, sgn),
2213 28900 : GET_MODE_PRECISION (imode), sgn);
2214 14450 : result = wi::min (wi::max (op0, nmin, sgn), nmax, sgn);
2215 14450 : result = wide_int::from (result, width, sgn);
2216 14450 : break;
2217 14450 : }
2218 165171 : case SIGN_EXTEND:
2219 165171 : result = wide_int::from (op0, width, SIGNED);
2220 165171 : break;
2221 :
2222 0 : case SS_NEG:
2223 0 : if (wi::only_sign_bit_p (op0))
2224 0 : result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
2225 : else
2226 0 : result = wi::neg (op0);
2227 : break;
2228 :
2229 0 : case SS_ABS:
2230 0 : if (wi::only_sign_bit_p (op0))
2231 0 : result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
2232 : else
2233 0 : result = wi::abs (op0);
2234 : break;
2235 :
2236 : case SQRT:
2237 : default:
2238 : return 0;
2239 : }
2240 :
2241 3818117 : return immed_wide_int_const (result, result_mode);
2242 3818247 : }
2243 :
2244 24739665 : else if (CONST_DOUBLE_AS_FLOAT_P (op)
2245 413911 : && SCALAR_FLOAT_MODE_P (mode)
2246 411863 : && SCALAR_FLOAT_MODE_P (GET_MODE (op)))
2247 : {
2248 411863 : REAL_VALUE_TYPE d = *CONST_DOUBLE_REAL_VALUE (op);
2249 411863 : switch (code)
2250 : {
2251 : case SQRT:
2252 : return 0;
2253 838 : case ABS:
2254 838 : d = real_value_abs (&d);
2255 838 : break;
2256 15845 : case NEG:
2257 15845 : d = real_value_negate (&d);
2258 15845 : break;
2259 2284 : case FLOAT_TRUNCATE:
2260 : /* Don't perform the operation if flag_signaling_nans is on
2261 : and the operand is a signaling NaN. */
2262 2284 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2263 : return NULL_RTX;
2264 : /* Or if flag_rounding_math is on and the truncation is not
2265 : exact. */
2266 2284 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2267 2284 : && !exact_real_truncate (mode, &d))
2268 231 : return NULL_RTX;
2269 2053 : d = real_value_truncate (mode, d);
2270 2053 : break;
2271 386263 : case FLOAT_EXTEND:
2272 : /* Don't perform the operation if flag_signaling_nans is on
2273 : and the operand is a signaling NaN. */
2274 386263 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2275 : return NULL_RTX;
2276 : /* All this does is change the mode, unless changing
2277 : mode class. */
2278 386261 : if (GET_MODE_CLASS (mode) != GET_MODE_CLASS (GET_MODE (op)))
2279 0 : real_convert (&d, mode, &d);
2280 : break;
2281 0 : case FIX:
2282 : /* Don't perform the operation if flag_signaling_nans is on
2283 : and the operand is a signaling NaN. */
2284 0 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2285 : return NULL_RTX;
2286 0 : real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
2287 0 : break;
2288 6024 : case NOT:
2289 6024 : {
2290 6024 : long tmp[4];
2291 6024 : int i;
2292 :
2293 6024 : real_to_target (tmp, &d, GET_MODE (op));
2294 30120 : for (i = 0; i < 4; i++)
2295 24096 : tmp[i] = ~tmp[i];
2296 6024 : real_from_target (&d, tmp, mode);
2297 6024 : break;
2298 : }
2299 0 : default:
2300 0 : gcc_unreachable ();
2301 : }
2302 411021 : return const_double_from_real_value (d, mode);
2303 : }
2304 2048 : else if (CONST_DOUBLE_AS_FLOAT_P (op)
2305 2048 : && SCALAR_FLOAT_MODE_P (GET_MODE (op))
2306 24329850 : && is_int_mode (mode, &result_mode))
2307 : {
2308 2048 : unsigned int width = GET_MODE_PRECISION (result_mode);
2309 2048 : if (width > MAX_BITSIZE_MODE_ANY_INT)
2310 : return 0;
2311 :
2312 : /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
2313 : operators are intentionally left unspecified (to ease implementation
2314 : by target backends), for consistency, this routine implements the
2315 : same semantics for constant folding as used by the middle-end. */
2316 :
2317 : /* This was formerly used only for non-IEEE float.
2318 : eggert@twinsun.com says it is safe for IEEE also. */
2319 2048 : REAL_VALUE_TYPE t;
2320 2048 : const REAL_VALUE_TYPE *x = CONST_DOUBLE_REAL_VALUE (op);
2321 2048 : wide_int wmax, wmin;
2322 : /* This is part of the abi to real_to_integer, but we check
2323 : things before making this call. */
2324 2048 : bool fail;
2325 :
2326 2048 : switch (code)
2327 : {
2328 2040 : case FIX:
2329 : /* According to IEEE standard, for conversions from floating point to
2330 : integer. When a NaN or infinite operand cannot be represented in
2331 : the destination format and this cannot otherwise be indicated, the
2332 : invalid operation exception shall be signaled. When a numeric
2333 : operand would convert to an integer outside the range of the
2334 : destination format, the invalid operation exception shall be
2335 : signaled if this situation cannot otherwise be indicated. */
2336 2040 : if (REAL_VALUE_ISNAN (*x))
2337 955 : return flag_trapping_math ? NULL_RTX : const0_rtx;
2338 :
2339 1085 : if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
2340 : return NULL_RTX;
2341 :
2342 : /* Test against the signed upper bound. */
2343 125 : wmax = wi::max_value (width, SIGNED);
2344 125 : real_from_integer (&t, VOIDmode, wmax, SIGNED);
2345 125 : if (real_less (&t, x))
2346 3 : return (flag_trapping_math
2347 3 : ? NULL_RTX : immed_wide_int_const (wmax, mode));
2348 :
2349 : /* Test against the signed lower bound. */
2350 122 : wmin = wi::min_value (width, SIGNED);
2351 122 : real_from_integer (&t, VOIDmode, wmin, SIGNED);
2352 122 : if (real_less (x, &t))
2353 8 : return immed_wide_int_const (wmin, mode);
2354 :
2355 114 : return immed_wide_int_const (real_to_integer (x, &fail, width),
2356 : mode);
2357 :
2358 8 : case UNSIGNED_FIX:
2359 8 : if (REAL_VALUE_ISNAN (*x) || REAL_VALUE_NEGATIVE (*x))
2360 6 : return flag_trapping_math ? NULL_RTX : const0_rtx;
2361 :
2362 2 : if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
2363 : return NULL_RTX;
2364 :
2365 : /* Test against the unsigned upper bound. */
2366 0 : wmax = wi::max_value (width, UNSIGNED);
2367 0 : real_from_integer (&t, VOIDmode, wmax, UNSIGNED);
2368 0 : if (real_less (&t, x))
2369 0 : return (flag_trapping_math
2370 0 : ? NULL_RTX : immed_wide_int_const (wmax, mode));
2371 :
2372 0 : return immed_wide_int_const (real_to_integer (x, &fail, width),
2373 : mode);
2374 :
2375 0 : default:
2376 0 : gcc_unreachable ();
2377 : }
2378 2048 : }
2379 :
2380 : /* Handle polynomial integers. */
2381 : else if (CONST_POLY_INT_P (op))
2382 : {
2383 : poly_wide_int result;
2384 : switch (code)
2385 : {
2386 : case NEG:
2387 : result = -const_poly_int_value (op);
2388 : break;
2389 :
2390 : case NOT:
2391 : result = ~const_poly_int_value (op);
2392 : break;
2393 :
2394 : default:
2395 : return NULL_RTX;
2396 : }
2397 : return immed_wide_int_const (result, mode);
2398 : }
2399 :
2400 : return NULL_RTX;
2401 : }
2402 :
2403 : /* Subroutine of simplify_binary_operation to simplify a binary operation
2404 : CODE that can commute with byte swapping, with result mode MODE and
2405 : operating on OP0 and OP1. CODE is currently one of AND, IOR or XOR.
2406 : Return zero if no simplification or canonicalization is possible. */
2407 :
2408 : rtx
2409 37930772 : simplify_context::simplify_byte_swapping_operation (rtx_code code,
2410 : machine_mode mode,
2411 : rtx op0, rtx op1)
2412 : {
2413 37930772 : rtx tem;
2414 :
2415 : /* (op (bswap x) C1)) -> (bswap (op x C2)) with C2 swapped. */
2416 37930772 : if (GET_CODE (op0) == BSWAP && CONST_SCALAR_INT_P (op1))
2417 : {
2418 229 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0),
2419 : simplify_gen_unary (BSWAP, mode, op1, mode));
2420 229 : return simplify_gen_unary (BSWAP, mode, tem, mode);
2421 : }
2422 :
2423 : /* (op (bswap x) (bswap y)) -> (bswap (op x y)). */
2424 37930543 : if (GET_CODE (op0) == BSWAP && GET_CODE (op1) == BSWAP)
2425 : {
2426 0 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0), XEXP (op1, 0));
2427 0 : return simplify_gen_unary (BSWAP, mode, tem, mode);
2428 : }
2429 :
2430 : return NULL_RTX;
2431 : }
2432 :
2433 : /* Subroutine of simplify_binary_operation to simplify a commutative,
2434 : associative binary operation CODE with result mode MODE, operating
2435 : on OP0 and OP1. CODE is currently one of PLUS, MULT, AND, IOR, XOR,
2436 : SMIN, SMAX, UMIN or UMAX. Return zero if no simplification or
2437 : canonicalization is possible. */
2438 :
2439 : rtx
2440 48830622 : simplify_context::simplify_associative_operation (rtx_code code,
2441 : machine_mode mode,
2442 : rtx op0, rtx op1)
2443 : {
2444 48830622 : rtx tem;
2445 :
2446 : /* Normally expressions simplified by simplify-rtx.cc are combined
2447 : at most from a few machine instructions and therefore the
2448 : expressions should be fairly small. During var-tracking
2449 : we can see arbitrarily large expressions though and reassociating
2450 : those can be quadratic, so punt after encountering max_assoc_count
2451 : simplify_associative_operation calls during outermost simplify_*
2452 : call. */
2453 48830622 : if (++assoc_count >= max_assoc_count)
2454 : return NULL_RTX;
2455 :
2456 : /* Linearize the operator to the left. */
2457 48826262 : if (GET_CODE (op1) == code)
2458 : {
2459 : /* "(a op b) op (c op d)" becomes "((a op b) op c) op d)". */
2460 19139 : if (GET_CODE (op0) == code)
2461 : {
2462 4978 : tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
2463 4978 : return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
2464 : }
2465 :
2466 : /* "a op (b op c)" becomes "(b op c) op a". */
2467 14161 : if (! swap_commutative_operands_p (op1, op0))
2468 14161 : return simplify_gen_binary (code, mode, op1, op0);
2469 :
2470 : std::swap (op0, op1);
2471 : }
2472 :
2473 48807123 : if (GET_CODE (op0) == code)
2474 : {
2475 : /* Canonicalize "(x op c) op y" as "(x op y) op c". */
2476 1348786 : if (swap_commutative_operands_p (XEXP (op0, 1), op1))
2477 : {
2478 274574 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
2479 274574 : return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2480 : }
2481 :
2482 : /* Attempt to simplify "(a op b) op c" as "a op (b op c)". */
2483 1074212 : tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
2484 1074212 : if (tem != 0)
2485 82362 : return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
2486 :
2487 : /* Attempt to simplify "(a op b) op c" as "(a op c) op b". */
2488 991850 : tem = simplify_binary_operation (code, mode, XEXP (op0, 0), op1);
2489 991850 : if (tem != 0)
2490 31892 : return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2491 : }
2492 :
2493 : return 0;
2494 : }
2495 :
2496 : /* If COMPARISON can be treated as an unsigned comparison, return a mask
2497 : that represents it (8 if it includes <, 4 if it includes > and 2
2498 : if it includes ==). Return 0 otherwise. */
2499 : static int
2500 18598 : unsigned_comparison_to_mask (rtx_code comparison)
2501 : {
2502 0 : switch (comparison)
2503 : {
2504 : case LTU:
2505 : return 8;
2506 : case GTU:
2507 : return 4;
2508 : case EQ:
2509 : return 2;
2510 :
2511 : case LEU:
2512 : return 10;
2513 : case GEU:
2514 : return 6;
2515 :
2516 : case NE:
2517 : return 12;
2518 :
2519 : default:
2520 : return 0;
2521 : }
2522 : }
2523 :
2524 : /* Reverse the mapping in unsigned_comparison_to_mask, going from masks
2525 : to comparisons. */
2526 : static rtx_code
2527 6571 : mask_to_unsigned_comparison (int mask)
2528 : {
2529 6571 : switch (mask)
2530 : {
2531 : case 8:
2532 : return LTU;
2533 160 : case 4:
2534 160 : return GTU;
2535 2569 : case 2:
2536 2569 : return EQ;
2537 :
2538 160 : case 10:
2539 160 : return LEU;
2540 160 : case 6:
2541 160 : return GEU;
2542 :
2543 3362 : case 12:
2544 3362 : return NE;
2545 :
2546 0 : default:
2547 0 : gcc_unreachable ();
2548 : }
2549 : }
2550 :
2551 : /* Return a mask describing the COMPARISON. */
2552 : static int
2553 2448 : comparison_to_mask (enum rtx_code comparison)
2554 : {
2555 2448 : switch (comparison)
2556 : {
2557 : case LT:
2558 : return 8;
2559 400 : case GT:
2560 400 : return 4;
2561 423 : case EQ:
2562 423 : return 2;
2563 23 : case UNORDERED:
2564 23 : return 1;
2565 :
2566 0 : case LTGT:
2567 0 : return 12;
2568 400 : case LE:
2569 400 : return 10;
2570 401 : case GE:
2571 401 : return 6;
2572 0 : case UNLT:
2573 0 : return 9;
2574 0 : case UNGT:
2575 0 : return 5;
2576 0 : case UNEQ:
2577 0 : return 3;
2578 :
2579 0 : case ORDERED:
2580 0 : return 14;
2581 400 : case NE:
2582 400 : return 13;
2583 0 : case UNLE:
2584 0 : return 11;
2585 0 : case UNGE:
2586 0 : return 7;
2587 :
2588 0 : default:
2589 0 : gcc_unreachable ();
2590 : }
2591 : }
2592 :
2593 : /* Return a comparison corresponding to the MASK. */
2594 : static enum rtx_code
2595 984 : mask_to_comparison (int mask)
2596 : {
2597 984 : switch (mask)
2598 : {
2599 : case 8:
2600 : return LT;
2601 : case 4:
2602 : return GT;
2603 : case 2:
2604 : return EQ;
2605 : case 1:
2606 : return UNORDERED;
2607 :
2608 : case 12:
2609 : return LTGT;
2610 : case 10:
2611 : return LE;
2612 : case 6:
2613 : return GE;
2614 : case 9:
2615 : return UNLT;
2616 : case 5:
2617 : return UNGT;
2618 : case 3:
2619 : return UNEQ;
2620 :
2621 : case 14:
2622 : return ORDERED;
2623 : case 13:
2624 : return NE;
2625 : case 11:
2626 : return UNLE;
2627 : case 7:
2628 : return UNGE;
2629 :
2630 0 : default:
2631 0 : gcc_unreachable ();
2632 : }
2633 : }
2634 :
2635 : /* Canonicalize RES, a scalar const0_rtx/const_true_rtx to the right
2636 : false/true value of comparison with MODE where comparison operands
2637 : have CMP_MODE. */
2638 :
2639 : static rtx
2640 785525 : relational_result (machine_mode mode, machine_mode cmp_mode, rtx res)
2641 : {
2642 785525 : if (SCALAR_FLOAT_MODE_P (mode))
2643 : {
2644 168 : if (res == const0_rtx)
2645 164 : return CONST0_RTX (mode);
2646 : #ifdef FLOAT_STORE_FLAG_VALUE
2647 : REAL_VALUE_TYPE val = FLOAT_STORE_FLAG_VALUE (mode);
2648 : return const_double_from_real_value (val, mode);
2649 : #else
2650 : return NULL_RTX;
2651 : #endif
2652 : }
2653 785357 : if (VECTOR_MODE_P (mode))
2654 : {
2655 378 : if (res == const0_rtx)
2656 79 : return CONST0_RTX (mode);
2657 : #ifdef VECTOR_STORE_FLAG_VALUE
2658 299 : rtx val = VECTOR_STORE_FLAG_VALUE (mode);
2659 289 : if (val == NULL_RTX)
2660 : return NULL_RTX;
2661 289 : if (val == const1_rtx)
2662 0 : return CONST1_RTX (mode);
2663 :
2664 289 : return gen_const_vec_duplicate (mode, val);
2665 : #else
2666 : return NULL_RTX;
2667 : #endif
2668 : }
2669 : /* For vector comparison with scalar int result, it is unknown
2670 : if the target means here a comparison into an integral bitmask,
2671 : or comparison where all comparisons true mean const_true_rtx
2672 : whole result, or where any comparisons true mean const_true_rtx
2673 : whole result. For const0_rtx all the cases are the same. */
2674 784979 : if (VECTOR_MODE_P (cmp_mode)
2675 0 : && SCALAR_INT_MODE_P (mode)
2676 0 : && res == const_true_rtx)
2677 0 : return NULL_RTX;
2678 :
2679 : return res;
2680 : }
2681 :
2682 : /* Simplify a logical operation CODE with result mode MODE, operating on OP0
2683 : and OP1, in the case where both are relational operations. Assume that
2684 : OP0 is inverted if INVERT0_P is true.
2685 :
2686 : Return 0 if no such simplification is possible. */
2687 : rtx
2688 13801629 : simplify_context::simplify_logical_relational_operation (rtx_code code,
2689 : machine_mode mode,
2690 : rtx op0, rtx op1,
2691 : bool invert0_p)
2692 : {
2693 13801629 : if (!(COMPARISON_P (op0) && COMPARISON_P (op1)))
2694 : return 0;
2695 :
2696 21392 : if (!(rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2697 9725 : && rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))))
2698 : return 0;
2699 :
2700 9299 : if (side_effects_p (op0))
2701 : return 0;
2702 :
2703 9299 : enum rtx_code code0 = GET_CODE (op0);
2704 9299 : enum rtx_code code1 = GET_CODE (op1);
2705 9299 : machine_mode cmp_mode = GET_MODE (XEXP (op0, 0));
2706 9299 : if (cmp_mode == VOIDmode)
2707 0 : cmp_mode = GET_MODE (XEXP (op0, 1));
2708 :
2709 : /* Assume at first that the comparisons are on integers, and that the
2710 : operands are therefore ordered. */
2711 9299 : int all = 14;
2712 9299 : int mask0 = unsigned_comparison_to_mask (code0);
2713 9299 : int mask1 = unsigned_comparison_to_mask (code1);
2714 18598 : bool unsigned_p = (IN_RANGE (mask0 & 12, 4, 8)
2715 9299 : || IN_RANGE (mask1 & 12, 4, 8));
2716 1224 : if (unsigned_p)
2717 : {
2718 : /* We only reach here when comparing integers. Reject mixtures of signed
2719 : and unsigned comparisons. */
2720 8075 : if (mask0 == 0 || mask1 == 0)
2721 : return 0;
2722 : }
2723 : else
2724 : {
2725 : /* See whether the operands might be unordered. Assume that all
2726 : results are possible for CC modes, and punt later if we don't get an
2727 : always-true or always-false answer. */
2728 1224 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC || HONOR_NANS (cmp_mode))
2729 : all = 15;
2730 1224 : mask0 = comparison_to_mask (code0) & all;
2731 1224 : mask1 = comparison_to_mask (code1) & all;
2732 : }
2733 :
2734 8019 : if (invert0_p)
2735 4529 : mask0 = mask0 ^ all;
2736 :
2737 8019 : int mask;
2738 8019 : if (code == AND)
2739 928 : mask = mask0 & mask1;
2740 7091 : else if (code == IOR)
2741 952 : mask = mask0 | mask1;
2742 6139 : else if (code == XOR)
2743 6139 : mask = mask0 ^ mask1;
2744 : else
2745 : return 0;
2746 :
2747 8019 : if (mask == all)
2748 232 : return relational_result (mode, GET_MODE (op0), const_true_rtx);
2749 :
2750 7787 : if (mask == 0)
2751 232 : return relational_result (mode, GET_MODE (op0), const0_rtx);
2752 :
2753 7555 : if (unsigned_p)
2754 6571 : code = mask_to_unsigned_comparison (mask);
2755 : else
2756 : {
2757 984 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
2758 : return 0;
2759 :
2760 984 : code = mask_to_comparison (mask);
2761 : /* LTGT and NE are arithmetically equivalent for ordered operands,
2762 : with NE being the canonical choice. */
2763 984 : if (code == LTGT && all == 14)
2764 160 : code = NE;
2765 : }
2766 :
2767 7555 : op0 = XEXP (op1, 0);
2768 7555 : op1 = XEXP (op1, 1);
2769 :
2770 7555 : return simplify_gen_relational (code, mode, VOIDmode, op0, op1);
2771 : }
2772 :
2773 : /* We are going to IOR together OP0/OP1. If there is a common term in OP0/OP1
2774 : then we may be able to simplify the expression. We're primarily trying to
2775 : simplify down to IOR/XOR expression right now, but there may be other
2776 : simplifications we can do in the future.
2777 :
2778 : Return the simplified expression or NULL_RTX if no simplification was
2779 : possible. */
2780 : rtx
2781 28135467 : simplify_context::simplify_ior_with_common_term (machine_mode mode, rtx op0, rtx op1)
2782 : {
2783 : /* (ior X (plus/xor X C)) can be simplified into (ior X C) when
2784 : X and C have no bits in common. */
2785 28135467 : if ((GET_CODE (op1) == PLUS || GET_CODE (op1) == XOR)
2786 228188 : && rtx_equal_p (op0, XEXP (op1, 0))
2787 8327 : && ((nonzero_bits (op0, GET_MODE (op0))
2788 8327 : & nonzero_bits (XEXP (op1, 1), GET_MODE (op1))) == 0)
2789 28135467 : && !side_effects_p (op1))
2790 0 : return simplify_gen_binary (IOR, mode, op0, XEXP (op1, 1));
2791 :
2792 : /* (ior (and A C1) (and (not A) C2)) can be converted
2793 : into (and (xor A C2) (C1 + C2)) when there are no bits
2794 : in common between C1 and C2. */
2795 28135467 : if (GET_CODE (op0) == AND
2796 4170505 : && GET_CODE (op1) == AND
2797 390985 : && GET_CODE (XEXP (op1, 0)) == NOT
2798 18798 : && rtx_equal_p (XEXP (op0, 0), XEXP (XEXP (op1, 0), 0))
2799 3538 : && CONST_INT_P (XEXP (op0, 1))
2800 91 : && CONST_INT_P (XEXP (op1, 1))
2801 28135558 : && (INTVAL (XEXP (op0, 1)) & INTVAL (XEXP (op1, 1))) == 0)
2802 : {
2803 91 : rtx c = GEN_INT (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1)));
2804 :
2805 91 : rtx tem = simplify_gen_binary (XOR, mode, XEXP (op0, 0), XEXP (op1, 1));
2806 91 : if (tem)
2807 : {
2808 91 : tem = simplify_gen_binary (AND, mode, tem, c);
2809 :
2810 91 : if (tem)
2811 : return tem;
2812 : }
2813 : }
2814 :
2815 : /* Another variant seen on some target particularly those with
2816 : sub-word operations.
2817 :
2818 : (ior (and A C1) (plus (and A C2) C2)) can be simplified into
2819 : (and (xor (A C2) (C1 + C2).
2820 :
2821 : Where C2 is the sign bit for A's mode. So 0x80 for QI,
2822 : 0x8000 for HI, etc. In this case we know there is no carry
2823 : from the PLUS into relevant bits of the output. */
2824 28135376 : if (GET_CODE (op0) == AND
2825 4170414 : && GET_CODE (op1) == PLUS
2826 5496 : && GET_CODE (XEXP (op1, 0)) == AND
2827 168 : && rtx_equal_p (XEXP (op0, 0), XEXP (XEXP (op1, 0), 0))
2828 144 : && CONST_INT_P (XEXP (op0, 1))
2829 144 : && CONST_INT_P (XEXP (op1, 1))
2830 144 : && CONST_INT_P (XEXP (XEXP (op1, 0), 1))
2831 144 : && INTVAL (XEXP (op1, 1)) == INTVAL (XEXP (XEXP (op1, 0), 1))
2832 36 : && GET_MODE_BITSIZE (GET_MODE (op1)).is_constant ()
2833 72 : && ((INTVAL (XEXP (op1, 1)) & GET_MODE_MASK (GET_MODE (op1)))
2834 72 : == HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (GET_MODE (op1)).to_constant () - 1))
2835 28135376 : && (INTVAL (XEXP (op0, 1)) & INTVAL (XEXP (op1, 1))) == 0)
2836 : {
2837 0 : rtx c = GEN_INT (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1)));
2838 :
2839 0 : rtx tem = simplify_gen_binary (XOR, mode, XEXP (op0, 0), XEXP (op1, 1));
2840 0 : if (tem)
2841 : {
2842 0 : tem = simplify_gen_binary (AND, mode, tem, c);
2843 0 : if (tem)
2844 : return tem;
2845 : }
2846 : }
2847 : return NULL_RTX;
2848 : }
2849 :
2850 :
2851 : /* Simplify a binary operation CODE with result mode MODE, operating on OP0
2852 : and OP1. Return 0 if no simplification is possible.
2853 :
2854 : Don't use this for relational operations such as EQ or LT.
2855 : Use simplify_relational_operation instead. */
2856 : rtx
2857 490418461 : simplify_context::simplify_binary_operation (rtx_code code, machine_mode mode,
2858 : rtx op0, rtx op1)
2859 : {
2860 490418461 : rtx trueop0, trueop1;
2861 490418461 : rtx tem;
2862 :
2863 : /* Relational operations don't work here. We must know the mode
2864 : of the operands in order to do the comparison correctly.
2865 : Assuming a full word can give incorrect results.
2866 : Consider comparing 128 with -128 in QImode. */
2867 490418461 : gcc_assert (GET_RTX_CLASS (code) != RTX_COMPARE);
2868 490418461 : gcc_assert (GET_RTX_CLASS (code) != RTX_COMM_COMPARE);
2869 :
2870 : /* Make sure the constant is second. */
2871 490418461 : if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
2872 490418461 : && swap_commutative_operands_p (op0, op1))
2873 : std::swap (op0, op1);
2874 :
2875 490418461 : trueop0 = avoid_constant_pool_reference (op0);
2876 490418461 : trueop1 = avoid_constant_pool_reference (op1);
2877 :
2878 490418461 : tem = simplify_const_binary_operation (code, mode, trueop0, trueop1);
2879 490418461 : if (tem)
2880 : return tem;
2881 459953007 : tem = simplify_binary_operation_1 (code, mode, op0, op1, trueop0, trueop1);
2882 :
2883 459953007 : if (tem)
2884 : return tem;
2885 :
2886 : /* If the above steps did not result in a simplification and op0 or op1
2887 : were constant pool references, use the referenced constants directly. */
2888 395484922 : if (trueop0 != op0 || trueop1 != op1)
2889 580504 : return simplify_gen_binary (code, mode, trueop0, trueop1);
2890 :
2891 : return NULL_RTX;
2892 : }
2893 :
2894 : /* Subroutine of simplify_binary_operation_1 that looks for cases in
2895 : which OP0 and OP1 are both vector series or vector duplicates
2896 : (which are really just series with a step of 0). If so, try to
2897 : form a new series by applying CODE to the bases and to the steps.
2898 : Return null if no simplification is possible.
2899 :
2900 : MODE is the mode of the operation and is known to be a vector
2901 : integer mode. */
2902 :
2903 : rtx
2904 2571620 : simplify_context::simplify_binary_operation_series (rtx_code code,
2905 : machine_mode mode,
2906 : rtx op0, rtx op1)
2907 : {
2908 2571620 : rtx base0, step0;
2909 2571620 : if (vec_duplicate_p (op0, &base0))
2910 73626 : step0 = const0_rtx;
2911 2497994 : else if (!vec_series_p (op0, &base0, &step0))
2912 : return NULL_RTX;
2913 :
2914 74364 : rtx base1, step1;
2915 74364 : if (vec_duplicate_p (op1, &base1))
2916 437 : step1 = const0_rtx;
2917 73927 : else if (!vec_series_p (op1, &base1, &step1))
2918 : return NULL_RTX;
2919 :
2920 : /* Only create a new series if we can simplify both parts. In other
2921 : cases this isn't really a simplification, and it's not necessarily
2922 : a win to replace a vector operation with a scalar operation. */
2923 5666 : scalar_mode inner_mode = GET_MODE_INNER (mode);
2924 5666 : rtx new_base = simplify_binary_operation (code, inner_mode, base0, base1);
2925 5666 : if (!new_base)
2926 : return NULL_RTX;
2927 :
2928 4702 : rtx new_step = simplify_binary_operation (code, inner_mode, step0, step1);
2929 4702 : if (!new_step)
2930 : return NULL_RTX;
2931 :
2932 4702 : return gen_vec_series (mode, new_base, new_step);
2933 : }
2934 :
2935 : /* Subroutine of simplify_binary_operation_1. Un-distribute a binary
2936 : operation CODE with result mode MODE, operating on OP0 and OP1.
2937 : e.g. simplify (xor (and A C) (and (B C)) to (and (xor (A B) C).
2938 : Returns NULL_RTX if no simplification is possible. */
2939 :
2940 : rtx
2941 1340211 : simplify_context::simplify_distributive_operation (rtx_code code,
2942 : machine_mode mode,
2943 : rtx op0, rtx op1)
2944 : {
2945 1340211 : enum rtx_code op = GET_CODE (op0);
2946 1340211 : gcc_assert (GET_CODE (op1) == op);
2947 :
2948 1340211 : if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))
2949 1340211 : && ! side_effects_p (XEXP (op0, 1)))
2950 332720 : return simplify_gen_binary (op, mode,
2951 : simplify_gen_binary (code, mode,
2952 : XEXP (op0, 0),
2953 : XEXP (op1, 0)),
2954 332720 : XEXP (op0, 1));
2955 :
2956 1007491 : if (GET_RTX_CLASS (op) == RTX_COMM_ARITH)
2957 : {
2958 990125 : if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2959 990125 : && ! side_effects_p (XEXP (op0, 0)))
2960 489820 : return simplify_gen_binary (op, mode,
2961 : simplify_gen_binary (code, mode,
2962 : XEXP (op0, 1),
2963 : XEXP (op1, 1)),
2964 489820 : XEXP (op0, 0));
2965 500305 : if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 1))
2966 500305 : && ! side_effects_p (XEXP (op0, 0)))
2967 54 : return simplify_gen_binary (op, mode,
2968 : simplify_gen_binary (code, mode,
2969 : XEXP (op0, 1),
2970 : XEXP (op1, 0)),
2971 54 : XEXP (op0, 0));
2972 500251 : if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 0))
2973 500251 : && ! side_effects_p (XEXP (op0, 1)))
2974 256261 : return simplify_gen_binary (op, mode,
2975 : simplify_gen_binary (code, mode,
2976 : XEXP (op0, 0),
2977 : XEXP (op1, 1)),
2978 256261 : XEXP (op0, 1));
2979 : }
2980 :
2981 : return NULL_RTX;
2982 : }
2983 :
2984 : /* Return TRUE if a rotate in mode MODE with a constant count in OP1
2985 : should be reversed.
2986 :
2987 : If the rotate should not be reversed, return FALSE.
2988 :
2989 : LEFT indicates if this is a rotate left or a rotate right. */
2990 :
2991 : bool
2992 149907 : reverse_rotate_by_imm_p (machine_mode mode, unsigned int left, rtx op1)
2993 : {
2994 149907 : if (!CONST_INT_P (op1))
2995 : return false;
2996 :
2997 : /* Some targets may only be able to rotate by a constant
2998 : in one direction. So we need to query the optab interface
2999 : to see what is possible. */
3000 112684 : optab binoptab = left ? rotl_optab : rotr_optab;
3001 48487 : optab re_binoptab = left ? rotr_optab : rotl_optab;
3002 112684 : enum insn_code icode = optab_handler (binoptab, mode);
3003 112684 : enum insn_code re_icode = optab_handler (re_binoptab, mode);
3004 :
3005 : /* If the target can not support the reversed optab, then there
3006 : is nothing to do. */
3007 112684 : if (re_icode == CODE_FOR_nothing)
3008 : return false;
3009 :
3010 : /* If the target does not support the requested rotate-by-immediate,
3011 : then we want to try reversing the rotate. We also want to try
3012 : reversing to minimize the count. */
3013 110196 : if ((icode == CODE_FOR_nothing)
3014 110196 : || (!insn_operand_matches (icode, 2, op1))
3015 550980 : || (IN_RANGE (INTVAL (op1),
3016 : GET_MODE_UNIT_PRECISION (mode) / 2 + left,
3017 : GET_MODE_UNIT_PRECISION (mode) - 1)))
3018 15469 : return (insn_operand_matches (re_icode, 2, op1));
3019 : return false;
3020 : }
3021 :
3022 : /* Analyse argument X to see if it represents an (ASHIFT X Y) operation
3023 : and return the expression to be shifted in SHIFT_OPND and the shift amount
3024 : in SHIFT_AMNT. This is primarily used to group handling of ASHIFT (X, CST)
3025 : and (PLUS (X, X)) in one place. If the expression is not equivalent to an
3026 : ASHIFT then return FALSE and set SHIFT_OPND and SHIFT_AMNT to NULL. */
3027 :
3028 : static bool
3029 539211702 : extract_ashift_operands_p (rtx x, rtx *shift_opnd, rtx *shift_amnt)
3030 : {
3031 539211702 : if (GET_CODE (x) == ASHIFT)
3032 : {
3033 13711460 : *shift_opnd = XEXP (x, 0);
3034 13711460 : *shift_amnt = XEXP (x, 1);
3035 13711460 : return true;
3036 : }
3037 525500242 : if (GET_CODE (x) == PLUS && rtx_equal_p (XEXP (x, 0), XEXP (x, 1)))
3038 : {
3039 11763 : *shift_opnd = XEXP (x, 0);
3040 11763 : *shift_amnt = CONST1_RTX (GET_MODE (x));
3041 11763 : return true;
3042 : }
3043 525488479 : *shift_opnd = NULL_RTX;
3044 525488479 : *shift_amnt = NULL_RTX;
3045 525488479 : return false;
3046 : }
3047 :
3048 : /* OP0 and OP1 are combined under an operation of mode MODE that can
3049 : potentially result in a ROTATE expression. Analyze the OP0 and OP1
3050 : and return the resulting ROTATE expression if so. Return NULL otherwise.
3051 : This is used in detecting the patterns (X << C1) [+,|,^] (X >> C2) where
3052 : C1 + C2 == GET_MODE_UNIT_PRECISION (mode).
3053 : (X << C1) and (C >> C2) would be OP0 and OP1. */
3054 :
3055 : static rtx
3056 272462157 : simplify_rotate_op (rtx op0, rtx op1, machine_mode mode)
3057 : {
3058 : /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3059 : mode size to (rotate A CX). */
3060 :
3061 272462157 : rtx opleft = op0;
3062 272462157 : rtx opright = op1;
3063 272462157 : rtx ashift_opnd, ashift_amnt;
3064 : /* In some cases the ASHIFT is not a direct ASHIFT. Look deeper and extract
3065 : the relevant operands here. */
3066 272462157 : bool ashift_op_p
3067 272462157 : = extract_ashift_operands_p (op1, &ashift_opnd, &ashift_amnt);
3068 :
3069 272462157 : if (ashift_op_p
3070 270735830 : || GET_CODE (op1) == SUBREG)
3071 : {
3072 : opleft = op1;
3073 : opright = op0;
3074 : }
3075 : else
3076 : {
3077 266749545 : opright = op1;
3078 266749545 : opleft = op0;
3079 266749545 : ashift_op_p
3080 266749545 : = extract_ashift_operands_p (opleft, &ashift_opnd, &ashift_amnt);
3081 : }
3082 :
3083 13723223 : if (ashift_op_p && GET_CODE (opright) == LSHIFTRT
3084 270788530 : && rtx_equal_p (ashift_opnd, XEXP (opright, 0)))
3085 : {
3086 9436 : rtx leftcst = unwrap_const_vec_duplicate (ashift_amnt);
3087 9436 : rtx rightcst = unwrap_const_vec_duplicate (XEXP (opright, 1));
3088 :
3089 5624 : if (CONST_INT_P (leftcst) && CONST_INT_P (rightcst)
3090 15060 : && (INTVAL (leftcst) + INTVAL (rightcst)
3091 5624 : == GET_MODE_UNIT_PRECISION (mode)))
3092 5095 : return gen_rtx_ROTATE (mode, XEXP (opright, 0), ashift_amnt);
3093 : }
3094 :
3095 : /* Same, but for ashift that has been "simplified" to a wider mode
3096 : by simplify_shift_const. */
3097 272457062 : scalar_int_mode int_mode, inner_mode;
3098 :
3099 272457062 : if (GET_CODE (opleft) == SUBREG
3100 278053885 : && is_a <scalar_int_mode> (mode, &int_mode)
3101 5591728 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (opleft)),
3102 : &inner_mode)
3103 5552731 : && GET_CODE (SUBREG_REG (opleft)) == ASHIFT
3104 189589 : && GET_CODE (opright) == LSHIFTRT
3105 886 : && GET_CODE (XEXP (opright, 0)) == SUBREG
3106 234 : && known_eq (SUBREG_BYTE (opleft), SUBREG_BYTE (XEXP (opright, 0)))
3107 464 : && GET_MODE_SIZE (int_mode) < GET_MODE_SIZE (inner_mode)
3108 225 : && rtx_equal_p (XEXP (SUBREG_REG (opleft), 0),
3109 225 : SUBREG_REG (XEXP (opright, 0)))
3110 9 : && CONST_INT_P (XEXP (SUBREG_REG (opleft), 1))
3111 9 : && CONST_INT_P (XEXP (opright, 1))
3112 272457062 : && (INTVAL (XEXP (SUBREG_REG (opleft), 1))
3113 9 : + INTVAL (XEXP (opright, 1))
3114 9 : == GET_MODE_PRECISION (int_mode)))
3115 1 : return gen_rtx_ROTATE (int_mode, XEXP (opright, 0),
3116 : XEXP (SUBREG_REG (opleft), 1));
3117 : return NULL_RTX;
3118 : }
3119 :
3120 : /* Returns true if OP0 and OP1 match the pattern (OP (plus (A - 1)) (neg A)),
3121 : and the pattern can be simplified (there are no side effects). */
3122 :
3123 : static bool
3124 40025489 : match_plus_neg_pattern (rtx op0, rtx op1, machine_mode mode)
3125 : {
3126 : /* Remove SUBREG from OP0 and OP1, if needed. */
3127 40025489 : if (GET_CODE (op0) == SUBREG
3128 7202425 : && GET_CODE (op1) == SUBREG
3129 299999 : && subreg_lowpart_p (op0)
3130 40324827 : && subreg_lowpart_p (op1))
3131 : {
3132 299329 : op0 = XEXP (op0, 0);
3133 299329 : op1 = XEXP (op1, 0);
3134 : }
3135 :
3136 : /* Check for the pattern (OP (plus (A - 1)) (neg A)). */
3137 40025489 : if (((GET_CODE (op1) == NEG
3138 4011 : && GET_CODE (op0) == PLUS
3139 2131 : && XEXP (op0, 1) == CONSTM1_RTX (mode))
3140 40024806 : || (GET_CODE (op0) == NEG
3141 77877 : && GET_CODE (op1) == PLUS
3142 0 : && XEXP (op1, 1) == CONSTM1_RTX (mode)))
3143 683 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3144 40025491 : && !side_effects_p (XEXP (op0, 0)))
3145 2 : return true;
3146 : return false;
3147 : }
3148 :
3149 : /* Check if OP matches the pattern of (subreg (not X)) and the subreg is
3150 : non-paradoxical. */
3151 :
3152 : static bool
3153 75863994 : non_paradoxical_subreg_not_p (rtx op)
3154 : {
3155 75863994 : return GET_CODE (op) == SUBREG
3156 8753788 : && !paradoxical_subreg_p (op)
3157 78689863 : && GET_CODE (SUBREG_REG (op)) == NOT;
3158 : }
3159 :
3160 : /* Convert (binop (subreg (not X)) Y) into (binop (not (subreg X)) Y), or
3161 : (binop X (subreg (not Y))) into (binop X (not (subreg Y))) to expose
3162 : opportunities to combine another binary logical operation with NOT. */
3163 :
3164 : static rtx
3165 37933251 : simplify_with_subreg_not (rtx_code binop, machine_mode mode, rtx op0, rtx op1)
3166 : {
3167 37933251 : rtx opn = NULL_RTX;
3168 37933251 : if (non_paradoxical_subreg_not_p (op0))
3169 : opn = op0;
3170 37930743 : else if (non_paradoxical_subreg_not_p (op1))
3171 : opn = op1;
3172 :
3173 2531 : if (opn == NULL_RTX)
3174 : return NULL_RTX;
3175 :
3176 5062 : rtx new_subreg = simplify_gen_subreg (mode,
3177 : XEXP (SUBREG_REG (opn), 0),
3178 2531 : GET_MODE (SUBREG_REG (opn)),
3179 2531 : SUBREG_BYTE (opn));
3180 :
3181 2531 : if (!new_subreg)
3182 : return NULL_RTX;
3183 :
3184 2479 : rtx new_not = simplify_gen_unary (NOT, mode, new_subreg, mode);
3185 2479 : if (opn == op0)
3186 2456 : return simplify_gen_binary (binop, mode, new_not, op1);
3187 : else
3188 23 : return simplify_gen_binary (binop, mode, op0, new_not);
3189 : }
3190 :
3191 : /* Return TRUE iff NOP is a negated form of OP, or vice-versa. */
3192 : static bool
3193 6887188 : negated_ops_p (rtx nop, rtx op)
3194 : {
3195 : /* Explicit negation. */
3196 6887188 : if (GET_CODE (nop) == NOT
3197 6887188 : && rtx_equal_p (XEXP (nop, 0), op))
3198 : return true;
3199 6883844 : if (GET_CODE (op) == NOT
3200 6883844 : && rtx_equal_p (XEXP (op, 0), nop))
3201 : return true;
3202 :
3203 : /* (~C <r A) is a negated form of (C << A) if C == 1. */
3204 6880739 : if (GET_CODE (op) == ASHIFT
3205 1461088 : && GET_CODE (nop) == ROTATE
3206 0 : && XEXP (op, 0) == CONST1_RTX (GET_MODE (op))
3207 0 : && CONST_INT_P (XEXP (nop, 0))
3208 0 : && INTVAL (XEXP (nop, 0)) == -2
3209 6880739 : && rtx_equal_p (XEXP (op, 1), XEXP (nop, 1)))
3210 : return true;
3211 6880739 : if (GET_CODE (nop) == ASHIFT
3212 153295 : && GET_CODE (op) == ROTATE
3213 0 : && XEXP (nop, 0) == CONST1_RTX (GET_MODE (op))
3214 0 : && CONST_INT_P (XEXP (nop, 0))
3215 0 : && INTVAL (XEXP (nop, 0)) == -2
3216 6880739 : && rtx_equal_p (XEXP (op, 1), XEXP (nop, 1)))
3217 : return true;
3218 :
3219 : /* ??? Should we consider rotations of C and ~C by the same amount? */
3220 :
3221 : return false;
3222 : }
3223 :
3224 : /* Subroutine of simplify_binary_operation. Simplify a binary operation
3225 : CODE with result mode MODE, operating on OP0 and OP1. If OP0 and/or
3226 : OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the
3227 : actual constants. */
3228 :
3229 : rtx
3230 459953007 : simplify_context::simplify_binary_operation_1 (rtx_code code,
3231 : machine_mode mode,
3232 : rtx op0, rtx op1,
3233 : rtx trueop0, rtx trueop1)
3234 : {
3235 459953007 : rtx tem, reversed, elt0, elt1;
3236 459953007 : HOST_WIDE_INT val;
3237 459953007 : scalar_int_mode int_mode, inner_mode;
3238 459953007 : poly_int64 offset;
3239 :
3240 : /* Even if we can't compute a constant result,
3241 : there are some cases worth simplifying. */
3242 :
3243 459953007 : switch (code)
3244 : {
3245 261877179 : case PLUS:
3246 : /* Maybe simplify x + 0 to x. The two expressions are equivalent
3247 : when x is NaN, infinite, or finite and nonzero. They aren't
3248 : when x is -0 and the rounding mode is not towards -infinity,
3249 : since (-0) + 0 is then 0. */
3250 519863551 : if (!HONOR_SIGNED_ZEROS (mode) && !HONOR_SNANS (mode)
3251 519863539 : && trueop1 == CONST0_RTX (mode))
3252 : return op0;
3253 :
3254 : /* ((-a) + b) -> (b - a) and similarly for (a + (-b)). These
3255 : transformations are safe even for IEEE. */
3256 260313490 : if (GET_CODE (op0) == NEG)
3257 63997 : return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
3258 260249493 : else if (GET_CODE (op1) == NEG)
3259 8499 : return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
3260 :
3261 : /* (~a) + 1 -> -a */
3262 260240994 : if (INTEGRAL_MODE_P (mode)
3263 255439970 : && GET_CODE (op0) == NOT
3264 1375678 : && trueop1 == const1_rtx)
3265 3856 : return simplify_gen_unary (NEG, mode, XEXP (op0, 0), mode);
3266 :
3267 : /* Handle both-operands-constant cases. We can only add
3268 : CONST_INTs to constants since the sum of relocatable symbols
3269 : can't be handled by most assemblers. Don't add CONST_INT
3270 : to CONST_INT since overflow won't be computed properly if wider
3271 : than HOST_BITS_PER_WIDE_INT. */
3272 :
3273 260237138 : if ((GET_CODE (op0) == CONST
3274 260237138 : || GET_CODE (op0) == SYMBOL_REF
3275 257630270 : || GET_CODE (op0) == LABEL_REF)
3276 260237138 : && poly_int_rtx_p (op1, &offset))
3277 2605906 : return plus_constant (mode, op0, offset);
3278 257631232 : else if ((GET_CODE (op1) == CONST
3279 257631232 : || GET_CODE (op1) == SYMBOL_REF
3280 253449619 : || GET_CODE (op1) == LABEL_REF)
3281 257631232 : && poly_int_rtx_p (op0, &offset))
3282 0 : return plus_constant (mode, op1, offset);
3283 :
3284 : /* See if this is something like X * C - X or vice versa or
3285 : if the multiplication is written as a shift. If so, we can
3286 : distribute and make a new multiply, shift, or maybe just
3287 : have X (if C is 2 in the example above). But don't make
3288 : something more expensive than we had before. */
3289 :
3290 257631232 : if (is_a <scalar_int_mode> (mode, &int_mode))
3291 : {
3292 250594353 : rtx lhs = op0, rhs = op1;
3293 :
3294 250594353 : wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
3295 250594353 : wide_int coeff1 = wi::one (GET_MODE_PRECISION (int_mode));
3296 :
3297 250594353 : if (GET_CODE (lhs) == NEG)
3298 : {
3299 0 : coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3300 0 : lhs = XEXP (lhs, 0);
3301 : }
3302 250594353 : else if (GET_CODE (lhs) == MULT
3303 9565222 : && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
3304 : {
3305 8247632 : coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
3306 8247632 : lhs = XEXP (lhs, 0);
3307 : }
3308 242346721 : else if (GET_CODE (lhs) == ASHIFT
3309 10886547 : && CONST_INT_P (XEXP (lhs, 1))
3310 10813798 : && INTVAL (XEXP (lhs, 1)) >= 0
3311 253160507 : && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
3312 : {
3313 10813786 : coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
3314 21627572 : GET_MODE_PRECISION (int_mode));
3315 10813786 : lhs = XEXP (lhs, 0);
3316 : }
3317 :
3318 250594353 : if (GET_CODE (rhs) == NEG)
3319 : {
3320 0 : coeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3321 0 : rhs = XEXP (rhs, 0);
3322 : }
3323 250594353 : else if (GET_CODE (rhs) == MULT
3324 355749 : && CONST_INT_P (XEXP (rhs, 1)))
3325 : {
3326 199376 : coeff1 = rtx_mode_t (XEXP (rhs, 1), int_mode);
3327 199376 : rhs = XEXP (rhs, 0);
3328 : }
3329 250394977 : else if (GET_CODE (rhs) == ASHIFT
3330 593931 : && CONST_INT_P (XEXP (rhs, 1))
3331 584119 : && INTVAL (XEXP (rhs, 1)) >= 0
3332 250979096 : && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
3333 : {
3334 584119 : coeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
3335 1168238 : GET_MODE_PRECISION (int_mode));
3336 584119 : rhs = XEXP (rhs, 0);
3337 : }
3338 :
3339 : /* Keep PLUS of 2 volatile memory references. */
3340 250594353 : if (rtx_equal_p (lhs, rhs)
3341 250594353 : && (!MEM_P (lhs) || !MEM_VOLATILE_P (lhs)))
3342 : {
3343 834237 : rtx orig = gen_rtx_PLUS (int_mode, op0, op1);
3344 834237 : rtx coeff;
3345 834237 : bool speed = optimize_function_for_speed_p (cfun);
3346 :
3347 834237 : coeff = immed_wide_int_const (coeff0 + coeff1, int_mode);
3348 :
3349 834237 : tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
3350 834237 : return (set_src_cost (tem, int_mode, speed)
3351 834237 : <= set_src_cost (orig, int_mode, speed) ? tem : 0);
3352 : }
3353 :
3354 : /* Optimize (X - 1) * Y + Y to X * Y. */
3355 249760116 : lhs = op0;
3356 249760116 : rhs = op1;
3357 249760116 : if (GET_CODE (op0) == MULT)
3358 : {
3359 9513745 : if (((GET_CODE (XEXP (op0, 0)) == PLUS
3360 626532 : && XEXP (XEXP (op0, 0), 1) == constm1_rtx)
3361 9460245 : || (GET_CODE (XEXP (op0, 0)) == MINUS
3362 51783 : && XEXP (XEXP (op0, 0), 1) == const1_rtx))
3363 9567245 : && rtx_equal_p (XEXP (op0, 1), op1))
3364 84 : lhs = XEXP (XEXP (op0, 0), 0);
3365 9513661 : else if (((GET_CODE (XEXP (op0, 1)) == PLUS
3366 1768 : && XEXP (XEXP (op0, 1), 1) == constm1_rtx)
3367 9513603 : || (GET_CODE (XEXP (op0, 1)) == MINUS
3368 366 : && XEXP (XEXP (op0, 1), 1) == const1_rtx))
3369 9513719 : && rtx_equal_p (XEXP (op0, 0), op1))
3370 0 : lhs = XEXP (XEXP (op0, 1), 0);
3371 : }
3372 240246371 : else if (GET_CODE (op1) == MULT)
3373 : {
3374 128454 : if (((GET_CODE (XEXP (op1, 0)) == PLUS
3375 91 : && XEXP (XEXP (op1, 0), 1) == constm1_rtx)
3376 128450 : || (GET_CODE (XEXP (op1, 0)) == MINUS
3377 23 : && XEXP (XEXP (op1, 0), 1) == const1_rtx))
3378 128458 : && rtx_equal_p (XEXP (op1, 1), op0))
3379 0 : rhs = XEXP (XEXP (op1, 0), 0);
3380 128454 : else if (((GET_CODE (XEXP (op1, 1)) == PLUS
3381 45 : && XEXP (XEXP (op1, 1), 1) == constm1_rtx)
3382 128454 : || (GET_CODE (XEXP (op1, 1)) == MINUS
3383 0 : && XEXP (XEXP (op1, 1), 1) == const1_rtx))
3384 128454 : && rtx_equal_p (XEXP (op1, 0), op0))
3385 0 : rhs = XEXP (XEXP (op1, 1), 0);
3386 : }
3387 249760116 : if (lhs != op0 || rhs != op1)
3388 84 : return simplify_gen_binary (MULT, int_mode, lhs, rhs);
3389 250594353 : }
3390 :
3391 : /* (plus (xor X C1) C2) is (xor X (C1^C2)) if C2 is signbit. */
3392 256796911 : if (CONST_SCALAR_INT_P (op1)
3393 196361591 : && GET_CODE (op0) == XOR
3394 18134 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
3395 256806402 : && mode_signbit_p (mode, op1))
3396 121 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3397 : simplify_gen_binary (XOR, mode, op1,
3398 121 : XEXP (op0, 1)));
3399 :
3400 : /* (plus (xor X C1) C2) is (xor X (C1^C2)) if X is either 0 or 1 and
3401 : 2 * ((X ^ C1) & C2) == 0; based on A + B == A ^ B + 2 * (A & B). */
3402 256796790 : if (CONST_SCALAR_INT_P (op1)
3403 196361470 : && GET_CODE (op0) == XOR
3404 18013 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
3405 9370 : && nonzero_bits (XEXP (op0, 0), mode) == 1
3406 349 : && 2 * (INTVAL (XEXP (op0, 1)) & INTVAL (op1)) == 0
3407 256796790 : && 2 * ((1 ^ INTVAL (XEXP (op0, 1))) & INTVAL (op1)) == 0)
3408 0 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3409 : simplify_gen_binary (XOR, mode, op1,
3410 0 : XEXP (op0, 1)));
3411 :
3412 : /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)). */
3413 256796790 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3414 256794262 : && GET_CODE (op0) == MULT
3415 266680196 : && GET_CODE (XEXP (op0, 0)) == NEG)
3416 : {
3417 4258 : rtx in1, in2;
3418 :
3419 4258 : in1 = XEXP (XEXP (op0, 0), 0);
3420 4258 : in2 = XEXP (op0, 1);
3421 4258 : return simplify_gen_binary (MINUS, mode, op1,
3422 : simplify_gen_binary (MULT, mode,
3423 4258 : in1, in2));
3424 : }
3425 :
3426 : /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
3427 : C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
3428 : is 1. */
3429 256792532 : if (COMPARISON_P (op0)
3430 1300173 : && ((STORE_FLAG_VALUE == -1 && trueop1 == const1_rtx)
3431 1300173 : || (STORE_FLAG_VALUE == 1 && trueop1 == constm1_rtx))
3432 256849907 : && (reversed = reversed_comparison (op0, mode)))
3433 57018 : return
3434 57018 : simplify_gen_unary (NEG, mode, reversed, mode);
3435 :
3436 : /* Convert (plus (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3437 : mode size to (rotate A CX). */
3438 256735514 : if ((tem = simplify_rotate_op (op0, op1, mode)))
3439 : return tem;
3440 :
3441 : /* If one of the operands is a PLUS or a MINUS, see if we can
3442 : simplify this by the associative law.
3443 : Don't use the associative law for floating point.
3444 : The inaccuracy makes it nonassociative,
3445 : and subtle programs can break if operations are associated. */
3446 :
3447 256734039 : if (INTEGRAL_MODE_P (mode)
3448 251933064 : && (plus_minus_operand_p (op0)
3449 217737427 : || plus_minus_operand_p (op1))
3450 35199766 : && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
3451 : return tem;
3452 :
3453 : /* Reassociate floating point addition only when the user
3454 : specifies associative math operations. */
3455 222172767 : if (FLOAT_MODE_P (mode)
3456 4800975 : && flag_associative_math)
3457 : {
3458 910085 : tem = simplify_associative_operation (code, mode, op0, op1);
3459 910085 : if (tem)
3460 : return tem;
3461 : }
3462 :
3463 : /* Handle vector series. */
3464 222159056 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3465 : {
3466 2065002 : tem = simplify_binary_operation_series (code, mode, op0, op1);
3467 2065002 : if (tem)
3468 : return tem;
3469 : }
3470 : break;
3471 :
3472 : case COMPARE:
3473 : break;
3474 :
3475 45359334 : case MINUS:
3476 : /* We can't assume x-x is 0 even with non-IEEE floating point,
3477 : but since it is zero except in very strange circumstances, we
3478 : will treat it as zero with -ffinite-math-only. */
3479 45359334 : if (rtx_equal_p (trueop0, trueop1)
3480 211641 : && ! side_effects_p (op0)
3481 45570550 : && (!FLOAT_MODE_P (mode) || !HONOR_NANS (mode)))
3482 208475 : return CONST0_RTX (mode);
3483 :
3484 : /* Change subtraction from zero into negation. (0 - x) is the
3485 : same as -x when x is NaN, infinite, or finite and nonzero.
3486 : But if the mode has signed zeros, and does not round towards
3487 : -infinity, then 0 - 0 is 0, not -0. */
3488 45150859 : if (!HONOR_SIGNED_ZEROS (mode) && trueop0 == CONST0_RTX (mode))
3489 354001 : return simplify_gen_unary (NEG, mode, op1, mode);
3490 :
3491 : /* (-1 - a) is ~a, unless the expression contains symbolic
3492 : constants, in which case not retaining additions and
3493 : subtractions could cause invalid assembly to be produced. */
3494 44796858 : if (trueop0 == CONSTM1_RTX (mode)
3495 44796858 : && !contains_symbolic_reference_p (op1))
3496 615252 : return simplify_gen_unary (NOT, mode, op1, mode);
3497 :
3498 : /* Subtracting 0 has no effect unless the mode has signalling NaNs,
3499 : or has signed zeros and supports rounding towards -infinity.
3500 : In such a case, 0 - 0 is -0. */
3501 44921602 : if (!(HONOR_SIGNED_ZEROS (mode)
3502 739996 : && HONOR_SIGN_DEPENDENT_ROUNDING (mode))
3503 44180456 : && !HONOR_SNANS (mode)
3504 88362026 : && trueop1 == CONST0_RTX (mode))
3505 : return op0;
3506 :
3507 : /* See if this is something like X * C - X or vice versa or
3508 : if the multiplication is written as a shift. If so, we can
3509 : distribute and make a new multiply, shift, or maybe just
3510 : have X (if C is 2 in the example above). But don't make
3511 : something more expensive than we had before. */
3512 :
3513 43246068 : if (is_a <scalar_int_mode> (mode, &int_mode))
3514 : {
3515 41853700 : rtx lhs = op0, rhs = op1;
3516 :
3517 41853700 : wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
3518 41853700 : wide_int negcoeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3519 :
3520 41853700 : if (GET_CODE (lhs) == NEG)
3521 : {
3522 72735 : coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3523 72735 : lhs = XEXP (lhs, 0);
3524 : }
3525 41780965 : else if (GET_CODE (lhs) == MULT
3526 230157 : && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
3527 : {
3528 78779 : coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
3529 78779 : lhs = XEXP (lhs, 0);
3530 : }
3531 41702186 : else if (GET_CODE (lhs) == ASHIFT
3532 306018 : && CONST_INT_P (XEXP (lhs, 1))
3533 302728 : && INTVAL (XEXP (lhs, 1)) >= 0
3534 42004893 : && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
3535 : {
3536 302707 : coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
3537 605414 : GET_MODE_PRECISION (int_mode));
3538 302707 : lhs = XEXP (lhs, 0);
3539 : }
3540 :
3541 41853700 : if (GET_CODE (rhs) == NEG)
3542 : {
3543 12971 : negcoeff1 = wi::one (GET_MODE_PRECISION (int_mode));
3544 12971 : rhs = XEXP (rhs, 0);
3545 : }
3546 41840729 : else if (GET_CODE (rhs) == MULT
3547 130187 : && CONST_INT_P (XEXP (rhs, 1)))
3548 : {
3549 91788 : negcoeff1 = wi::neg (rtx_mode_t (XEXP (rhs, 1), int_mode));
3550 91788 : rhs = XEXP (rhs, 0);
3551 : }
3552 41748941 : else if (GET_CODE (rhs) == ASHIFT
3553 410019 : && CONST_INT_P (XEXP (rhs, 1))
3554 409473 : && INTVAL (XEXP (rhs, 1)) >= 0
3555 42158414 : && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
3556 : {
3557 409473 : negcoeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
3558 818946 : GET_MODE_PRECISION (int_mode));
3559 409473 : negcoeff1 = -negcoeff1;
3560 409473 : rhs = XEXP (rhs, 0);
3561 : }
3562 :
3563 41853700 : if (rtx_equal_p (lhs, rhs))
3564 : {
3565 92239 : rtx orig = gen_rtx_MINUS (int_mode, op0, op1);
3566 92239 : rtx coeff;
3567 92239 : bool speed = optimize_function_for_speed_p (cfun);
3568 :
3569 92239 : coeff = immed_wide_int_const (coeff0 + negcoeff1, int_mode);
3570 :
3571 92239 : tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
3572 92239 : return (set_src_cost (tem, int_mode, speed)
3573 92239 : <= set_src_cost (orig, int_mode, speed) ? tem : 0);
3574 : }
3575 :
3576 : /* Optimize (X + 1) * Y - Y to X * Y. */
3577 41761461 : lhs = op0;
3578 41761461 : if (GET_CODE (op0) == MULT)
3579 : {
3580 229677 : if (((GET_CODE (XEXP (op0, 0)) == PLUS
3581 4939 : && XEXP (XEXP (op0, 0), 1) == const1_rtx)
3582 227999 : || (GET_CODE (XEXP (op0, 0)) == MINUS
3583 1669 : && XEXP (XEXP (op0, 0), 1) == constm1_rtx))
3584 231355 : && rtx_equal_p (XEXP (op0, 1), op1))
3585 2 : lhs = XEXP (XEXP (op0, 0), 0);
3586 229675 : else if (((GET_CODE (XEXP (op0, 1)) == PLUS
3587 30 : && XEXP (XEXP (op0, 1), 1) == const1_rtx)
3588 229663 : || (GET_CODE (XEXP (op0, 1)) == MINUS
3589 84 : && XEXP (XEXP (op0, 1), 1) == constm1_rtx))
3590 229687 : && rtx_equal_p (XEXP (op0, 0), op1))
3591 0 : lhs = XEXP (XEXP (op0, 1), 0);
3592 : }
3593 41761461 : if (lhs != op0)
3594 2 : return simplify_gen_binary (MULT, int_mode, lhs, op1);
3595 41853700 : }
3596 :
3597 : /* (a - (-b)) -> (a + b). True even for IEEE. */
3598 43153827 : if (GET_CODE (op1) == NEG)
3599 12917 : return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
3600 :
3601 : /* (-x - c) may be simplified as (-c - x). */
3602 43140910 : if (GET_CODE (op0) == NEG
3603 76874 : && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1)))
3604 : {
3605 698 : tem = simplify_unary_operation (NEG, mode, op1, mode);
3606 698 : if (tem)
3607 698 : return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
3608 : }
3609 :
3610 43140212 : if ((GET_CODE (op0) == CONST
3611 43140212 : || GET_CODE (op0) == SYMBOL_REF
3612 37616565 : || GET_CODE (op0) == LABEL_REF)
3613 43140212 : && poly_int_rtx_p (op1, &offset))
3614 54564 : return plus_constant (mode, op0, trunc_int_for_mode (-offset, mode));
3615 :
3616 : /* Don't let a relocatable value get a negative coeff. */
3617 43085648 : if (is_a <scalar_int_mode> (mode)
3618 41693311 : && poly_int_rtx_p (op1)
3619 50317579 : && GET_MODE (op0) != VOIDmode)
3620 7231931 : return simplify_gen_binary (PLUS, mode,
3621 : op0,
3622 7231931 : neg_poly_int_rtx (mode, op1));
3623 :
3624 : /* (x - (x & y)) -> (x & ~y) */
3625 35853717 : if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND)
3626 : {
3627 253664 : if (rtx_equal_p (op0, XEXP (op1, 0)))
3628 : {
3629 492 : tem = simplify_gen_unary (NOT, mode, XEXP (op1, 1),
3630 246 : GET_MODE (XEXP (op1, 1)));
3631 246 : return simplify_gen_binary (AND, mode, op0, tem);
3632 : }
3633 253418 : if (rtx_equal_p (op0, XEXP (op1, 1)))
3634 : {
3635 2388 : tem = simplify_gen_unary (NOT, mode, XEXP (op1, 0),
3636 1194 : GET_MODE (XEXP (op1, 0)));
3637 1194 : return simplify_gen_binary (AND, mode, op0, tem);
3638 : }
3639 : }
3640 :
3641 : /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
3642 : by reversing the comparison code if valid. */
3643 35852277 : if (STORE_FLAG_VALUE == 1
3644 35852277 : && trueop0 == const1_rtx
3645 1192168 : && COMPARISON_P (op1)
3646 35956744 : && (reversed = reversed_comparison (op1, mode)))
3647 : return reversed;
3648 :
3649 : /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A). */
3650 35747815 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3651 35746464 : && GET_CODE (op1) == MULT
3652 35978611 : && GET_CODE (XEXP (op1, 0)) == NEG)
3653 : {
3654 173 : rtx in1, in2;
3655 :
3656 173 : in1 = XEXP (XEXP (op1, 0), 0);
3657 173 : in2 = XEXP (op1, 1);
3658 173 : return simplify_gen_binary (PLUS, mode,
3659 : simplify_gen_binary (MULT, mode,
3660 : in1, in2),
3661 173 : op0);
3662 : }
3663 :
3664 : /* Canonicalize (minus (neg A) (mult B C)) to
3665 : (minus (mult (neg B) C) A). */
3666 35747642 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3667 35746291 : && GET_CODE (op1) == MULT
3668 35978265 : && GET_CODE (op0) == NEG)
3669 : {
3670 683 : rtx in1, in2;
3671 :
3672 683 : in1 = simplify_gen_unary (NEG, mode, XEXP (op1, 0), mode);
3673 683 : in2 = XEXP (op1, 1);
3674 683 : return simplify_gen_binary (MINUS, mode,
3675 : simplify_gen_binary (MULT, mode,
3676 : in1, in2),
3677 683 : XEXP (op0, 0));
3678 : }
3679 :
3680 : /* If one of the operands is a PLUS or a MINUS, see if we can
3681 : simplify this by the associative law. This will, for example,
3682 : canonicalize (minus A (plus B C)) to (minus (minus A B) C).
3683 : Don't use the associative law for floating point.
3684 : The inaccuracy makes it nonassociative,
3685 : and subtle programs can break if operations are associated. */
3686 :
3687 35746959 : if (INTEGRAL_MODE_P (mode)
3688 34885472 : && (plus_minus_operand_p (op0)
3689 31980455 : || plus_minus_operand_p (op1))
3690 4140595 : && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
3691 : return tem;
3692 :
3693 : /* Handle vector series. */
3694 31756532 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3695 : {
3696 506618 : tem = simplify_binary_operation_series (code, mode, op0, op1);
3697 506618 : if (tem)
3698 : return tem;
3699 : }
3700 : break;
3701 :
3702 12811875 : case MULT:
3703 12811875 : if (trueop1 == constm1_rtx)
3704 35000 : return simplify_gen_unary (NEG, mode, op0, mode);
3705 :
3706 12776875 : if (GET_CODE (op0) == NEG)
3707 : {
3708 38308 : rtx temp = simplify_unary_operation (NEG, mode, op1, mode);
3709 : /* If op1 is a MULT as well and simplify_unary_operation
3710 : just moved the NEG to the second operand, simplify_gen_binary
3711 : below could through simplify_associative_operation move
3712 : the NEG around again and recurse endlessly. */
3713 38308 : if (temp
3714 1861 : && GET_CODE (op1) == MULT
3715 0 : && GET_CODE (temp) == MULT
3716 0 : && XEXP (op1, 0) == XEXP (temp, 0)
3717 0 : && GET_CODE (XEXP (temp, 1)) == NEG
3718 0 : && XEXP (op1, 1) == XEXP (XEXP (temp, 1), 0))
3719 : temp = NULL_RTX;
3720 : if (temp)
3721 1861 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp);
3722 : }
3723 12775014 : if (GET_CODE (op1) == NEG)
3724 : {
3725 976 : rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
3726 : /* If op0 is a MULT as well and simplify_unary_operation
3727 : just moved the NEG to the second operand, simplify_gen_binary
3728 : below could through simplify_associative_operation move
3729 : the NEG around again and recurse endlessly. */
3730 976 : if (temp
3731 399 : && GET_CODE (op0) == MULT
3732 296 : && GET_CODE (temp) == MULT
3733 296 : && XEXP (op0, 0) == XEXP (temp, 0)
3734 6 : && GET_CODE (XEXP (temp, 1)) == NEG
3735 5 : && XEXP (op0, 1) == XEXP (XEXP (temp, 1), 0))
3736 : temp = NULL_RTX;
3737 : if (temp)
3738 394 : return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
3739 : }
3740 :
3741 : /* Maybe simplify x * 0 to 0. The reduction is not valid if
3742 : x is NaN, since x * 0 is then also NaN. Nor is it valid
3743 : when the mode has signed zeros, since multiplying a negative
3744 : number by 0 will give -0, not 0. */
3745 12774620 : if (!HONOR_NANS (mode)
3746 11787743 : && !HONOR_SIGNED_ZEROS (mode)
3747 11787327 : && trueop1 == CONST0_RTX (mode)
3748 12822177 : && ! side_effects_p (op0))
3749 : return op1;
3750 :
3751 : /* In IEEE floating point, x*1 is not equivalent to x for
3752 : signalling NaNs. */
3753 12727490 : if (!HONOR_SNANS (mode)
3754 12727490 : && trueop1 == CONST1_RTX (mode))
3755 : return op0;
3756 :
3757 : /* Convert multiply by constant power of two into shift. */
3758 12187221 : if (mem_depth == 0 && CONST_SCALAR_INT_P (trueop1))
3759 : {
3760 6240256 : val = wi::exact_log2 (rtx_mode_t (trueop1, mode));
3761 6240256 : if (val >= 0)
3762 2941985 : return simplify_gen_binary (ASHIFT, mode, op0,
3763 2941985 : gen_int_shift_amount (mode, val));
3764 : }
3765 :
3766 : /* x*2 is x+x and x*(-1) is -x */
3767 9245236 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
3768 172487 : && SCALAR_FLOAT_MODE_P (GET_MODE (trueop1))
3769 172487 : && !DECIMAL_FLOAT_MODE_P (GET_MODE (trueop1))
3770 172203 : && GET_MODE (op0) == mode)
3771 : {
3772 172203 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
3773 :
3774 172203 : if (real_equal (d1, &dconst2))
3775 682 : return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
3776 :
3777 171521 : if (!HONOR_SNANS (mode)
3778 171521 : && real_equal (d1, &dconstm1))
3779 25 : return simplify_gen_unary (NEG, mode, op0, mode);
3780 : }
3781 :
3782 : /* Optimize -x * -x as x * x. */
3783 9244529 : if (FLOAT_MODE_P (mode)
3784 1410197 : && GET_CODE (op0) == NEG
3785 8341 : && GET_CODE (op1) == NEG
3786 0 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3787 0 : && !side_effects_p (XEXP (op0, 0)))
3788 0 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3789 :
3790 : /* Likewise, optimize abs(x) * abs(x) as x * x. */
3791 9244529 : if (SCALAR_FLOAT_MODE_P (mode)
3792 1104482 : && GET_CODE (op0) == ABS
3793 1488 : && GET_CODE (op1) == ABS
3794 1 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3795 9244529 : && !side_effects_p (XEXP (op0, 0)))
3796 0 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3797 :
3798 : /* Reassociate multiplication, but for floating point MULTs
3799 : only when the user specifies unsafe math optimizations. */
3800 9244529 : if (! FLOAT_MODE_P (mode)
3801 1410197 : || flag_unsafe_math_optimizations)
3802 : {
3803 8258763 : tem = simplify_associative_operation (code, mode, op0, op1);
3804 8258763 : if (tem)
3805 : return tem;
3806 : }
3807 : break;
3808 :
3809 15558222 : case IOR:
3810 15558222 : if (trueop1 == CONST0_RTX (mode))
3811 : return op0;
3812 14735374 : if (INTEGRAL_MODE_P (mode)
3813 14458827 : && trueop1 == CONSTM1_RTX (mode)
3814 10125 : && !side_effects_p (op0))
3815 : return op1;
3816 14725249 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
3817 : return op0;
3818 : /* A | (~A) -> -1 */
3819 71531 : if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
3820 14704658 : || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
3821 0 : && ! side_effects_p (op0)
3822 14704658 : && GET_MODE_CLASS (mode) != MODE_CC)
3823 0 : return CONSTM1_RTX (mode);
3824 :
3825 : /* IOR of two single bit bitfields extracted from the same object.
3826 : Bitfields are represented as an AND based extraction */
3827 14704658 : if (GET_CODE (op0) == AND
3828 4197634 : && GET_CODE (op1) == AND
3829 : /* Verify both AND operands are logical right shifts. */
3830 277662 : && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
3831 1770 : && GET_CODE (XEXP (op1, 0)) == LSHIFTRT
3832 : /* Verify both bitfields are extracted from the same object. */
3833 90 : && XEXP (XEXP (op0, 0), 0) == XEXP (XEXP (op1, 0), 0)
3834 : /* Verify both fields are a single bit (could be generalized). */
3835 86 : && XEXP (op0, 1) == CONST1_RTX (mode)
3836 0 : && XEXP (op1, 1) == CONST1_RTX (mode)
3837 : /* Verify bit positions (for cases with variable bit position). */
3838 0 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
3839 0 : && CONST_INT_P (XEXP (XEXP (op1, 0), 1)))
3840 : {
3841 0 : unsigned HOST_WIDE_INT bitpos1 = INTVAL (XEXP (XEXP (op0, 0), 1));
3842 0 : unsigned HOST_WIDE_INT bitpos2 = INTVAL (XEXP (XEXP (op1, 0), 1));
3843 0 : unsigned HOST_WIDE_INT mask
3844 0 : = (HOST_WIDE_INT_1U << bitpos1) | (HOST_WIDE_INT_1U << bitpos2);
3845 :
3846 0 : rtx m = GEN_INT (mask);
3847 0 : rtx t = gen_rtx_AND (mode, XEXP (XEXP (op0, 0), 0), m);
3848 0 : t = gen_rtx_NE (mode, t, CONST0_RTX (mode));
3849 0 : return t;
3850 : }
3851 :
3852 : /* IOR of multiple single bit bitfields extracted from the same object
3853 : (building on previous case).
3854 : First bitfield is represented as an AND based extraction, as done
3855 : above. Second represented as NE based extraction, from
3856 : output above. */
3857 14704658 : if (GET_CODE (op0) == AND
3858 4197634 : && GET_CODE (op1) == NE
3859 : /* Verify AND operand is logical right shift. */
3860 3367 : && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
3861 : /* Verify NE operand is an AND (based on output above). */
3862 86 : && GET_CODE (XEXP (op1, 0)) == AND
3863 : /* Verify both bitfields are extracted from the same object. */
3864 0 : && XEXP (XEXP (op0, 0), 0) == XEXP (XEXP (op1, 0), 0)
3865 : /* Verify masking is with a single bit and that we have a NE 0
3866 : comparison for the other operand. */
3867 0 : && XEXP (op0, 1) == CONST1_RTX (mode)
3868 0 : && XEXP (op1, 1) == CONST0_RTX (mode)
3869 : /* Verify bit position. */
3870 0 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
3871 : {
3872 0 : unsigned HOST_WIDE_INT bitpos1 = INTVAL (XEXP (XEXP (op0, 0), 1));
3873 0 : unsigned HOST_WIDE_INT mask
3874 0 : = (HOST_WIDE_INT_1U << bitpos1) | INTVAL (XEXP (XEXP (op1, 0), 1));
3875 :
3876 0 : rtx m = GEN_INT (mask);
3877 0 : rtx t = gen_rtx_AND (mode, XEXP (XEXP (op0, 0), 0), m);
3878 0 : t = gen_rtx_NE (mode, t, CONST0_RTX (mode));
3879 0 : return t;
3880 : }
3881 :
3882 : /* Convert (ior (plus (A - 1)) (neg A)) to -1. */
3883 14704658 : if (match_plus_neg_pattern (op0, op1, mode))
3884 0 : return CONSTM1_RTX (mode);
3885 :
3886 : /* (ior A C) is C if all bits of A that might be nonzero are on in C. */
3887 14704658 : if (CONST_INT_P (op1)
3888 3760691 : && HWI_COMPUTABLE_MODE_P (mode)
3889 3704271 : && (nonzero_bits (op0, mode) & ~UINTVAL (op1)) == 0
3890 15113911 : && !side_effects_p (op0))
3891 : return op1;
3892 :
3893 : /* Canonicalize (X & C1) | C2. */
3894 14295405 : if (GET_CODE (op0) == AND
3895 4188815 : && CONST_INT_P (trueop1)
3896 738841 : && CONST_INT_P (XEXP (op0, 1)))
3897 : {
3898 523999 : HOST_WIDE_INT mask = GET_MODE_MASK (mode);
3899 523999 : HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
3900 523999 : HOST_WIDE_INT c2 = INTVAL (trueop1);
3901 :
3902 : /* If (C1&C2) == C1, then (X&C1)|C2 becomes C2. */
3903 523999 : if ((c1 & c2) == c1
3904 523999 : && !side_effects_p (XEXP (op0, 0)))
3905 : return trueop1;
3906 :
3907 : /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2. */
3908 523979 : if (((c1|c2) & mask) == mask)
3909 72694 : return simplify_gen_binary (IOR, mode, XEXP (op0, 0), op1);
3910 :
3911 : /* If (C1|C2) has a single bit clear, then adjust C1 so that
3912 : when split it'll match a single bit clear style insn.
3913 :
3914 : This could have been done with a target dependent splitter, but
3915 : then every target with single bit manipulation insns would need
3916 : to implement such splitters. */
3917 451285 : if (exact_log2 (~(c1 | c2)) >= 0)
3918 : {
3919 60439 : rtx temp = gen_rtx_AND (mode, XEXP (op0, 0), GEN_INT (c1 | c2));
3920 60439 : temp = gen_rtx_IOR (mode, temp, trueop1);
3921 60439 : return temp;
3922 : }
3923 : }
3924 :
3925 : /* Convert (A & B) | A to A. */
3926 14162252 : if (GET_CODE (op0) == AND
3927 4055662 : && (rtx_equal_p (XEXP (op0, 0), op1)
3928 4055175 : || rtx_equal_p (XEXP (op0, 1), op1))
3929 3600 : && ! side_effects_p (XEXP (op0, 0))
3930 14165852 : && ! side_effects_p (XEXP (op0, 1)))
3931 : return op1;
3932 :
3933 : /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3934 : mode size to (rotate A CX). */
3935 14158652 : tem = simplify_rotate_op (op0, op1, mode);
3936 14158652 : if (tem)
3937 : return tem;
3938 :
3939 : /* If OP0 is (ashiftrt (plus ...) C), it might actually be
3940 : a (sign_extend (plus ...)). Then check if OP1 is a CONST_INT and
3941 : the PLUS does not affect any of the bits in OP1: then we can do
3942 : the IOR as a PLUS and we can associate. This is valid if OP1
3943 : can be safely shifted left C bits. */
3944 14156411 : if (CONST_INT_P (trueop1) && GET_CODE (op0) == ASHIFTRT
3945 6350 : && GET_CODE (XEXP (op0, 0)) == PLUS
3946 81 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
3947 57 : && CONST_INT_P (XEXP (op0, 1))
3948 57 : && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
3949 : {
3950 57 : int count = INTVAL (XEXP (op0, 1));
3951 57 : HOST_WIDE_INT mask = UINTVAL (trueop1) << count;
3952 :
3953 57 : if (mask >> count == INTVAL (trueop1)
3954 50 : && trunc_int_for_mode (mask, mode) == mask
3955 94 : && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
3956 0 : return simplify_gen_binary (ASHIFTRT, mode,
3957 : plus_constant (mode, XEXP (op0, 0),
3958 0 : mask),
3959 : XEXP (op0, 1));
3960 : }
3961 :
3962 : /* The following happens with bitfield merging.
3963 : (X & C) | ((X | Y) & ~C) -> X | (Y & ~C) */
3964 14156411 : if (GET_CODE (op0) == AND
3965 4052062 : && GET_CODE (op1) == AND
3966 277662 : && CONST_INT_P (XEXP (op0, 1))
3967 121843 : && CONST_INT_P (XEXP (op1, 1))
3968 117366 : && (INTVAL (XEXP (op0, 1))
3969 117366 : == ~INTVAL (XEXP (op1, 1))))
3970 : {
3971 : /* The IOR/XOR may be on both sides. */
3972 33014 : rtx top0 = NULL_RTX, top1 = NULL_RTX;
3973 33014 : if (GET_CODE (XEXP (op1, 0)) == IOR
3974 33014 : || GET_CODE (XEXP (op1, 0)) == XOR)
3975 : top0 = op0, top1 = op1;
3976 32895 : else if (GET_CODE (XEXP (op0, 0)) == IOR
3977 32895 : || GET_CODE (XEXP (op0, 0)) == XOR)
3978 3 : top0 = op1, top1 = op0;
3979 33014 : if (top0 && top1)
3980 : {
3981 : /* X may be on either side of the inner IOR/XOR. */
3982 122 : rtx tem = NULL_RTX;
3983 122 : if (rtx_equal_p (XEXP (top0, 0),
3984 122 : XEXP (XEXP (top1, 0), 0)))
3985 76 : tem = XEXP (XEXP (top1, 0), 1);
3986 46 : else if (rtx_equal_p (XEXP (top0, 0),
3987 46 : XEXP (XEXP (top1, 0), 1)))
3988 13 : tem = XEXP (XEXP (top1, 0), 0);
3989 89 : if (tem)
3990 89 : return simplify_gen_binary (GET_CODE (XEXP (top1, 0)),
3991 : mode, XEXP (top0, 0),
3992 : simplify_gen_binary
3993 89 : (AND, mode, tem, XEXP (top1, 1)));
3994 : }
3995 : }
3996 :
3997 : /* Convert (ior (and A C) (and B C)) into (and (ior A B) C). */
3998 14156322 : if (GET_CODE (op0) == GET_CODE (op1)
3999 3435971 : && (GET_CODE (op0) == AND
4000 : || GET_CODE (op0) == IOR
4001 3435971 : || GET_CODE (op0) == LSHIFTRT
4002 3157442 : || GET_CODE (op0) == ASHIFTRT
4003 3157307 : || GET_CODE (op0) == ASHIFT
4004 3141651 : || GET_CODE (op0) == ROTATE
4005 3141651 : || GET_CODE (op0) == ROTATERT))
4006 : {
4007 294320 : tem = simplify_distributive_operation (code, mode, op0, op1);
4008 294320 : if (tem)
4009 : return tem;
4010 : }
4011 :
4012 : /* Convert (ior (and (not A) B) A) into A | B. */
4013 14074130 : if (GET_CODE (op0) == AND
4014 14074130 : && negated_ops_p (XEXP (op0, 0), op1))
4015 6351 : return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
4016 :
4017 : /* op0/op1 may have a common term which in turn may allow simplification
4018 : of the the outer IOR. There are likely other cases we should
4019 : handle for the outer code as well as the form of the operands. */
4020 14067779 : tem = simplify_ior_with_common_term (mode, op0, op1);
4021 14067779 : if (tem)
4022 : return tem;
4023 :
4024 : /* IOR is commutative and we can't rely on canonicalization at this point,
4025 : so try again to simplify with the operands reversed. */
4026 14067688 : tem = simplify_ior_with_common_term (mode, op1, op0);
4027 14067688 : if (tem)
4028 : return tem;
4029 :
4030 14067688 : tem = simplify_with_subreg_not (code, mode, op0, op1);
4031 14067688 : if (tem)
4032 : return tem;
4033 :
4034 14067683 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
4035 14067683 : if (tem)
4036 : return tem;
4037 :
4038 14067676 : tem = simplify_associative_operation (code, mode, op0, op1);
4039 14067676 : if (tem)
4040 : return tem;
4041 :
4042 13791748 : tem = simplify_logical_relational_operation (code, mode, op0, op1);
4043 13791748 : if (tem)
4044 : return tem;
4045 : break;
4046 :
4047 1853985 : case XOR:
4048 1853985 : if (trueop1 == CONST0_RTX (mode))
4049 : return op0;
4050 1795214 : if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
4051 30929 : return simplify_gen_unary (NOT, mode, op0, mode);
4052 1764285 : if (rtx_equal_p (trueop0, trueop1)
4053 2591 : && ! side_effects_p (op0)
4054 1766872 : && GET_MODE_CLASS (mode) != MODE_CC)
4055 2587 : return CONST0_RTX (mode);
4056 :
4057 : /* Canonicalize XOR of the most significant bit to PLUS. */
4058 1761698 : if (CONST_SCALAR_INT_P (op1)
4059 1761698 : && mode_signbit_p (mode, op1))
4060 40234 : return simplify_gen_binary (PLUS, mode, op0, op1);
4061 : /* (xor (plus X C1) C2) is (xor X (C1^C2)) if C1 is signbit. */
4062 1721464 : if (CONST_SCALAR_INT_P (op1)
4063 495951 : && GET_CODE (op0) == PLUS
4064 2527 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
4065 1722966 : && mode_signbit_p (mode, XEXP (op0, 1)))
4066 189 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
4067 : simplify_gen_binary (XOR, mode, op1,
4068 189 : XEXP (op0, 1)));
4069 :
4070 : /* If we are XORing two things that have no bits in common,
4071 : convert them into an IOR. This helps to detect rotation encoded
4072 : using those methods and possibly other simplifications. */
4073 :
4074 1721275 : if (HWI_COMPUTABLE_MODE_P (mode)
4075 1393322 : && (nonzero_bits (op0, mode)
4076 1393322 : & nonzero_bits (op1, mode)) == 0)
4077 11774 : return (simplify_gen_binary (IOR, mode, op0, op1));
4078 :
4079 : /* Convert (xor (plus (A - 1)) (neg A)) to -1. */
4080 1709501 : if (match_plus_neg_pattern (op0, op1, mode))
4081 0 : return CONSTM1_RTX (mode);
4082 :
4083 : /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
4084 : Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
4085 : (NOT y). */
4086 1709501 : {
4087 1709501 : int num_negated = 0;
4088 :
4089 1709501 : if (GET_CODE (op0) == NOT)
4090 716 : num_negated++, op0 = XEXP (op0, 0);
4091 1709501 : if (GET_CODE (op1) == NOT)
4092 65 : num_negated++, op1 = XEXP (op1, 0);
4093 :
4094 65 : if (num_negated == 2)
4095 0 : return simplify_gen_binary (XOR, mode, op0, op1);
4096 1709501 : else if (num_negated == 1)
4097 781 : return simplify_gen_unary (NOT, mode,
4098 : simplify_gen_binary (XOR, mode, op0, op1),
4099 781 : mode);
4100 : }
4101 :
4102 : /* Convert (xor (and A B) B) to (and (not A) B). The latter may
4103 : correspond to a machine insn or result in further simplifications
4104 : if B is a constant. */
4105 :
4106 1708720 : if (GET_CODE (op0) == AND
4107 193810 : && rtx_equal_p (XEXP (op0, 1), op1)
4108 1731692 : && ! side_effects_p (op1))
4109 22972 : return simplify_gen_binary (AND, mode,
4110 : simplify_gen_unary (NOT, mode,
4111 : XEXP (op0, 0), mode),
4112 22972 : op1);
4113 :
4114 1685748 : else if (GET_CODE (op0) == AND
4115 170838 : && rtx_equal_p (XEXP (op0, 0), op1)
4116 1687845 : && ! side_effects_p (op1))
4117 2097 : return simplify_gen_binary (AND, mode,
4118 : simplify_gen_unary (NOT, mode,
4119 : XEXP (op0, 1), mode),
4120 2097 : op1);
4121 :
4122 : /* Given (xor (ior (xor A B) C) D), where B, C and D are
4123 : constants, simplify to (xor (ior A C) (B&~C)^D), canceling
4124 : out bits inverted twice and not set by C. Similarly, given
4125 : (xor (and (xor A B) C) D), simplify without inverting C in
4126 : the xor operand: (xor (and A C) (B&C)^D).
4127 : */
4128 1683651 : else if ((GET_CODE (op0) == IOR || GET_CODE (op0) == AND)
4129 192700 : && GET_CODE (XEXP (op0, 0)) == XOR
4130 7586 : && CONST_INT_P (op1)
4131 222 : && CONST_INT_P (XEXP (op0, 1))
4132 179 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
4133 : {
4134 38 : enum rtx_code op = GET_CODE (op0);
4135 38 : rtx a = XEXP (XEXP (op0, 0), 0);
4136 38 : rtx b = XEXP (XEXP (op0, 0), 1);
4137 38 : rtx c = XEXP (op0, 1);
4138 38 : rtx d = op1;
4139 38 : HOST_WIDE_INT bval = INTVAL (b);
4140 38 : HOST_WIDE_INT cval = INTVAL (c);
4141 38 : HOST_WIDE_INT dval = INTVAL (d);
4142 38 : HOST_WIDE_INT xcval;
4143 :
4144 38 : if (op == IOR)
4145 8 : xcval = ~cval;
4146 : else
4147 : xcval = cval;
4148 :
4149 38 : return simplify_gen_binary (XOR, mode,
4150 : simplify_gen_binary (op, mode, a, c),
4151 38 : gen_int_mode ((bval & xcval) ^ dval,
4152 : mode));
4153 : }
4154 :
4155 : /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P),
4156 : we can transform like this:
4157 : (A&B)^C == ~(A&B)&C | ~C&(A&B)
4158 : == (~A|~B)&C | ~C&(A&B) * DeMorgan's Law
4159 : == ~A&C | ~B&C | A&(~C&B) * Distribute and re-order
4160 : Attempt a few simplifications when B and C are both constants. */
4161 1683613 : if (GET_CODE (op0) == AND
4162 168711 : && CONST_INT_P (op1)
4163 14595 : && CONST_INT_P (XEXP (op0, 1)))
4164 : {
4165 11576 : rtx a = XEXP (op0, 0);
4166 11576 : rtx b = XEXP (op0, 1);
4167 11576 : rtx c = op1;
4168 11576 : HOST_WIDE_INT bval = INTVAL (b);
4169 11576 : HOST_WIDE_INT cval = INTVAL (c);
4170 :
4171 : /* Instead of computing ~A&C, we compute its negated value,
4172 : ~(A|~C). If it yields -1, ~A&C is zero, so we can
4173 : optimize for sure. If it does not simplify, we still try
4174 : to compute ~A&C below, but since that always allocates
4175 : RTL, we don't try that before committing to returning a
4176 : simplified expression. */
4177 11576 : rtx n_na_c = simplify_binary_operation (IOR, mode, a,
4178 : GEN_INT (~cval));
4179 :
4180 11576 : if ((~cval & bval) == 0)
4181 : {
4182 830 : rtx na_c = NULL_RTX;
4183 830 : if (n_na_c)
4184 0 : na_c = simplify_gen_unary (NOT, mode, n_na_c, mode);
4185 : else
4186 : {
4187 : /* If ~A does not simplify, don't bother: we don't
4188 : want to simplify 2 operations into 3, and if na_c
4189 : were to simplify with na, n_na_c would have
4190 : simplified as well. */
4191 830 : rtx na = simplify_unary_operation (NOT, mode, a, mode);
4192 830 : if (na)
4193 0 : na_c = simplify_gen_binary (AND, mode, na, c);
4194 : }
4195 :
4196 : /* Try to simplify ~A&C | ~B&C. */
4197 0 : if (na_c != NULL_RTX)
4198 0 : return simplify_gen_binary (IOR, mode, na_c,
4199 0 : gen_int_mode (~bval & cval, mode));
4200 : }
4201 : else
4202 : {
4203 : /* If ~A&C is zero, simplify A&(~C&B) | ~B&C. */
4204 10746 : if (n_na_c == CONSTM1_RTX (mode))
4205 : {
4206 0 : rtx a_nc_b = simplify_gen_binary (AND, mode, a,
4207 0 : gen_int_mode (~cval & bval,
4208 : mode));
4209 0 : return simplify_gen_binary (IOR, mode, a_nc_b,
4210 0 : gen_int_mode (~bval & cval,
4211 : mode));
4212 : }
4213 : }
4214 : }
4215 :
4216 : /* If we have (xor (and (xor A B) C) A) with C a constant we can instead
4217 : do (ior (and A ~C) (and B C)) which is a machine instruction on some
4218 : machines, and also has shorter instruction path length. */
4219 1683613 : if (GET_CODE (op0) == AND
4220 168711 : && GET_CODE (XEXP (op0, 0)) == XOR
4221 7098 : && CONST_INT_P (XEXP (op0, 1))
4222 1687435 : && rtx_equal_p (XEXP (XEXP (op0, 0), 0), trueop1))
4223 : {
4224 7 : rtx a = trueop1;
4225 7 : rtx b = XEXP (XEXP (op0, 0), 1);
4226 7 : rtx c = XEXP (op0, 1);
4227 7 : rtx nc = simplify_gen_unary (NOT, mode, c, mode);
4228 7 : rtx a_nc = simplify_gen_binary (AND, mode, a, nc);
4229 7 : rtx bc = simplify_gen_binary (AND, mode, b, c);
4230 7 : return simplify_gen_binary (IOR, mode, a_nc, bc);
4231 : }
4232 : /* Similarly, (xor (and (xor A B) C) B) as (ior (and A C) (and B ~C)) */
4233 1683606 : else if (GET_CODE (op0) == AND
4234 168704 : && GET_CODE (XEXP (op0, 0)) == XOR
4235 7091 : && CONST_INT_P (XEXP (op0, 1))
4236 1687421 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), trueop1))
4237 : {
4238 8 : rtx a = XEXP (XEXP (op0, 0), 0);
4239 8 : rtx b = trueop1;
4240 8 : rtx c = XEXP (op0, 1);
4241 8 : rtx nc = simplify_gen_unary (NOT, mode, c, mode);
4242 8 : rtx b_nc = simplify_gen_binary (AND, mode, b, nc);
4243 8 : rtx ac = simplify_gen_binary (AND, mode, a, c);
4244 8 : return simplify_gen_binary (IOR, mode, ac, b_nc);
4245 : }
4246 :
4247 : /* (xor (comparison foo bar) (const_int 1)) can become the reversed
4248 : comparison if STORE_FLAG_VALUE is 1. */
4249 1683598 : if (STORE_FLAG_VALUE == 1
4250 1683598 : && trueop1 == const1_rtx
4251 209405 : && COMPARISON_P (op0)
4252 1690243 : && (reversed = reversed_comparison (op0, mode)))
4253 : return reversed;
4254 :
4255 : /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
4256 : is (lt foo (const_int 0)), so we can perform the above
4257 : simplification if STORE_FLAG_VALUE is 1. */
4258 :
4259 1676961 : if (is_a <scalar_int_mode> (mode, &int_mode)
4260 : && STORE_FLAG_VALUE == 1
4261 1353499 : && trueop1 == const1_rtx
4262 202768 : && GET_CODE (op0) == LSHIFTRT
4263 35733 : && CONST_INT_P (XEXP (op0, 1))
4264 35733 : && INTVAL (XEXP (op0, 1)) == GET_MODE_PRECISION (int_mode) - 1)
4265 34646 : return gen_rtx_GE (int_mode, XEXP (op0, 0), const0_rtx);
4266 :
4267 : /* (xor (comparison foo bar) (const_int sign-bit))
4268 : when STORE_FLAG_VALUE is the sign bit. */
4269 1642315 : if (is_a <scalar_int_mode> (mode, &int_mode)
4270 1318853 : && val_signbit_p (int_mode, STORE_FLAG_VALUE)
4271 0 : && trueop1 == const_true_rtx
4272 0 : && COMPARISON_P (op0)
4273 0 : && (reversed = reversed_comparison (op0, int_mode)))
4274 : return reversed;
4275 :
4276 : /* Convert (xor (and A C) (and B C)) into (and (xor A B) C). */
4277 1642315 : if (GET_CODE (op0) == GET_CODE (op1)
4278 570255 : && (GET_CODE (op0) == AND
4279 570255 : || GET_CODE (op0) == LSHIFTRT
4280 493071 : || GET_CODE (op0) == ASHIFTRT
4281 492969 : || GET_CODE (op0) == ASHIFT
4282 492841 : || GET_CODE (op0) == ROTATE
4283 492699 : || GET_CODE (op0) == ROTATERT))
4284 : {
4285 78090 : tem = simplify_distributive_operation (code, mode, op0, op1);
4286 78090 : if (tem)
4287 : return tem;
4288 : }
4289 :
4290 : /* Convert (xor (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
4291 : mode size to (rotate A CX). */
4292 1567991 : tem = simplify_rotate_op (op0, op1, mode);
4293 1567991 : if (tem)
4294 : return tem;
4295 :
4296 : /* Convert (xor (and (not A) B) A) into A | B. */
4297 1566611 : if (GET_CODE (op0) == AND
4298 1566611 : && negated_ops_p (XEXP (op0, 0), op1))
4299 0 : return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
4300 :
4301 : /* Convert (xor (and (rotate (~1) A) B) (ashift 1 A))
4302 : into B | (1 << A). */
4303 1566611 : if (SHIFT_COUNT_TRUNCATED
4304 : && GET_CODE (op0) == AND
4305 : && GET_CODE (XEXP (op0, 0)) == ROTATE
4306 : && CONST_INT_P (XEXP (XEXP (op0, 0), 0))
4307 : && INTVAL (XEXP (XEXP (op0, 0), 0)) == -2
4308 : && GET_CODE (op1) == ASHIFT
4309 : && CONST_INT_P (XEXP (op1, 0))
4310 : && INTVAL (XEXP (op1, 0)) == 1
4311 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), XEXP (op1, 1))
4312 : && !side_effects_p (XEXP (op1, 1)))
4313 : return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
4314 :
4315 1566611 : tem = simplify_with_subreg_not (code, mode, op0, op1);
4316 1566611 : if (tem)
4317 : return tem;
4318 :
4319 1566610 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
4320 1566610 : if (tem)
4321 : return tem;
4322 :
4323 1566610 : tem = simplify_associative_operation (code, mode, op0, op1);
4324 1566610 : if (tem)
4325 : return tem;
4326 : break;
4327 :
4328 24793596 : case AND:
4329 24793596 : if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
4330 : return trueop1;
4331 24469521 : if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
4332 : return op0;
4333 24061194 : if (HWI_COMPUTABLE_MODE_P (mode))
4334 : {
4335 : /* When WORD_REGISTER_OPERATIONS is true, we need to know the
4336 : nonzero bits in WORD_MODE rather than MODE. */
4337 21089593 : scalar_int_mode tmode = as_a <scalar_int_mode> (mode);
4338 21089593 : if (WORD_REGISTER_OPERATIONS
4339 : && GET_MODE_BITSIZE (tmode) < BITS_PER_WORD)
4340 : tmode = word_mode;
4341 21089593 : HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, tmode);
4342 21089593 : HOST_WIDE_INT nzop1;
4343 21089593 : if (CONST_INT_P (trueop1))
4344 : {
4345 17917510 : HOST_WIDE_INT val1 = INTVAL (trueop1);
4346 : /* If we are turning off bits already known off in OP0, we need
4347 : not do an AND. */
4348 17917510 : if ((nzop0 & ~val1) == 0)
4349 441638 : return op0;
4350 :
4351 : /* Canonicalize (and (subreg (lshiftrt X shift)) mask) into
4352 : (and (lshiftrt (subreg X) shift) mask).
4353 :
4354 : Keeps shift and AND in the same mode, improving recognition.
4355 : Only applied when subreg is a lowpart, shift is valid,
4356 : and no precision is lost. */
4357 17562092 : if (SUBREG_P (op0)
4358 6236051 : && subreg_lowpart_p (op0)
4359 6219063 : && !paradoxical_subreg_p (op0)
4360 795801 : && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
4361 : /* simplify_subreg asserts the object being accessed is not
4362 : VOIDmode or BLKmode. We may have a REG_EQUAL note which
4363 : is not simplified and the source operand is a constant,
4364 : and thus VOIDmode. Guard against that. */
4365 117510 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) != VOIDmode
4366 117460 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) != BLKmode
4367 117460 : && !CONST_INT_P (XEXP (XEXP (op0, 0), 0))
4368 117460 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
4369 96483 : && INTVAL (XEXP (XEXP (op0, 0), 1)) >= 0
4370 96483 : && INTVAL (XEXP (XEXP (op0, 0), 1)) < HOST_BITS_PER_WIDE_INT
4371 17658574 : && ((INTVAL (XEXP (XEXP (op0, 0), 1))
4372 96482 : + floor_log2 (val1))
4373 17562092 : < GET_MODE_PRECISION (as_a <scalar_int_mode> (mode))))
4374 : {
4375 13382 : tem = XEXP (XEXP (op0, 0), 0);
4376 13382 : if (SUBREG_P (tem))
4377 : {
4378 296 : if (subreg_lowpart_p (tem))
4379 296 : tem = SUBREG_REG (tem);
4380 : else
4381 : tem = NULL_RTX;
4382 : }
4383 296 : if (tem != NULL_RTX)
4384 : {
4385 13382 : offset = subreg_lowpart_offset (mode, GET_MODE (tem));
4386 13382 : tem = simplify_gen_subreg (mode, tem, GET_MODE (tem),
4387 13382 : offset);
4388 13382 : if (tem)
4389 : {
4390 13382 : unsigned shiftamt = INTVAL (XEXP (XEXP (op0, 0), 1));
4391 13382 : rtx shiftamtrtx = gen_int_shift_amount (mode,
4392 13382 : shiftamt);
4393 13382 : op0 = simplify_gen_binary (LSHIFTRT, mode, tem,
4394 : shiftamtrtx);
4395 13382 : return simplify_gen_binary (AND, mode, op0, op1);
4396 : }
4397 : }
4398 : }
4399 : }
4400 20720793 : nzop1 = nonzero_bits (trueop1, mode);
4401 : /* If we are clearing all the nonzero bits, the result is zero. */
4402 20720793 : if ((nzop1 & nzop0) == 0
4403 20720793 : && !side_effects_p (op0) && !side_effects_p (op1))
4404 72838 : return CONST0_RTX (mode);
4405 : }
4406 23624574 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
4407 23624570 : && GET_MODE_CLASS (mode) != MODE_CC)
4408 : return op0;
4409 : /* A & (~A) -> 0 */
4410 590393 : if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
4411 23611377 : || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
4412 3213 : && ! side_effects_p (op0)
4413 23617754 : && GET_MODE_CLASS (mode) != MODE_CC)
4414 3212 : return CONST0_RTX (mode);
4415 :
4416 : /* Convert (and (plus (A - 1)) (neg A)) to 0. */
4417 23611330 : if (match_plus_neg_pattern (op0, op1, mode))
4418 2 : return CONST0_RTX (mode);
4419 :
4420 : /* Transform (and (extend X) C) into (zero_extend (and X C)) if
4421 : there are no nonzero bits of C outside of X's mode. */
4422 47222656 : if ((GET_CODE (op0) == SIGN_EXTEND
4423 23611328 : || GET_CODE (op0) == ZERO_EXTEND)
4424 94547 : && CONST_SCALAR_INT_P (trueop1)
4425 81323 : && is_a <scalar_int_mode> (mode, &int_mode)
4426 81323 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
4427 23692651 : && (wi::mask (GET_MODE_PRECISION (inner_mode), true,
4428 81323 : GET_MODE_PRECISION (int_mode))
4429 23692651 : & rtx_mode_t (trueop1, mode)) == 0)
4430 : {
4431 79303 : machine_mode imode = GET_MODE (XEXP (op0, 0));
4432 79303 : tem = immed_wide_int_const (rtx_mode_t (trueop1, mode), imode);
4433 79303 : tem = simplify_gen_binary (AND, imode, XEXP (op0, 0), tem);
4434 79303 : return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
4435 : }
4436 :
4437 : /* Transform (and (truncate X) C) into (truncate (and X C)). This way
4438 : we might be able to further simplify the AND with X and potentially
4439 : remove the truncation altogether. */
4440 23532025 : if (GET_CODE (op0) == TRUNCATE && CONST_INT_P (trueop1))
4441 : {
4442 6 : rtx x = XEXP (op0, 0);
4443 6 : machine_mode xmode = GET_MODE (x);
4444 6 : tem = simplify_gen_binary (AND, xmode, x,
4445 6 : gen_int_mode (INTVAL (trueop1), xmode));
4446 6 : return simplify_gen_unary (TRUNCATE, mode, tem, xmode);
4447 : }
4448 :
4449 : /* Canonicalize (A | C1) & C2 as (A & C2) | (C1 & C2). */
4450 23532019 : if (GET_CODE (op0) == IOR
4451 1400614 : && CONST_INT_P (trueop1)
4452 216714 : && CONST_INT_P (XEXP (op0, 1)))
4453 : {
4454 133995 : HOST_WIDE_INT tmp = INTVAL (trueop1) & INTVAL (XEXP (op0, 1));
4455 133995 : return simplify_gen_binary (IOR, mode,
4456 : simplify_gen_binary (AND, mode,
4457 : XEXP (op0, 0), op1),
4458 133995 : gen_int_mode (tmp, mode));
4459 : }
4460 :
4461 : /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
4462 : insn (and may simplify more). */
4463 23398024 : if (GET_CODE (op0) == XOR
4464 151758 : && rtx_equal_p (XEXP (op0, 0), op1)
4465 23399465 : && ! side_effects_p (op1))
4466 1441 : return simplify_gen_binary (AND, mode,
4467 : simplify_gen_unary (NOT, mode,
4468 : XEXP (op0, 1), mode),
4469 1441 : op1);
4470 :
4471 23396583 : if (GET_CODE (op0) == XOR
4472 150317 : && rtx_equal_p (XEXP (op0, 1), op1)
4473 23401380 : && ! side_effects_p (op1))
4474 4797 : return simplify_gen_binary (AND, mode,
4475 : simplify_gen_unary (NOT, mode,
4476 : XEXP (op0, 0), mode),
4477 4797 : op1);
4478 :
4479 : /* Similarly for (~(A ^ B)) & A. */
4480 23391786 : if (GET_CODE (op0) == NOT
4481 587229 : && GET_CODE (XEXP (op0, 0)) == XOR
4482 3854 : && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
4483 23391840 : && ! side_effects_p (op1))
4484 54 : return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
4485 :
4486 23391732 : if (GET_CODE (op0) == NOT
4487 587175 : && GET_CODE (XEXP (op0, 0)) == XOR
4488 3800 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
4489 23391769 : && ! side_effects_p (op1))
4490 37 : return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
4491 :
4492 : /* Convert (A | B) & A to A. */
4493 23391695 : if (GET_CODE (op0) == IOR
4494 1266619 : && (rtx_equal_p (XEXP (op0, 0), op1)
4495 1266094 : || rtx_equal_p (XEXP (op0, 1), op1))
4496 745 : && ! side_effects_p (XEXP (op0, 0))
4497 23392440 : && ! side_effects_p (XEXP (op0, 1)))
4498 : return op1;
4499 :
4500 : /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
4501 : ((A & N) + B) & M -> (A + B) & M
4502 : Similarly if (N & M) == 0,
4503 : ((A | N) + B) & M -> (A + B) & M
4504 : and for - instead of + and/or ^ instead of |.
4505 : Also, if (N & M) == 0, then
4506 : (A +- N) & M -> A & M. */
4507 23390950 : if (CONST_INT_P (trueop1)
4508 17356514 : && HWI_COMPUTABLE_MODE_P (mode)
4509 17334867 : && ~UINTVAL (trueop1)
4510 17334867 : && (UINTVAL (trueop1) & (UINTVAL (trueop1) + 1)) == 0
4511 34781789 : && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS))
4512 : {
4513 978951 : rtx pmop[2];
4514 978951 : int which;
4515 :
4516 978951 : pmop[0] = XEXP (op0, 0);
4517 978951 : pmop[1] = XEXP (op0, 1);
4518 :
4519 978951 : if (CONST_INT_P (pmop[1])
4520 482497 : && (UINTVAL (pmop[1]) & UINTVAL (trueop1)) == 0)
4521 169435 : return simplify_gen_binary (AND, mode, pmop[0], op1);
4522 :
4523 2451486 : for (which = 0; which < 2; which++)
4524 : {
4525 1634324 : tem = pmop[which];
4526 1634324 : switch (GET_CODE (tem))
4527 : {
4528 14544 : case AND:
4529 14544 : if (CONST_INT_P (XEXP (tem, 1))
4530 13029 : && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1))
4531 : == UINTVAL (trueop1))
4532 7639 : pmop[which] = XEXP (tem, 0);
4533 : break;
4534 1368 : case IOR:
4535 1368 : case XOR:
4536 1368 : if (CONST_INT_P (XEXP (tem, 1))
4537 174 : && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1)) == 0)
4538 7 : pmop[which] = XEXP (tem, 0);
4539 : break;
4540 : default:
4541 : break;
4542 : }
4543 : }
4544 :
4545 817162 : if (pmop[0] != XEXP (op0, 0) || pmop[1] != XEXP (op0, 1))
4546 : {
4547 7646 : tem = simplify_gen_binary (GET_CODE (op0), mode,
4548 : pmop[0], pmop[1]);
4549 7646 : return simplify_gen_binary (code, mode, tem, op1);
4550 : }
4551 : }
4552 :
4553 : /* (and X (ior (not X) Y) -> (and X Y) */
4554 23221515 : if (GET_CODE (op1) == IOR
4555 967998 : && GET_CODE (XEXP (op1, 0)) == NOT
4556 23226513 : && rtx_equal_p (op0, XEXP (XEXP (op1, 0), 0)))
4557 0 : return simplify_gen_binary (AND, mode, op0, XEXP (op1, 1));
4558 :
4559 : /* (and (ior (not X) Y) X) -> (and X Y) */
4560 23221515 : if (GET_CODE (op0) == IOR
4561 1265874 : && GET_CODE (XEXP (op0, 0)) == NOT
4562 23269031 : && rtx_equal_p (op1, XEXP (XEXP (op0, 0), 0)))
4563 6 : return simplify_gen_binary (AND, mode, op1, XEXP (op0, 1));
4564 :
4565 : /* (and X (ior Y (not X)) -> (and X Y) */
4566 23221509 : if (GET_CODE (op1) == IOR
4567 967998 : && GET_CODE (XEXP (op1, 1)) == NOT
4568 23222091 : && rtx_equal_p (op0, XEXP (XEXP (op1, 1), 0)))
4569 0 : return simplify_gen_binary (AND, mode, op0, XEXP (op1, 0));
4570 :
4571 : /* (and (ior Y (not X)) X) -> (and X Y) */
4572 23221509 : if (GET_CODE (op0) == IOR
4573 1265868 : && GET_CODE (XEXP (op0, 1)) == NOT
4574 23228578 : && rtx_equal_p (op1, XEXP (XEXP (op0, 1), 0)))
4575 78 : return simplify_gen_binary (AND, mode, op1, XEXP (op0, 0));
4576 :
4577 : /* (and (ior/xor X Y) (not Y)) -> X & ~Y */
4578 23221431 : if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
4579 23221431 : && negated_ops_p (op1, XEXP (op0, 1)))
4580 98 : return simplify_gen_binary (AND, mode, XEXP (op0, 0),
4581 : simplify_gen_unary (NOT, mode,
4582 : XEXP (op0, 1),
4583 98 : mode));
4584 : /* (and (ior/xor Y X) (not Y)) -> X & ~Y */
4585 23221333 : if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
4586 23221333 : && negated_ops_p (op1, XEXP (op0, 0)))
4587 0 : return simplify_gen_binary (AND, mode, XEXP (op0, 1),
4588 : simplify_gen_unary (NOT, mode,
4589 : XEXP (op0, 0),
4590 0 : mode));
4591 :
4592 : /* Convert (and (ior A C) (ior B C)) into (ior (and A B) C). */
4593 23221333 : if (GET_CODE (op0) == GET_CODE (op1)
4594 2300408 : && (GET_CODE (op0) == AND
4595 : || GET_CODE (op0) == IOR
4596 2300408 : || GET_CODE (op0) == LSHIFTRT
4597 1332933 : || GET_CODE (op0) == ASHIFTRT
4598 1332779 : || GET_CODE (op0) == ASHIFT
4599 1332607 : || GET_CODE (op0) == ROTATE
4600 1332607 : || GET_CODE (op0) == ROTATERT))
4601 : {
4602 967801 : tem = simplify_distributive_operation (code, mode, op0, op1);
4603 967801 : if (tem)
4604 : return tem;
4605 : }
4606 :
4607 : /* (and:v4si
4608 : (ashiftrt:v4si A 16)
4609 : (const_vector: 0xffff x4))
4610 : is just (lshiftrt:v4si A 16). */
4611 22298994 : if (VECTOR_MODE_P (mode) && GET_CODE (op0) == ASHIFTRT
4612 4571 : && (CONST_INT_P (XEXP (op0, 1))
4613 2035 : || (GET_CODE (XEXP (op0, 1)) == CONST_VECTOR
4614 94 : && const_vec_duplicate_p (XEXP (op0, 1))
4615 0 : && CONST_INT_P (XVECEXP (XEXP (op0, 1), 0, 0))))
4616 2536 : && GET_CODE (op1) == CONST_VECTOR
4617 22299022 : && const_vec_duplicate_p (op1)
4618 22299064 : && CONST_INT_P (XVECEXP (op1, 0, 0)))
4619 : {
4620 136 : unsigned HOST_WIDE_INT shift_count
4621 : = (CONST_INT_P (XEXP (op0, 1))
4622 68 : ? UINTVAL (XEXP (op0, 1))
4623 0 : : UINTVAL (XVECEXP (XEXP (op0, 1), 0, 0)));
4624 68 : unsigned HOST_WIDE_INT inner_prec
4625 136 : = GET_MODE_PRECISION (GET_MODE_INNER (mode));
4626 :
4627 : /* Avoid UD shift count. */
4628 68 : if (shift_count < inner_prec
4629 56 : && (UINTVAL (XVECEXP (op1, 0, 0))
4630 56 : == (HOST_WIDE_INT_1U << (inner_prec - shift_count)) - 1))
4631 42 : return simplify_gen_binary (LSHIFTRT, mode, XEXP (op0, 0), XEXP (op0, 1));
4632 : }
4633 :
4634 22298952 : tem = simplify_with_subreg_not (code, mode, op0, op1);
4635 22298952 : if (tem)
4636 : return tem;
4637 :
4638 22296479 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
4639 22296479 : if (tem)
4640 : return tem;
4641 :
4642 22296257 : tem = simplify_associative_operation (code, mode, op0, op1);
4643 22296257 : if (tem)
4644 : return tem;
4645 : break;
4646 :
4647 900653 : case UDIV:
4648 : /* 0/x is 0 (or x&0 if x has side-effects). */
4649 900653 : if (trueop0 == CONST0_RTX (mode)
4650 390 : && !cfun->can_throw_non_call_exceptions)
4651 : {
4652 390 : if (side_effects_p (op1))
4653 0 : return simplify_gen_binary (AND, mode, op1, trueop0);
4654 : return trueop0;
4655 : }
4656 : /* x/1 is x. */
4657 900263 : if (trueop1 == CONST1_RTX (mode))
4658 : {
4659 241839 : tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4660 241839 : if (tem)
4661 : return tem;
4662 : }
4663 : /* Convert divide by power of two into shift. */
4664 658424 : if (CONST_INT_P (trueop1)
4665 981548 : && (val = exact_log2 (UINTVAL (trueop1))) > 0)
4666 323124 : return simplify_gen_binary (LSHIFTRT, mode, op0,
4667 323124 : gen_int_shift_amount (mode, val));
4668 : break;
4669 :
4670 1416466 : case DIV:
4671 : /* Handle floating point and integers separately. */
4672 1416466 : if (SCALAR_FLOAT_MODE_P (mode))
4673 : {
4674 : /* Maybe change 0.0 / x to 0.0. This transformation isn't
4675 : safe for modes with NaNs, since 0.0 / 0.0 will then be
4676 : NaN rather than 0.0. Nor is it safe for modes with signed
4677 : zeros, since dividing 0 by a negative number gives -0.0 */
4678 328306 : if (trueop0 == CONST0_RTX (mode)
4679 2818 : && !HONOR_NANS (mode)
4680 14 : && !HONOR_SIGNED_ZEROS (mode)
4681 328320 : && ! side_effects_p (op1))
4682 : return op0;
4683 : /* x/1.0 is x. */
4684 328292 : if (trueop1 == CONST1_RTX (mode)
4685 328292 : && !HONOR_SNANS (mode))
4686 : return op0;
4687 :
4688 328288 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
4689 28163 : && trueop1 != CONST0_RTX (mode))
4690 : {
4691 22091 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
4692 :
4693 : /* x/-1.0 is -x. */
4694 22091 : if (real_equal (d1, &dconstm1)
4695 22091 : && !HONOR_SNANS (mode))
4696 0 : return simplify_gen_unary (NEG, mode, op0, mode);
4697 :
4698 : /* Change FP division by a constant into multiplication.
4699 : Only do this with -freciprocal-math. */
4700 22091 : if (flag_reciprocal_math
4701 22091 : && !real_equal (d1, &dconst0))
4702 : {
4703 7 : REAL_VALUE_TYPE d;
4704 7 : real_arithmetic (&d, RDIV_EXPR, &dconst1, d1);
4705 7 : tem = const_double_from_real_value (d, mode);
4706 7 : return simplify_gen_binary (MULT, mode, op0, tem);
4707 : }
4708 : }
4709 : }
4710 1088160 : else if (SCALAR_INT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
4711 : {
4712 : /* 0/x is 0 (or x&0 if x has side-effects). */
4713 1056700 : if (trueop0 == CONST0_RTX (mode)
4714 985 : && !cfun->can_throw_non_call_exceptions)
4715 : {
4716 931 : if (side_effects_p (op1))
4717 8 : return simplify_gen_binary (AND, mode, op1, trueop0);
4718 : return trueop0;
4719 : }
4720 : /* x/1 is x. */
4721 1055769 : if (trueop1 == CONST1_RTX (mode))
4722 : {
4723 85 : tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4724 85 : if (tem)
4725 : return tem;
4726 : }
4727 : /* x/-1 is -x. */
4728 1055684 : if (trueop1 == CONSTM1_RTX (mode))
4729 : {
4730 554 : rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4731 554 : if (x)
4732 554 : return simplify_gen_unary (NEG, mode, x, mode);
4733 : }
4734 : }
4735 : break;
4736 :
4737 920421 : case UMOD:
4738 : /* 0%x is 0 (or x&0 if x has side-effects). */
4739 920421 : if (trueop0 == CONST0_RTX (mode))
4740 : {
4741 948 : if (side_effects_p (op1))
4742 0 : return simplify_gen_binary (AND, mode, op1, trueop0);
4743 : return trueop0;
4744 : }
4745 : /* x%1 is 0 (of x&0 if x has side-effects). */
4746 919473 : if (trueop1 == CONST1_RTX (mode))
4747 : {
4748 274148 : if (side_effects_p (op0))
4749 0 : return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
4750 274148 : return CONST0_RTX (mode);
4751 : }
4752 : /* Implement modulus by power of two as AND. */
4753 645325 : if (CONST_INT_P (trueop1)
4754 942285 : && exact_log2 (UINTVAL (trueop1)) > 0)
4755 296960 : return simplify_gen_binary (AND, mode, op0,
4756 296960 : gen_int_mode (UINTVAL (trueop1) - 1,
4757 : mode));
4758 : break;
4759 :
4760 580374 : case MOD:
4761 : /* 0%x is 0 (or x&0 if x has side-effects). */
4762 580374 : if (trueop0 == CONST0_RTX (mode))
4763 : {
4764 1219 : if (side_effects_p (op1))
4765 8 : return simplify_gen_binary (AND, mode, op1, trueop0);
4766 : return trueop0;
4767 : }
4768 : /* x%1 and x%-1 is 0 (or x&0 if x has side-effects). */
4769 579155 : if (trueop1 == CONST1_RTX (mode) || trueop1 == constm1_rtx)
4770 : {
4771 557 : if (side_effects_p (op0))
4772 0 : return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
4773 557 : return CONST0_RTX (mode);
4774 : }
4775 : break;
4776 :
4777 141373 : case ROTATERT:
4778 141373 : case ROTATE:
4779 141373 : if (trueop1 == CONST0_RTX (mode))
4780 : return op0;
4781 : /* Canonicalize rotates by constant amount. If the condition of
4782 : reversing direction is met, then reverse the direction. */
4783 : #if defined(HAVE_rotate) && defined(HAVE_rotatert)
4784 141283 : if (reverse_rotate_by_imm_p (mode, (code == ROTATE), trueop1))
4785 : {
4786 12209 : int new_amount = GET_MODE_UNIT_PRECISION (mode) - INTVAL (trueop1);
4787 12209 : rtx new_amount_rtx = gen_int_shift_amount (mode, new_amount);
4788 12935 : return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
4789 : mode, op0, new_amount_rtx);
4790 : }
4791 : #endif
4792 : /* ROTATE/ROTATERT:HI (X:HI, 8) is BSWAP:HI (X). Other combinations
4793 : such as SImode with a count of 16 do not correspond to RTL BSWAP
4794 : semantics. */
4795 129074 : tem = unwrap_const_vec_duplicate (trueop1);
4796 129074 : if (GET_MODE_UNIT_BITSIZE (mode) == (2 * BITS_PER_UNIT)
4797 129074 : && CONST_INT_P (tem) && INTVAL (tem) == BITS_PER_UNIT)
4798 672 : return simplify_gen_unary (BSWAP, mode, op0, mode);
4799 :
4800 : /* FALLTHRU */
4801 5469533 : case ASHIFTRT:
4802 5469533 : if (trueop1 == CONST0_RTX (mode))
4803 : return op0;
4804 5467253 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4805 : return op0;
4806 : /* Rotating ~0 always results in ~0. */
4807 5467078 : if (CONST_INT_P (trueop0)
4808 15482 : && HWI_COMPUTABLE_MODE_P (mode)
4809 15454 : && UINTVAL (trueop0) == GET_MODE_MASK (mode)
4810 5467078 : && ! side_effects_p (op1))
4811 : return op0;
4812 :
4813 32101621 : canonicalize_shift:
4814 : /* Given:
4815 : scalar modes M1, M2
4816 : scalar constants c1, c2
4817 : size (M2) > size (M1)
4818 : c1 == size (M2) - size (M1)
4819 : optimize:
4820 : ([a|l]shiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int <c1>))
4821 : <low_part>)
4822 : (const_int <c2>))
4823 : to:
4824 : (subreg:M1 ([a|l]shiftrt:M2 (reg:M2) (const_int <c1 + c2>))
4825 : <low_part>). */
4826 32101621 : if ((code == ASHIFTRT || code == LSHIFTRT)
4827 12227756 : && is_a <scalar_int_mode> (mode, &int_mode)
4828 11407486 : && SUBREG_P (op0)
4829 1241007 : && CONST_INT_P (op1)
4830 1237607 : && GET_CODE (SUBREG_REG (op0)) == LSHIFTRT
4831 18962 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op0)),
4832 : &inner_mode)
4833 18962 : && CONST_INT_P (XEXP (SUBREG_REG (op0), 1))
4834 37538 : && GET_MODE_BITSIZE (inner_mode) > GET_MODE_BITSIZE (int_mode)
4835 18769 : && (INTVAL (XEXP (SUBREG_REG (op0), 1))
4836 37538 : == GET_MODE_BITSIZE (inner_mode) - GET_MODE_BITSIZE (int_mode))
4837 32120139 : && subreg_lowpart_p (op0))
4838 : {
4839 18518 : rtx tmp = gen_int_shift_amount
4840 18518 : (inner_mode, INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (op1));
4841 :
4842 : /* Combine would usually zero out the value when combining two
4843 : local shifts and the range becomes larger or equal to the mode.
4844 : However since we fold away one of the shifts here combine won't
4845 : see it so we should immediately zero the result if it's out of
4846 : range. */
4847 18518 : if (code == LSHIFTRT
4848 33516 : && INTVAL (tmp) >= GET_MODE_BITSIZE (inner_mode))
4849 0 : tmp = const0_rtx;
4850 : else
4851 18518 : tmp = simplify_gen_binary (code,
4852 : inner_mode,
4853 18518 : XEXP (SUBREG_REG (op0), 0),
4854 : tmp);
4855 :
4856 18518 : return lowpart_subreg (int_mode, tmp, inner_mode);
4857 : }
4858 :
4859 32083103 : if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
4860 : {
4861 : val = INTVAL (op1) & (GET_MODE_UNIT_PRECISION (mode) - 1);
4862 : if (val != INTVAL (op1))
4863 : return simplify_gen_binary (code, mode, op0,
4864 : gen_int_shift_amount (mode, val));
4865 : }
4866 :
4867 : /* Simplify:
4868 :
4869 : (code:M1
4870 : (subreg:M1
4871 : ([al]shiftrt:M2
4872 : (subreg:M2
4873 : (ashift:M1 X C1))
4874 : C2))
4875 : C3)
4876 :
4877 : to:
4878 :
4879 : (code:M1
4880 : ([al]shiftrt:M1
4881 : (ashift:M1 X C1+N)
4882 : C2+N)
4883 : C3)
4884 :
4885 : where M1 is N bits wider than M2. Optimizing the (subreg:M1 ...)
4886 : directly would be arithmetically correct, but restricting the
4887 : simplification to shifts by constants is more conservative,
4888 : since it is more likely to lead to further simplifications. */
4889 32083103 : if (is_a<scalar_int_mode> (mode, &int_mode)
4890 5751515 : && paradoxical_subreg_p (op0)
4891 5228217 : && is_a<scalar_int_mode> (GET_MODE (SUBREG_REG (op0)), &inner_mode)
4892 5203770 : && (GET_CODE (SUBREG_REG (op0)) == ASHIFTRT
4893 5203770 : || GET_CODE (SUBREG_REG (op0)) == LSHIFTRT)
4894 157949 : && CONST_INT_P (op1))
4895 : {
4896 157949 : auto xcode = GET_CODE (SUBREG_REG (op0));
4897 157949 : rtx xop0 = XEXP (SUBREG_REG (op0), 0);
4898 157949 : rtx xop1 = XEXP (SUBREG_REG (op0), 1);
4899 157949 : if (SUBREG_P (xop0)
4900 11155 : && GET_MODE (SUBREG_REG (xop0)) == mode
4901 11010 : && GET_CODE (SUBREG_REG (xop0)) == ASHIFT
4902 594 : && CONST_INT_P (xop1)
4903 158543 : && UINTVAL (xop1) < GET_MODE_PRECISION (inner_mode))
4904 : {
4905 594 : rtx yop0 = XEXP (SUBREG_REG (xop0), 0);
4906 594 : rtx yop1 = XEXP (SUBREG_REG (xop0), 1);
4907 594 : if (CONST_INT_P (yop1)
4908 594 : && UINTVAL (yop1) < GET_MODE_PRECISION (inner_mode))
4909 : {
4910 1188 : auto bias = (GET_MODE_BITSIZE (int_mode)
4911 594 : - GET_MODE_BITSIZE (inner_mode));
4912 594 : tem = simplify_gen_binary (ASHIFT, mode, yop0,
4913 594 : GEN_INT (INTVAL (yop1) + bias));
4914 594 : tem = simplify_gen_binary (xcode, mode, tem,
4915 594 : GEN_INT (INTVAL (xop1) + bias));
4916 594 : return simplify_gen_binary (code, mode, tem, op1);
4917 : }
4918 : }
4919 : }
4920 : break;
4921 :
4922 0 : case SS_ASHIFT:
4923 0 : if (CONST_INT_P (trueop0)
4924 0 : && HWI_COMPUTABLE_MODE_P (mode)
4925 0 : && (UINTVAL (trueop0) == (GET_MODE_MASK (mode) >> 1)
4926 0 : || mode_signbit_p (mode, trueop0))
4927 0 : && ! side_effects_p (op1))
4928 : return op0;
4929 0 : goto simplify_ashift;
4930 :
4931 0 : case US_ASHIFT:
4932 0 : if (CONST_INT_P (trueop0)
4933 0 : && HWI_COMPUTABLE_MODE_P (mode)
4934 0 : && UINTVAL (trueop0) == GET_MODE_MASK (mode)
4935 0 : && ! side_effects_p (op1))
4936 : return op0;
4937 : /* FALLTHRU */
4938 :
4939 20159767 : case ASHIFT:
4940 20159767 : simplify_ashift:
4941 20159767 : if (trueop1 == CONST0_RTX (mode))
4942 : return op0;
4943 19990890 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4944 : return op0;
4945 19961340 : if (mem_depth
4946 215846 : && code == ASHIFT
4947 215846 : && CONST_INT_P (trueop1)
4948 215838 : && is_a <scalar_int_mode> (mode, &int_mode)
4949 20177166 : && IN_RANGE (UINTVAL (trueop1),
4950 : 1, GET_MODE_PRECISION (int_mode) - 1))
4951 : {
4952 215826 : auto c = (wi::one (GET_MODE_PRECISION (int_mode))
4953 215826 : << UINTVAL (trueop1));
4954 215826 : rtx new_op1 = immed_wide_int_const (c, int_mode);
4955 215826 : return simplify_gen_binary (MULT, int_mode, op0, new_op1);
4956 215826 : }
4957 :
4958 : /* If we're shifting left a signed bitfield extraction and the
4959 : shift count + bitfield size is a natural integral mode and
4960 : the field starts at offset 0 (counting from the LSB), then
4961 : this can be simplified to a sign extension of a left shift.
4962 :
4963 : Some ISAs (RISC-V 64-bit) have inherent support for such
4964 : instructions and it's better for various optimizations to
4965 : express as a SIGN_EXTEND rather than a shifted SIGN_EXTRACT. */
4966 19745514 : if (GET_CODE (op0) == SIGN_EXTRACT
4967 28 : && REG_P (XEXP (op0, 0))
4968 : /* The size of the bitfield, the location of the bitfield and
4969 : shift count must be CONST_INTs. */
4970 22 : && CONST_INT_P (op1)
4971 22 : && CONST_INT_P (XEXP (op0, 1))
4972 22 : && CONST_INT_P (XEXP (op0, 2)))
4973 : {
4974 22 : int size = INTVAL (op1) + INTVAL (XEXP (op0, 1));
4975 22 : machine_mode smaller_mode;
4976 : /* Now we need to verify the size of the bitfield plus the shift
4977 : count is an integral mode and smaller than MODE. This is
4978 : requirement for using SIGN_EXTEND. We also need to verify the
4979 : field starts at bit location 0 and that the subreg lowpart also
4980 : starts at zero. */
4981 22 : if (int_mode_for_size (size, size).exists (&smaller_mode)
4982 3 : && mode > smaller_mode
4983 22 : && (subreg_lowpart_offset (smaller_mode, mode).to_constant ()
4984 3 : == UINTVAL (XEXP (op0, 2)))
4985 1 : && XEXP (op0, 2) == CONST0_RTX (mode))
4986 : {
4987 : /* Everything passed. So we just need to get the subreg of the
4988 : original input, shift it and sign extend the result. */
4989 1 : rtx op = gen_lowpart (smaller_mode, XEXP (op0, 0));
4990 1 : rtx x = gen_rtx_ASHIFT (smaller_mode, op, op1);
4991 1 : return gen_rtx_SIGN_EXTEND (mode, x);
4992 : }
4993 : }
4994 19745513 : goto canonicalize_shift;
4995 :
4996 8718597 : case LSHIFTRT:
4997 8718597 : if (trueop1 == CONST0_RTX (mode))
4998 : return op0;
4999 6890610 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
5000 : return op0;
5001 : /* Optimize (lshiftrt (clz X) C) as (eq X 0). */
5002 6889030 : if (GET_CODE (op0) == CLZ
5003 0 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
5004 0 : && CONST_INT_P (trueop1)
5005 : && STORE_FLAG_VALUE == 1
5006 6889030 : && INTVAL (trueop1) < GET_MODE_UNIT_PRECISION (mode))
5007 : {
5008 0 : unsigned HOST_WIDE_INT zero_val = 0;
5009 :
5010 0 : if (CLZ_DEFINED_VALUE_AT_ZERO (inner_mode, zero_val)
5011 0 : && zero_val == GET_MODE_PRECISION (inner_mode)
5012 0 : && INTVAL (trueop1) == exact_log2 (zero_val))
5013 0 : return simplify_gen_relational (EQ, mode, inner_mode,
5014 0 : XEXP (op0, 0), const0_rtx);
5015 : }
5016 6889030 : goto canonicalize_shift;
5017 :
5018 231062 : case SMIN:
5019 231062 : if (HWI_COMPUTABLE_MODE_P (mode)
5020 210159 : && mode_signbit_p (mode, trueop1)
5021 0 : && ! side_effects_p (op0))
5022 : return op1;
5023 231062 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5024 : return op0;
5025 230884 : tem = simplify_associative_operation (code, mode, op0, op1);
5026 230884 : if (tem)
5027 : return tem;
5028 : break;
5029 :
5030 716434 : case SMAX:
5031 716434 : if (HWI_COMPUTABLE_MODE_P (mode)
5032 688229 : && CONST_INT_P (trueop1)
5033 654551 : && (UINTVAL (trueop1) == GET_MODE_MASK (mode) >> 1)
5034 0 : && ! side_effects_p (op0))
5035 : return op1;
5036 716434 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5037 : return op0;
5038 716327 : tem = simplify_associative_operation (code, mode, op0, op1);
5039 716327 : if (tem)
5040 : return tem;
5041 : break;
5042 :
5043 413772 : case UMIN:
5044 413772 : if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
5045 : return op1;
5046 413760 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5047 : return op0;
5048 413641 : tem = simplify_associative_operation (code, mode, op0, op1);
5049 413641 : if (tem)
5050 : return tem;
5051 : break;
5052 :
5053 370469 : case UMAX:
5054 370469 : if (trueop1 == constm1_rtx && ! side_effects_p (op0))
5055 : return op1;
5056 370469 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5057 : return op0;
5058 370379 : tem = simplify_associative_operation (code, mode, op0, op1);
5059 370379 : if (tem)
5060 : return tem;
5061 : break;
5062 :
5063 11824 : case SS_PLUS:
5064 11824 : case US_PLUS:
5065 11824 : case SS_MINUS:
5066 11824 : case US_MINUS:
5067 : /* Simplify x +/- 0 to x, if possible. */
5068 11824 : if (trueop1 == CONST0_RTX (mode))
5069 0 : return op0;
5070 : return 0;
5071 :
5072 0 : case SS_MULT:
5073 0 : case US_MULT:
5074 : /* Simplify x * 0 to 0, if possible. */
5075 0 : if (trueop1 == CONST0_RTX (mode)
5076 0 : && !side_effects_p (op0))
5077 : return op1;
5078 :
5079 : /* Simplify x * 1 to x, if possible. */
5080 0 : if (trueop1 == CONST1_RTX (mode))
5081 0 : return op0;
5082 : return 0;
5083 :
5084 517824 : case SMUL_HIGHPART:
5085 517824 : case UMUL_HIGHPART:
5086 : /* Simplify x * 0 to 0, if possible. */
5087 517824 : if (trueop1 == CONST0_RTX (mode)
5088 517824 : && !side_effects_p (op0))
5089 78 : return op1;
5090 : return 0;
5091 :
5092 0 : case SS_DIV:
5093 0 : case US_DIV:
5094 : /* Simplify x / 1 to x, if possible. */
5095 0 : if (trueop1 == CONST1_RTX (mode))
5096 0 : return op0;
5097 : return 0;
5098 :
5099 0 : case COPYSIGN:
5100 0 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5101 : return op0;
5102 0 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1))
5103 : {
5104 0 : REAL_VALUE_TYPE f1;
5105 0 : real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (trueop1));
5106 0 : rtx tmp = simplify_gen_unary (ABS, mode, op0, mode);
5107 0 : if (REAL_VALUE_NEGATIVE (f1))
5108 0 : tmp = simplify_unary_operation (NEG, mode, tmp, mode);
5109 0 : return tmp;
5110 : }
5111 0 : if (GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
5112 0 : return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
5113 0 : if (GET_CODE (op1) == ABS
5114 0 : && ! side_effects_p (op1))
5115 0 : return simplify_gen_unary (ABS, mode, op0, mode);
5116 0 : if (GET_CODE (op0) == COPYSIGN
5117 0 : && ! side_effects_p (XEXP (op0, 1)))
5118 0 : return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
5119 0 : if (GET_CODE (op1) == COPYSIGN
5120 0 : && ! side_effects_p (XEXP (op1, 0)))
5121 0 : return simplify_gen_binary (COPYSIGN, mode, op0, XEXP (op1, 1));
5122 : return 0;
5123 :
5124 1108 : case VEC_SERIES:
5125 2216 : if (op1 == CONST0_RTX (GET_MODE_INNER (mode)))
5126 92 : return gen_vec_duplicate (mode, op0);
5127 1016 : if (valid_for_const_vector_p (mode, op0)
5128 1016 : && valid_for_const_vector_p (mode, op1))
5129 93 : return gen_const_vec_series (mode, op0, op1);
5130 : return 0;
5131 :
5132 3988925 : case VEC_SELECT:
5133 3988925 : if (!VECTOR_MODE_P (mode))
5134 : {
5135 1101934 : gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
5136 2203868 : gcc_assert (mode == GET_MODE_INNER (GET_MODE (trueop0)));
5137 1101934 : gcc_assert (GET_CODE (trueop1) == PARALLEL);
5138 1101934 : gcc_assert (XVECLEN (trueop1, 0) == 1);
5139 :
5140 : /* We can't reason about selections made at runtime. */
5141 1101934 : if (!CONST_INT_P (XVECEXP (trueop1, 0, 0)))
5142 459953007 : return 0;
5143 :
5144 1101934 : if (vec_duplicate_p (trueop0, &elt0))
5145 2019 : return elt0;
5146 :
5147 1099915 : if (GET_CODE (trueop0) == CONST_VECTOR)
5148 7350 : return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP
5149 : (trueop1, 0, 0)));
5150 :
5151 : /* Extract a scalar element from a nested VEC_SELECT expression
5152 : (with optional nested VEC_CONCAT expression). Some targets
5153 : (i386) extract scalar element from a vector using chain of
5154 : nested VEC_SELECT expressions. When input operand is a memory
5155 : operand, this operation can be simplified to a simple scalar
5156 : load from an offsetted memory address. */
5157 1092565 : int n_elts;
5158 1092565 : if (GET_CODE (trueop0) == VEC_SELECT
5159 1175634 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
5160 83069 : .is_constant (&n_elts)))
5161 : {
5162 83069 : rtx op0 = XEXP (trueop0, 0);
5163 83069 : rtx op1 = XEXP (trueop0, 1);
5164 :
5165 83069 : int i = INTVAL (XVECEXP (trueop1, 0, 0));
5166 83069 : int elem;
5167 :
5168 83069 : rtvec vec;
5169 83069 : rtx tmp_op, tmp;
5170 :
5171 83069 : gcc_assert (GET_CODE (op1) == PARALLEL);
5172 83069 : gcc_assert (i < XVECLEN (op1, 0));
5173 :
5174 : /* Select element, pointed by nested selector. */
5175 83069 : elem = INTVAL (XVECEXP (op1, 0, i));
5176 :
5177 83069 : gcc_assert (elem < n_elts);
5178 :
5179 : /* Handle the case when nested VEC_SELECT wraps VEC_CONCAT. */
5180 83069 : if (GET_CODE (op0) == VEC_CONCAT)
5181 : {
5182 34101 : rtx op00 = XEXP (op0, 0);
5183 34101 : rtx op01 = XEXP (op0, 1);
5184 :
5185 34101 : machine_mode mode00, mode01;
5186 34101 : int n_elts00, n_elts01;
5187 :
5188 34101 : mode00 = GET_MODE (op00);
5189 34101 : mode01 = GET_MODE (op01);
5190 :
5191 : /* Find out the number of elements of each operand.
5192 : Since the concatenated result has a constant number
5193 : of elements, the operands must too. */
5194 34101 : n_elts00 = GET_MODE_NUNITS (mode00).to_constant ();
5195 34101 : n_elts01 = GET_MODE_NUNITS (mode01).to_constant ();
5196 :
5197 34101 : gcc_assert (n_elts == n_elts00 + n_elts01);
5198 :
5199 : /* Select correct operand of VEC_CONCAT
5200 : and adjust selector. */
5201 34101 : if (elem < n_elts01)
5202 : tmp_op = op00;
5203 : else
5204 : {
5205 453 : tmp_op = op01;
5206 453 : elem -= n_elts00;
5207 : }
5208 : }
5209 : else
5210 : tmp_op = op0;
5211 :
5212 83069 : vec = rtvec_alloc (1);
5213 83069 : RTVEC_ELT (vec, 0) = GEN_INT (elem);
5214 :
5215 83069 : tmp = gen_rtx_fmt_ee (code, mode,
5216 : tmp_op, gen_rtx_PARALLEL (VOIDmode, vec));
5217 83069 : return tmp;
5218 : }
5219 : /* If we select one half of a vec_concat, return that. */
5220 1009496 : else if (GET_CODE (trueop0) == VEC_CONCAT)
5221 : {
5222 1591 : rtx subop0 = XEXP (trueop0, 0);
5223 1591 : rtx subop1 = XEXP (trueop0, 1);
5224 1591 : machine_mode mode0 = GET_MODE (subop0);
5225 1591 : machine_mode mode1 = GET_MODE (subop1);
5226 1591 : int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5227 1591 : if (i0 == 0 && mode == mode0 && !side_effects_p (subop1))
5228 459953007 : return subop0;
5229 1178 : if (known_eq (i0, GET_MODE_NUNITS (mode0))
5230 589 : && mode == mode1 && !side_effects_p (subop0))
5231 : return subop1;
5232 : }
5233 : }
5234 : else
5235 : {
5236 2886991 : gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
5237 8660973 : gcc_assert (GET_MODE_INNER (mode)
5238 : == GET_MODE_INNER (GET_MODE (trueop0)));
5239 2886991 : gcc_assert (GET_CODE (trueop1) == PARALLEL);
5240 :
5241 2886991 : if (vec_duplicate_p (trueop0, &elt0))
5242 : /* It doesn't matter which elements are selected by trueop1,
5243 : because they are all the same. */
5244 17577 : return gen_vec_duplicate (mode, elt0);
5245 :
5246 2869414 : if (GET_CODE (trueop0) == CONST_VECTOR)
5247 : {
5248 17984 : unsigned n_elts = XVECLEN (trueop1, 0);
5249 17984 : rtvec v = rtvec_alloc (n_elts);
5250 17984 : unsigned int i;
5251 :
5252 35968 : gcc_assert (known_eq (n_elts, GET_MODE_NUNITS (mode)));
5253 83606 : for (i = 0; i < n_elts; i++)
5254 : {
5255 65622 : rtx x = XVECEXP (trueop1, 0, i);
5256 :
5257 65622 : if (!CONST_INT_P (x))
5258 : return 0;
5259 :
5260 65622 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0,
5261 : INTVAL (x));
5262 : }
5263 :
5264 17984 : return gen_rtx_CONST_VECTOR (mode, v);
5265 : }
5266 :
5267 : /* Recognize the identity. */
5268 2851430 : if (GET_MODE (trueop0) == mode)
5269 : {
5270 624275 : bool maybe_ident = true;
5271 624275 : for (int i = 0; i < XVECLEN (trueop1, 0); i++)
5272 : {
5273 623878 : rtx j = XVECEXP (trueop1, 0, i);
5274 623878 : if (!CONST_INT_P (j) || INTVAL (j) != i)
5275 : {
5276 : maybe_ident = false;
5277 : break;
5278 : }
5279 : }
5280 388783 : if (maybe_ident)
5281 : return trueop0;
5282 : }
5283 :
5284 : /* If we select a low-part subreg, return that. */
5285 2851033 : if (vec_series_lowpart_p (mode, GET_MODE (trueop0), trueop1))
5286 : {
5287 0 : rtx new_rtx = lowpart_subreg (mode, trueop0,
5288 0 : GET_MODE (trueop0));
5289 0 : if (new_rtx != NULL_RTX)
5290 : return new_rtx;
5291 : }
5292 :
5293 : /* If we build {a,b} then permute it, build the result directly. */
5294 2851033 : if (XVECLEN (trueop1, 0) == 2
5295 606030 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
5296 606030 : && CONST_INT_P (XVECEXP (trueop1, 0, 1))
5297 606030 : && GET_CODE (trueop0) == VEC_CONCAT
5298 178363 : && GET_CODE (XEXP (trueop0, 0)) == VEC_CONCAT
5299 66 : && GET_MODE (XEXP (trueop0, 0)) == mode
5300 66 : && GET_CODE (XEXP (trueop0, 1)) == VEC_CONCAT
5301 55 : && GET_MODE (XEXP (trueop0, 1)) == mode)
5302 : {
5303 55 : unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5304 55 : unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
5305 55 : rtx subop0, subop1;
5306 :
5307 55 : gcc_assert (i0 < 4 && i1 < 4);
5308 55 : subop0 = XEXP (XEXP (trueop0, i0 / 2), i0 % 2);
5309 55 : subop1 = XEXP (XEXP (trueop0, i1 / 2), i1 % 2);
5310 :
5311 55 : return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
5312 : }
5313 :
5314 2850978 : if (XVECLEN (trueop1, 0) == 2
5315 605975 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
5316 605975 : && CONST_INT_P (XVECEXP (trueop1, 0, 1))
5317 605975 : && GET_CODE (trueop0) == VEC_CONCAT
5318 178308 : && GET_MODE (trueop0) == mode)
5319 : {
5320 2 : unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5321 2 : unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
5322 2 : rtx subop0, subop1;
5323 :
5324 2 : gcc_assert (i0 < 2 && i1 < 2);
5325 2 : subop0 = XEXP (trueop0, i0);
5326 2 : subop1 = XEXP (trueop0, i1);
5327 :
5328 2 : return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
5329 : }
5330 :
5331 : /* If we select one half of a vec_concat, return that. */
5332 2850976 : int l0, l1;
5333 2850976 : if (GET_CODE (trueop0) == VEC_CONCAT
5334 3752712 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
5335 1876356 : .is_constant (&l0))
5336 3752712 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 1)))
5337 1876356 : .is_constant (&l1))
5338 4727332 : && CONST_INT_P (XVECEXP (trueop1, 0, 0)))
5339 : {
5340 1876356 : rtx subop0 = XEXP (trueop0, 0);
5341 1876356 : rtx subop1 = XEXP (trueop0, 1);
5342 1876356 : machine_mode mode0 = GET_MODE (subop0);
5343 1876356 : machine_mode mode1 = GET_MODE (subop1);
5344 1876356 : int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5345 1876356 : if (i0 == 0 && !side_effects_p (op1) && mode == mode0)
5346 : {
5347 1423174 : bool success = true;
5348 1423174 : for (int i = 1; i < l0; ++i)
5349 : {
5350 1422848 : rtx j = XVECEXP (trueop1, 0, i);
5351 1422848 : if (!CONST_INT_P (j) || INTVAL (j) != i)
5352 : {
5353 : success = false;
5354 : break;
5355 : }
5356 : }
5357 1212399 : if (success)
5358 : return subop0;
5359 : }
5360 1876030 : if (i0 == l0 && !side_effects_p (op0) && mode == mode1)
5361 : {
5362 1234 : bool success = true;
5363 1234 : for (int i = 1; i < l1; ++i)
5364 : {
5365 1187 : rtx j = XVECEXP (trueop1, 0, i);
5366 1187 : if (!CONST_INT_P (j) || INTVAL (j) != i0 + i)
5367 : {
5368 : success = false;
5369 : break;
5370 : }
5371 : }
5372 560 : if (success)
5373 : return subop1;
5374 : }
5375 : }
5376 :
5377 : /* Simplify vec_select of a subreg of X to just a vec_select of X
5378 : when X has same component mode as vec_select. */
5379 2850603 : unsigned HOST_WIDE_INT subreg_offset = 0;
5380 2850603 : if (GET_CODE (trueop0) == SUBREG
5381 378585 : && GET_MODE_INNER (mode)
5382 757170 : == GET_MODE_INNER (GET_MODE (SUBREG_REG (trueop0)))
5383 29938 : && GET_MODE_NUNITS (mode).is_constant (&l1)
5384 3229188 : && constant_multiple_p (subreg_memory_offset (trueop0),
5385 29938 : GET_MODE_UNIT_BITSIZE (mode),
5386 : &subreg_offset))
5387 : {
5388 14969 : poly_uint64 nunits
5389 29938 : = GET_MODE_NUNITS (GET_MODE (SUBREG_REG (trueop0)));
5390 14969 : bool success = true;
5391 91757 : for (int i = 0; i != l1; i++)
5392 : {
5393 87137 : rtx idx = XVECEXP (trueop1, 0, i);
5394 87137 : if (!CONST_INT_P (idx)
5395 87137 : || maybe_ge (UINTVAL (idx) + subreg_offset, nunits))
5396 : {
5397 : success = false;
5398 : break;
5399 : }
5400 : }
5401 :
5402 14969 : if (success)
5403 : {
5404 4620 : rtx par = trueop1;
5405 4620 : if (subreg_offset)
5406 : {
5407 0 : rtvec vec = rtvec_alloc (l1);
5408 0 : for (int i = 0; i < l1; i++)
5409 0 : RTVEC_ELT (vec, i)
5410 0 : = GEN_INT (INTVAL (XVECEXP (trueop1, 0, i))
5411 : + subreg_offset);
5412 0 : par = gen_rtx_PARALLEL (VOIDmode, vec);
5413 : }
5414 4620 : return gen_rtx_VEC_SELECT (mode, SUBREG_REG (trueop0), par);
5415 : }
5416 : }
5417 : }
5418 :
5419 3854073 : if (XVECLEN (trueop1, 0) == 1
5420 1008174 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
5421 1008174 : && GET_CODE (trueop0) == VEC_CONCAT)
5422 : {
5423 185 : rtx vec = trueop0;
5424 370 : offset = INTVAL (XVECEXP (trueop1, 0, 0)) * GET_MODE_SIZE (mode);
5425 :
5426 : /* Try to find the element in the VEC_CONCAT. */
5427 185 : while (GET_MODE (vec) != mode
5428 370 : && GET_CODE (vec) == VEC_CONCAT)
5429 : {
5430 185 : poly_int64 vec_size;
5431 :
5432 185 : if (CONST_INT_P (XEXP (vec, 0)))
5433 : {
5434 : /* vec_concat of two const_ints doesn't make sense with
5435 : respect to modes. */
5436 0 : if (CONST_INT_P (XEXP (vec, 1)))
5437 459953007 : return 0;
5438 :
5439 0 : vec_size = GET_MODE_SIZE (GET_MODE (trueop0))
5440 0 : - GET_MODE_SIZE (GET_MODE (XEXP (vec, 1)));
5441 : }
5442 : else
5443 370 : vec_size = GET_MODE_SIZE (GET_MODE (XEXP (vec, 0)));
5444 :
5445 185 : if (known_lt (offset, vec_size))
5446 : vec = XEXP (vec, 0);
5447 15 : else if (known_ge (offset, vec_size))
5448 : {
5449 15 : offset -= vec_size;
5450 15 : vec = XEXP (vec, 1);
5451 : }
5452 : else
5453 : break;
5454 185 : vec = avoid_constant_pool_reference (vec);
5455 : }
5456 :
5457 185 : if (GET_MODE (vec) == mode)
5458 : return vec;
5459 : }
5460 :
5461 : /* If we select elements in a vec_merge that all come from the same
5462 : operand, select from that operand directly. */
5463 3854073 : if (GET_CODE (op0) == VEC_MERGE)
5464 : {
5465 9282 : rtx trueop02 = avoid_constant_pool_reference (XEXP (op0, 2));
5466 9282 : if (CONST_INT_P (trueop02))
5467 : {
5468 2871 : unsigned HOST_WIDE_INT sel = UINTVAL (trueop02);
5469 2871 : bool all_operand0 = true;
5470 2871 : bool all_operand1 = true;
5471 10689 : for (int i = 0; i < XVECLEN (trueop1, 0); i++)
5472 : {
5473 7818 : rtx j = XVECEXP (trueop1, 0, i);
5474 7818 : if (sel & (HOST_WIDE_INT_1U << UINTVAL (j)))
5475 : all_operand1 = false;
5476 : else
5477 3504 : all_operand0 = false;
5478 : }
5479 2871 : if (all_operand0 && !side_effects_p (XEXP (op0, 1)))
5480 1340 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 0), op1);
5481 1531 : if (all_operand1 && !side_effects_p (XEXP (op0, 0)))
5482 55 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 1), op1);
5483 : }
5484 : }
5485 :
5486 : /* If we have two nested selects that are inverses of each
5487 : other, replace them with the source operand. */
5488 3852678 : if (GET_CODE (trueop0) == VEC_SELECT
5489 75169 : && GET_MODE (XEXP (trueop0, 0)) == mode)
5490 : {
5491 1041 : rtx op0_subop1 = XEXP (trueop0, 1);
5492 1041 : gcc_assert (GET_CODE (op0_subop1) == PARALLEL);
5493 2082 : gcc_assert (known_eq (XVECLEN (trueop1, 0), GET_MODE_NUNITS (mode)));
5494 : bool identical_p = true;
5495 :
5496 : /* Apply the outer ordering vector to the inner one. (The inner
5497 : ordering vector is expressly permitted to be of a different
5498 : length than the outer one.) If the result is { 0, 1, ..., n-1 }
5499 : then the two VEC_SELECTs cancel. */
5500 9005 : for (int i = 0; i < XVECLEN (trueop1, 0); ++i)
5501 : {
5502 7964 : rtx x = XVECEXP (trueop1, 0, i);
5503 7964 : if (!CONST_INT_P (x))
5504 : return 0;
5505 7964 : rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
5506 7964 : if (!CONST_INT_P (y))
5507 : return 0;
5508 7964 : if (i != INTVAL (y))
5509 5890 : identical_p = false;
5510 : }
5511 1041 : if (identical_p)
5512 : return XEXP (trueop0, 0);
5513 :
5514 : /* Otherwise a permutation of a permutation is a permutation. */
5515 1041 : int len = XVECLEN (trueop1, 0);
5516 1041 : rtvec vec = rtvec_alloc (len);
5517 10046 : for (int i = 0; i < len; ++i)
5518 : {
5519 7964 : rtx x = XVECEXP (trueop1, 0, i);
5520 7964 : rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
5521 7964 : RTVEC_ELT (vec, i) = y;
5522 : }
5523 1041 : return gen_rtx_fmt_ee (code, mode, XEXP (trueop0, 0),
5524 : gen_rtx_PARALLEL (VOIDmode, vec));
5525 : }
5526 :
5527 : return 0;
5528 4129057 : case VEC_CONCAT:
5529 4129057 : {
5530 4129057 : machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
5531 4129057 : ? GET_MODE (trueop0)
5532 4129057 : : GET_MODE_INNER (mode));
5533 4129057 : machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
5534 4129057 : ? GET_MODE (trueop1)
5535 4129057 : : GET_MODE_INNER (mode));
5536 :
5537 4129057 : gcc_assert (VECTOR_MODE_P (mode));
5538 16516228 : gcc_assert (known_eq (GET_MODE_SIZE (op0_mode)
5539 : + GET_MODE_SIZE (op1_mode),
5540 : GET_MODE_SIZE (mode)));
5541 :
5542 4129057 : if (VECTOR_MODE_P (op0_mode))
5543 6402225 : gcc_assert (GET_MODE_INNER (mode)
5544 : == GET_MODE_INNER (op0_mode));
5545 : else
5546 3989964 : gcc_assert (GET_MODE_INNER (mode) == op0_mode);
5547 :
5548 4129057 : if (VECTOR_MODE_P (op1_mode))
5549 6402225 : gcc_assert (GET_MODE_INNER (mode)
5550 : == GET_MODE_INNER (op1_mode));
5551 : else
5552 3989964 : gcc_assert (GET_MODE_INNER (mode) == op1_mode);
5553 :
5554 4129057 : unsigned int n_elts, in_n_elts;
5555 4129057 : if ((GET_CODE (trueop0) == CONST_VECTOR
5556 4129057 : || CONST_SCALAR_INT_P (trueop0)
5557 4099185 : || CONST_DOUBLE_AS_FLOAT_P (trueop0))
5558 31318 : && (GET_CODE (trueop1) == CONST_VECTOR
5559 31318 : || CONST_SCALAR_INT_P (trueop1)
5560 31318 : || CONST_DOUBLE_AS_FLOAT_P (trueop1))
5561 0 : && GET_MODE_NUNITS (mode).is_constant (&n_elts)
5562 4129057 : && GET_MODE_NUNITS (op0_mode).is_constant (&in_n_elts))
5563 : {
5564 0 : rtvec v = rtvec_alloc (n_elts);
5565 0 : unsigned int i;
5566 0 : for (i = 0; i < n_elts; i++)
5567 : {
5568 0 : if (i < in_n_elts)
5569 : {
5570 0 : if (!VECTOR_MODE_P (op0_mode))
5571 0 : RTVEC_ELT (v, i) = trueop0;
5572 : else
5573 0 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
5574 : }
5575 : else
5576 : {
5577 0 : if (!VECTOR_MODE_P (op1_mode))
5578 0 : RTVEC_ELT (v, i) = trueop1;
5579 : else
5580 0 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
5581 : i - in_n_elts);
5582 : }
5583 : }
5584 :
5585 0 : return gen_rtx_CONST_VECTOR (mode, v);
5586 : }
5587 :
5588 : /* Try to merge two VEC_SELECTs from the same vector into a single one.
5589 : Restrict the transformation to avoid generating a VEC_SELECT with a
5590 : mode unrelated to its operand. */
5591 4129057 : if (GET_CODE (trueop0) == VEC_SELECT
5592 178720 : && GET_CODE (trueop1) == VEC_SELECT
5593 36187 : && rtx_equal_p (XEXP (trueop0, 0), XEXP (trueop1, 0))
5594 4147941 : && GET_MODE_INNER (GET_MODE (XEXP (trueop0, 0)))
5595 37768 : == GET_MODE_INNER(mode))
5596 : {
5597 18884 : rtx par0 = XEXP (trueop0, 1);
5598 18884 : rtx par1 = XEXP (trueop1, 1);
5599 18884 : int len0 = XVECLEN (par0, 0);
5600 18884 : int len1 = XVECLEN (par1, 0);
5601 18884 : rtvec vec = rtvec_alloc (len0 + len1);
5602 132598 : for (int i = 0; i < len0; i++)
5603 94830 : RTVEC_ELT (vec, i) = XVECEXP (par0, 0, i);
5604 113714 : for (int i = 0; i < len1; i++)
5605 94830 : RTVEC_ELT (vec, len0 + i) = XVECEXP (par1, 0, i);
5606 18884 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (trueop0, 0),
5607 18884 : gen_rtx_PARALLEL (VOIDmode, vec));
5608 : }
5609 : /* (vec_concat:N
5610 : (subreg:N/2 OP 0)
5611 : (subreg:N/2 OP N/2)) --> OP
5612 : i.e. where concatenating the first and second halves of the
5613 : same object OP. */
5614 4110173 : {
5615 4110173 : poly_uint64 offset = 0u;
5616 4110173 : rtx base0 = get_ref_base_and_offset (trueop0, &offset);
5617 4110173 : if (known_eq (offset, 0u)
5618 12328755 : && known_eq (GET_MODE_SIZE (GET_MODE (base0)),
5619 : GET_MODE_SIZE (mode)))
5620 : {
5621 68275 : rtx base1 = get_ref_base_and_offset (trueop1, &offset);
5622 68275 : if (rtx_equal_p (base0, base1)
5623 1188 : && known_eq (offset, GET_MODE_SIZE (op0_mode))
5624 1147 : && !side_effects_p (trueop0)
5625 69422 : && !side_effects_p (trueop1))
5626 1147 : return gen_lowpart (mode, base0);
5627 : }
5628 : }
5629 : }
5630 4109026 : return 0;
5631 :
5632 0 : default:
5633 0 : gcc_unreachable ();
5634 : }
5635 :
5636 386322111 : if (mode == GET_MODE (op0)
5637 331473848 : && mode == GET_MODE (op1)
5638 104909435 : && vec_duplicate_p (op0, &elt0)
5639 386448209 : && vec_duplicate_p (op1, &elt1))
5640 : {
5641 : /* Try applying the operator to ELT and see if that simplifies.
5642 : We can duplicate the result if so.
5643 :
5644 : The reason we don't use simplify_gen_binary is that it isn't
5645 : necessarily a win to convert things like:
5646 :
5647 : (plus:V (vec_duplicate:V (reg:S R1))
5648 : (vec_duplicate:V (reg:S R2)))
5649 :
5650 : to:
5651 :
5652 : (vec_duplicate:V (plus:S (reg:S R1) (reg:S R2)))
5653 :
5654 : The first might be done entirely in vector registers while the
5655 : second might need a move between register files. */
5656 164 : tem = simplify_binary_operation (code, GET_MODE_INNER (mode),
5657 : elt0, elt1);
5658 82 : if (tem)
5659 2 : return gen_vec_duplicate (mode, tem);
5660 : }
5661 :
5662 : return 0;
5663 : }
5664 :
5665 : /* Return true if binary operation OP distributes over addition in operand
5666 : OPNO, with the other operand being held constant. OPNO counts from 1. */
5667 :
5668 : static bool
5669 8225 : distributes_over_addition_p (rtx_code op, int opno)
5670 : {
5671 0 : switch (op)
5672 : {
5673 : case PLUS:
5674 : case MINUS:
5675 : case MULT:
5676 : return true;
5677 :
5678 0 : case ASHIFT:
5679 0 : return opno == 1;
5680 :
5681 0 : default:
5682 0 : return false;
5683 : }
5684 : }
5685 :
5686 : rtx
5687 494195245 : simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
5688 : rtx op0, rtx op1)
5689 : {
5690 494195245 : if (VECTOR_MODE_P (mode)
5691 15738888 : && code != VEC_CONCAT
5692 11594979 : && GET_CODE (op0) == CONST_VECTOR
5693 183571 : && GET_CODE (op1) == CONST_VECTOR)
5694 : {
5695 8934 : bool step_ok_p;
5696 8934 : if (CONST_VECTOR_STEPPED_P (op0)
5697 8934 : && CONST_VECTOR_STEPPED_P (op1))
5698 : /* We can operate directly on the encoding if:
5699 :
5700 : a3 - a2 == a2 - a1 && b3 - b2 == b2 - b1
5701 : implies
5702 : (a3 op b3) - (a2 op b2) == (a2 op b2) - (a1 op b1)
5703 :
5704 : Addition and subtraction are the supported operators
5705 : for which this is true. */
5706 709 : step_ok_p = (code == PLUS || code == MINUS);
5707 8225 : else if (CONST_VECTOR_STEPPED_P (op0))
5708 : /* We can operate directly on stepped encodings if:
5709 :
5710 : a3 - a2 == a2 - a1
5711 : implies:
5712 : (a3 op c) - (a2 op c) == (a2 op c) - (a1 op c)
5713 :
5714 : which is true if (x -> x op c) distributes over addition. */
5715 1307 : step_ok_p = distributes_over_addition_p (code, 1);
5716 : else
5717 : /* Similarly in reverse. */
5718 6918 : step_ok_p = distributes_over_addition_p (code, 2);
5719 8934 : rtx_vector_builder builder;
5720 8934 : if (!builder.new_binary_operation (mode, op0, op1, step_ok_p))
5721 : return 0;
5722 :
5723 8934 : unsigned int count = builder.encoded_nelts ();
5724 54835 : for (unsigned int i = 0; i < count; i++)
5725 : {
5726 91902 : rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
5727 : CONST_VECTOR_ELT (op0, i),
5728 45951 : CONST_VECTOR_ELT (op1, i));
5729 45951 : if (!x || !valid_for_const_vector_p (mode, x))
5730 50 : return 0;
5731 45901 : builder.quick_push (x);
5732 : }
5733 8884 : return builder.build ();
5734 8934 : }
5735 :
5736 494186311 : if (VECTOR_MODE_P (mode)
5737 15729954 : && code == VEC_CONCAT
5738 4143909 : && (CONST_SCALAR_INT_P (op0)
5739 4119868 : || CONST_FIXED_P (op0)
5740 4119868 : || CONST_DOUBLE_AS_FLOAT_P (op0)
5741 4116052 : || CONST_VECTOR_P (op0))
5742 46170 : && (CONST_SCALAR_INT_P (op1)
5743 42559 : || CONST_DOUBLE_AS_FLOAT_P (op1)
5744 40189 : || CONST_FIXED_P (op1)
5745 40189 : || CONST_VECTOR_P (op1)))
5746 : {
5747 : /* Both inputs have a constant number of elements, so the result
5748 : must too. */
5749 14852 : unsigned n_elts = GET_MODE_NUNITS (mode).to_constant ();
5750 14852 : rtvec v = rtvec_alloc (n_elts);
5751 :
5752 14852 : gcc_assert (n_elts >= 2);
5753 14852 : if (n_elts == 2)
5754 : {
5755 5981 : gcc_assert (GET_CODE (op0) != CONST_VECTOR);
5756 5981 : gcc_assert (GET_CODE (op1) != CONST_VECTOR);
5757 :
5758 5981 : RTVEC_ELT (v, 0) = op0;
5759 5981 : RTVEC_ELT (v, 1) = op1;
5760 : }
5761 : else
5762 : {
5763 8871 : unsigned op0_n_elts = GET_MODE_NUNITS (GET_MODE (op0)).to_constant ();
5764 8871 : unsigned op1_n_elts = GET_MODE_NUNITS (GET_MODE (op1)).to_constant ();
5765 8871 : unsigned i;
5766 :
5767 8871 : gcc_assert (GET_CODE (op0) == CONST_VECTOR);
5768 8871 : gcc_assert (GET_CODE (op1) == CONST_VECTOR);
5769 8871 : gcc_assert (op0_n_elts + op1_n_elts == n_elts);
5770 :
5771 53773 : for (i = 0; i < op0_n_elts; ++i)
5772 44902 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op0, i);
5773 53965 : for (i = 0; i < op1_n_elts; ++i)
5774 45094 : RTVEC_ELT (v, op0_n_elts+i) = CONST_VECTOR_ELT (op1, i);
5775 : }
5776 :
5777 14852 : return gen_rtx_CONST_VECTOR (mode, v);
5778 : }
5779 :
5780 481824562 : if (VECTOR_MODE_P (mode)
5781 15715102 : && GET_CODE (op0) == CONST_VECTOR
5782 184079 : && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1))
5783 494171459 : && (CONST_VECTOR_DUPLICATE_P (op0)
5784 120920 : || CONST_VECTOR_NUNITS (op0).is_constant ()))
5785 : {
5786 120920 : switch (code)
5787 : {
5788 120920 : case PLUS:
5789 120920 : case MINUS:
5790 120920 : case MULT:
5791 120920 : case DIV:
5792 120920 : case MOD:
5793 120920 : case UDIV:
5794 120920 : case UMOD:
5795 120920 : case AND:
5796 120920 : case IOR:
5797 120920 : case XOR:
5798 120920 : case SMIN:
5799 120920 : case SMAX:
5800 120920 : case UMIN:
5801 120920 : case UMAX:
5802 120920 : case LSHIFTRT:
5803 120920 : case ASHIFTRT:
5804 120920 : case ASHIFT:
5805 120920 : case ROTATE:
5806 120920 : case ROTATERT:
5807 120920 : case SS_PLUS:
5808 120920 : case US_PLUS:
5809 120920 : case SS_MINUS:
5810 120920 : case US_MINUS:
5811 120920 : case SS_ASHIFT:
5812 120920 : case US_ASHIFT:
5813 120920 : case COPYSIGN:
5814 120920 : break;
5815 : default:
5816 : return NULL_RTX;
5817 : }
5818 :
5819 120920 : unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op0)
5820 120920 : ? CONST_VECTOR_NPATTERNS (op0)
5821 128849 : : CONST_VECTOR_NUNITS (op0).to_constant ());
5822 120920 : rtx_vector_builder builder (mode, npatterns, 1);
5823 375849 : for (unsigned i = 0; i < npatterns; i++)
5824 : {
5825 268018 : rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
5826 134009 : CONST_VECTOR_ELT (op0, i), op1);
5827 134009 : if (!x || !valid_for_const_vector_p (mode, x))
5828 0 : return 0;
5829 134009 : builder.quick_push (x);
5830 : }
5831 120920 : return builder.build ();
5832 : }
5833 :
5834 494050539 : if (SCALAR_FLOAT_MODE_P (mode)
5835 6454235 : && CONST_DOUBLE_AS_FLOAT_P (op0)
5836 76676 : && CONST_DOUBLE_AS_FLOAT_P (op1)
5837 11614 : && mode == GET_MODE (op0) && mode == GET_MODE (op1))
5838 : {
5839 11614 : if (code == AND
5840 : || code == IOR
5841 11614 : || code == XOR)
5842 : {
5843 2538 : long tmp0[4];
5844 2538 : long tmp1[4];
5845 2538 : REAL_VALUE_TYPE r;
5846 2538 : int i;
5847 :
5848 2538 : real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0),
5849 2538 : GET_MODE (op0));
5850 2538 : real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1),
5851 2538 : GET_MODE (op1));
5852 12690 : for (i = 0; i < 4; i++)
5853 : {
5854 10152 : switch (code)
5855 : {
5856 5272 : case AND:
5857 5272 : tmp0[i] &= tmp1[i];
5858 5272 : break;
5859 2512 : case IOR:
5860 2512 : tmp0[i] |= tmp1[i];
5861 2512 : break;
5862 2368 : case XOR:
5863 2368 : tmp0[i] ^= tmp1[i];
5864 2368 : break;
5865 : default:
5866 : gcc_unreachable ();
5867 : }
5868 : }
5869 2538 : real_from_target (&r, tmp0, mode);
5870 2538 : return const_double_from_real_value (r, mode);
5871 : }
5872 9076 : else if (code == COPYSIGN)
5873 : {
5874 0 : REAL_VALUE_TYPE f0, f1;
5875 0 : real_convert (&f0, mode, CONST_DOUBLE_REAL_VALUE (op0));
5876 0 : real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (op1));
5877 0 : real_copysign (&f0, &f1);
5878 0 : return const_double_from_real_value (f0, mode);
5879 : }
5880 : else
5881 : {
5882 9076 : REAL_VALUE_TYPE f0, f1, value, result;
5883 9076 : const REAL_VALUE_TYPE *opr0, *opr1;
5884 9076 : bool inexact;
5885 :
5886 9076 : opr0 = CONST_DOUBLE_REAL_VALUE (op0);
5887 9076 : opr1 = CONST_DOUBLE_REAL_VALUE (op1);
5888 :
5889 9076 : if (HONOR_SNANS (mode)
5890 9076 : && (REAL_VALUE_ISSIGNALING_NAN (*opr0)
5891 803 : || REAL_VALUE_ISSIGNALING_NAN (*opr1)))
5892 : return 0;
5893 :
5894 9066 : real_convert (&f0, mode, opr0);
5895 9066 : real_convert (&f1, mode, opr1);
5896 :
5897 9066 : if (code == DIV
5898 4160 : && real_equal (&f1, &dconst0)
5899 12708 : && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
5900 : return 0;
5901 :
5902 27041 : if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
5903 5338 : && flag_trapping_math
5904 5260 : && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
5905 : {
5906 9 : int s0 = REAL_VALUE_NEGATIVE (f0);
5907 9 : int s1 = REAL_VALUE_NEGATIVE (f1);
5908 :
5909 9 : switch (code)
5910 : {
5911 0 : case PLUS:
5912 : /* Inf + -Inf = NaN plus exception. */
5913 0 : if (s0 != s1)
5914 : return 0;
5915 : break;
5916 0 : case MINUS:
5917 : /* Inf - Inf = NaN plus exception. */
5918 0 : if (s0 == s1)
5919 : return 0;
5920 : break;
5921 : case DIV:
5922 : /* Inf / Inf = NaN plus exception. */
5923 : return 0;
5924 : default:
5925 : break;
5926 : }
5927 : }
5928 :
5929 7930 : if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
5930 1947 : && flag_trapping_math
5931 7318 : && ((REAL_VALUE_ISINF (f0) && real_equal (&f1, &dconst0))
5932 1891 : || (REAL_VALUE_ISINF (f1)
5933 10 : && real_equal (&f0, &dconst0))))
5934 : /* Inf * 0 = NaN plus exception. */
5935 : return 0;
5936 :
5937 5401 : inexact = real_arithmetic (&value, rtx_to_tree_code (code),
5938 : &f0, &f1);
5939 5401 : real_convert (&result, mode, &value);
5940 :
5941 : /* Don't constant fold this floating point operation if
5942 : the result has overflowed and flag_trapping_math. */
5943 :
5944 5401 : if (flag_trapping_math
5945 20932 : && MODE_HAS_INFINITIES (mode)
5946 5233 : && REAL_VALUE_ISINF (result)
5947 1141 : && !REAL_VALUE_ISINF (f0)
5948 6528 : && !REAL_VALUE_ISINF (f1))
5949 : /* Overflow plus exception. */
5950 1127 : return 0;
5951 :
5952 : /* Don't constant fold this floating point operation if the
5953 : result may dependent upon the run-time rounding mode and
5954 : flag_rounding_math is set, or if GCC's software emulation
5955 : is unable to accurately represent the result. */
5956 :
5957 4274 : if ((flag_rounding_math
5958 27615 : || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
5959 4274 : && (inexact || !real_identical (&result, &value)))
5960 : return NULL_RTX;
5961 :
5962 3896 : return const_double_from_real_value (result, mode);
5963 : }
5964 : }
5965 :
5966 : /* We can fold some multi-word operations. */
5967 494038925 : scalar_int_mode int_mode;
5968 494038925 : if (is_a <scalar_int_mode> (mode, &int_mode)
5969 422862549 : && CONST_SCALAR_INT_P (op0)
5970 41121929 : && CONST_SCALAR_INT_P (op1)
5971 34093456 : && GET_MODE_PRECISION (int_mode) <= MAX_BITSIZE_MODE_ANY_INT)
5972 : {
5973 34093456 : wide_int result;
5974 34093456 : wi::overflow_type overflow;
5975 34093456 : rtx_mode_t pop0 = rtx_mode_t (op0, int_mode);
5976 34093456 : rtx_mode_t pop1 = rtx_mode_t (op1, int_mode);
5977 :
5978 : #if TARGET_SUPPORTS_WIDE_INT == 0
5979 : /* This assert keeps the simplification from producing a result
5980 : that cannot be represented in a CONST_DOUBLE but a lot of
5981 : upstream callers expect that this function never fails to
5982 : simplify something and so you if you added this to the test
5983 : above the code would die later anyway. If this assert
5984 : happens, you just need to make the port support wide int. */
5985 : gcc_assert (GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_DOUBLE_INT);
5986 : #endif
5987 34093456 : switch (code)
5988 : {
5989 1091288 : case MINUS:
5990 1091288 : result = wi::sub (pop0, pop1);
5991 1091288 : break;
5992 :
5993 26644255 : case PLUS:
5994 26644255 : result = wi::add (pop0, pop1);
5995 26644255 : break;
5996 :
5997 320535 : case MULT:
5998 320535 : result = wi::mul (pop0, pop1);
5999 320535 : break;
6000 :
6001 8944 : case DIV:
6002 8944 : result = wi::div_trunc (pop0, pop1, SIGNED, &overflow);
6003 8944 : if (overflow)
6004 : return NULL_RTX;
6005 : break;
6006 :
6007 1197 : case MOD:
6008 1197 : result = wi::mod_trunc (pop0, pop1, SIGNED, &overflow);
6009 1197 : if (overflow)
6010 : return NULL_RTX;
6011 : break;
6012 :
6013 6261 : case UDIV:
6014 6261 : result = wi::div_trunc (pop0, pop1, UNSIGNED, &overflow);
6015 6261 : if (overflow)
6016 : return NULL_RTX;
6017 : break;
6018 :
6019 16269 : case UMOD:
6020 16269 : result = wi::mod_trunc (pop0, pop1, UNSIGNED, &overflow);
6021 16269 : if (overflow)
6022 : return NULL_RTX;
6023 : break;
6024 :
6025 754665 : case AND:
6026 754665 : result = wi::bit_and (pop0, pop1);
6027 754665 : break;
6028 :
6029 260454 : case IOR:
6030 260454 : result = wi::bit_or (pop0, pop1);
6031 260454 : break;
6032 :
6033 44314 : case XOR:
6034 44314 : result = wi::bit_xor (pop0, pop1);
6035 44314 : break;
6036 :
6037 1763 : case SMIN:
6038 1763 : result = wi::smin (pop0, pop1);
6039 1763 : break;
6040 :
6041 1989 : case SMAX:
6042 1989 : result = wi::smax (pop0, pop1);
6043 1989 : break;
6044 :
6045 3219 : case UMIN:
6046 3219 : result = wi::umin (pop0, pop1);
6047 3219 : break;
6048 :
6049 3010 : case UMAX:
6050 3010 : result = wi::umax (pop0, pop1);
6051 3010 : break;
6052 :
6053 4894790 : case LSHIFTRT:
6054 4894790 : case ASHIFTRT:
6055 4894790 : case ASHIFT:
6056 4894790 : case SS_ASHIFT:
6057 4894790 : case US_ASHIFT:
6058 4894790 : {
6059 : /* The shift count might be in SImode while int_mode might
6060 : be narrower. On IA-64 it is even DImode. If the shift
6061 : count is too large and doesn't fit into int_mode, we'd
6062 : ICE. So, if int_mode is narrower than
6063 : HOST_BITS_PER_WIDE_INT, use DImode for the shift count. */
6064 4894790 : if (GET_MODE (op1) == VOIDmode
6065 4894790 : && GET_MODE_PRECISION (int_mode) < HOST_BITS_PER_WIDE_INT)
6066 1854774 : pop1 = rtx_mode_t (op1, DImode);
6067 :
6068 4894790 : wide_int wop1 = pop1;
6069 4894790 : if (SHIFT_COUNT_TRUNCATED)
6070 : wop1 = wi::umod_trunc (wop1, GET_MODE_PRECISION (int_mode));
6071 4894790 : else if (wi::geu_p (wop1, GET_MODE_PRECISION (int_mode)))
6072 64 : return NULL_RTX;
6073 :
6074 4894726 : switch (code)
6075 : {
6076 2782392 : case LSHIFTRT:
6077 2782392 : result = wi::lrshift (pop0, wop1);
6078 2782392 : break;
6079 :
6080 82125 : case ASHIFTRT:
6081 82125 : result = wi::arshift (pop0, wop1);
6082 82125 : break;
6083 :
6084 2030209 : case ASHIFT:
6085 2030209 : result = wi::lshift (pop0, wop1);
6086 2030209 : break;
6087 :
6088 0 : case SS_ASHIFT:
6089 0 : if (wi::leu_p (wop1, wi::clrsb (pop0)))
6090 0 : result = wi::lshift (pop0, wop1);
6091 0 : else if (wi::neg_p (pop0))
6092 0 : result = wi::min_value (int_mode, SIGNED);
6093 : else
6094 0 : result = wi::max_value (int_mode, SIGNED);
6095 : break;
6096 :
6097 0 : case US_ASHIFT:
6098 0 : if (wi::eq_p (pop0, 0))
6099 0 : result = pop0;
6100 0 : else if (wi::leu_p (wop1, wi::clz (pop0)))
6101 0 : result = wi::lshift (pop0, wop1);
6102 : else
6103 0 : result = wi::max_value (int_mode, UNSIGNED);
6104 : break;
6105 :
6106 : default:
6107 : gcc_unreachable ();
6108 : }
6109 4894726 : break;
6110 4894790 : }
6111 31557 : case ROTATE:
6112 31557 : case ROTATERT:
6113 31557 : {
6114 : /* The rotate count might be in SImode while int_mode might
6115 : be narrower. On IA-64 it is even DImode. If the shift
6116 : count is too large and doesn't fit into int_mode, we'd
6117 : ICE. So, if int_mode is narrower than
6118 : HOST_BITS_PER_WIDE_INT, use DImode for the shift count. */
6119 31557 : if (GET_MODE (op1) == VOIDmode
6120 31557 : && GET_MODE_PRECISION (int_mode) < HOST_BITS_PER_WIDE_INT)
6121 23779 : pop1 = rtx_mode_t (op1, DImode);
6122 :
6123 31557 : if (wi::neg_p (pop1))
6124 : return NULL_RTX;
6125 :
6126 31457 : switch (code)
6127 : {
6128 10469 : case ROTATE:
6129 10469 : result = wi::lrotate (pop0, pop1);
6130 10469 : break;
6131 :
6132 20988 : case ROTATERT:
6133 20988 : result = wi::rrotate (pop0, pop1);
6134 20988 : break;
6135 :
6136 : default:
6137 : gcc_unreachable ();
6138 : }
6139 : break;
6140 : }
6141 :
6142 2270 : case SS_PLUS:
6143 2270 : result = wi::add (pop0, pop1, SIGNED, &overflow);
6144 4484 : clamp_signed_saturation:
6145 4484 : if (overflow == wi::OVF_OVERFLOW)
6146 314 : result = wi::max_value (GET_MODE_PRECISION (int_mode), SIGNED);
6147 4170 : else if (overflow == wi::OVF_UNDERFLOW)
6148 278 : result = wi::min_value (GET_MODE_PRECISION (int_mode), SIGNED);
6149 3892 : else if (overflow != wi::OVF_NONE)
6150 : return NULL_RTX;
6151 : break;
6152 :
6153 2388 : case US_PLUS:
6154 2388 : result = wi::add (pop0, pop1, UNSIGNED, &overflow);
6155 2388 : clamp_unsigned_saturation:
6156 2388 : if (overflow != wi::OVF_NONE)
6157 502 : result = wi::max_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
6158 : break;
6159 :
6160 2214 : case SS_MINUS:
6161 2214 : result = wi::sub (pop0, pop1, SIGNED, &overflow);
6162 2214 : goto clamp_signed_saturation;
6163 :
6164 2068 : case US_MINUS:
6165 2068 : result = wi::sub (pop0, pop1, UNSIGNED, &overflow);
6166 2068 : if (overflow != wi::OVF_NONE)
6167 1350 : result = wi::min_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
6168 : break;
6169 :
6170 0 : case SS_MULT:
6171 0 : result = wi::mul (pop0, pop1, SIGNED, &overflow);
6172 0 : goto clamp_signed_saturation;
6173 :
6174 0 : case US_MULT:
6175 0 : result = wi::mul (pop0, pop1, UNSIGNED, &overflow);
6176 0 : goto clamp_unsigned_saturation;
6177 :
6178 6 : case SMUL_HIGHPART:
6179 6 : result = wi::mul_high (pop0, pop1, SIGNED);
6180 6 : break;
6181 :
6182 0 : case UMUL_HIGHPART:
6183 0 : result = wi::mul_high (pop0, pop1, UNSIGNED);
6184 0 : break;
6185 :
6186 : default:
6187 : return NULL_RTX;
6188 : }
6189 34091148 : return immed_wide_int_const (result, int_mode);
6190 34093456 : }
6191 :
6192 : /* Handle polynomial integers. */
6193 : if (NUM_POLY_INT_COEFFS > 1
6194 : && is_a <scalar_int_mode> (mode, &int_mode)
6195 : && poly_int_rtx_p (op0)
6196 : && poly_int_rtx_p (op1))
6197 : {
6198 : poly_wide_int result;
6199 : switch (code)
6200 : {
6201 : case PLUS:
6202 : result = wi::to_poly_wide (op0, mode) + wi::to_poly_wide (op1, mode);
6203 : break;
6204 :
6205 : case MINUS:
6206 : result = wi::to_poly_wide (op0, mode) - wi::to_poly_wide (op1, mode);
6207 : break;
6208 :
6209 : case MULT:
6210 : if (CONST_SCALAR_INT_P (op1))
6211 : result = wi::to_poly_wide (op0, mode) * rtx_mode_t (op1, mode);
6212 : else
6213 : return NULL_RTX;
6214 : break;
6215 :
6216 : case ASHIFT:
6217 : if (CONST_SCALAR_INT_P (op1))
6218 : {
6219 : wide_int shift
6220 : = rtx_mode_t (op1,
6221 : GET_MODE (op1) == VOIDmode
6222 : && (GET_MODE_PRECISION (int_mode)
6223 : < HOST_BITS_PER_WIDE_INT)
6224 : ? DImode : mode);
6225 : if (SHIFT_COUNT_TRUNCATED)
6226 : shift = wi::umod_trunc (shift, GET_MODE_PRECISION (int_mode));
6227 : else if (wi::geu_p (shift, GET_MODE_PRECISION (int_mode)))
6228 : return NULL_RTX;
6229 : result = wi::to_poly_wide (op0, mode) << shift;
6230 : }
6231 : else
6232 : return NULL_RTX;
6233 : break;
6234 :
6235 : case IOR:
6236 : if (!CONST_SCALAR_INT_P (op1)
6237 : || !can_ior_p (wi::to_poly_wide (op0, mode),
6238 : rtx_mode_t (op1, mode), &result))
6239 : return NULL_RTX;
6240 : break;
6241 :
6242 : default:
6243 : return NULL_RTX;
6244 : }
6245 : return immed_wide_int_const (result, int_mode);
6246 : }
6247 :
6248 : return NULL_RTX;
6249 : }
6250 :
6251 :
6252 :
6253 : /* Return a positive integer if X should sort after Y. The value
6254 : returned is 1 if and only if X and Y are both regs. */
6255 :
6256 : static int
6257 116752546 : simplify_plus_minus_op_data_cmp (rtx x, rtx y)
6258 : {
6259 116752546 : int result;
6260 :
6261 116752546 : result = (commutative_operand_precedence (y)
6262 116752546 : - commutative_operand_precedence (x));
6263 116752546 : if (result)
6264 81441504 : return result + result;
6265 :
6266 : /* Group together equal REGs to do more simplification. */
6267 35311042 : if (REG_P (x) && REG_P (y))
6268 8657746 : return REGNO (x) > REGNO (y);
6269 :
6270 : return 0;
6271 : }
6272 :
6273 : /* Simplify and canonicalize a PLUS or MINUS, at least one of whose
6274 : operands may be another PLUS or MINUS.
6275 :
6276 : Rather than test for specific case, we do this by a brute-force method
6277 : and do all possible simplifications until no more changes occur. Then
6278 : we rebuild the operation.
6279 :
6280 : May return NULL_RTX when no changes were made. */
6281 :
6282 : rtx
6283 39340361 : simplify_context::simplify_plus_minus (rtx_code code, machine_mode mode,
6284 : rtx op0, rtx op1)
6285 : {
6286 39340361 : struct simplify_plus_minus_op_data
6287 : {
6288 : rtx op;
6289 : short neg;
6290 : } ops[16];
6291 39340361 : rtx result, tem;
6292 39340361 : int n_ops = 2;
6293 39340361 : int changed, n_constants, canonicalized = 0;
6294 39340361 : int i, j;
6295 :
6296 39340361 : memset (ops, 0, sizeof ops);
6297 :
6298 : /* Set up the two operands and then expand them until nothing has been
6299 : changed. If we run out of room in our array, give up; this should
6300 : almost never happen. */
6301 :
6302 39340361 : ops[0].op = op0;
6303 39340361 : ops[0].neg = 0;
6304 39340361 : ops[1].op = op1;
6305 39340361 : ops[1].neg = (code == MINUS);
6306 :
6307 79991802 : do
6308 : {
6309 79991802 : changed = 0;
6310 79991802 : n_constants = 0;
6311 :
6312 323787489 : for (i = 0; i < n_ops; i++)
6313 : {
6314 243795703 : rtx this_op = ops[i].op;
6315 243795703 : int this_neg = ops[i].neg;
6316 243795703 : enum rtx_code this_code = GET_CODE (this_op);
6317 :
6318 243795703 : switch (this_code)
6319 : {
6320 39658056 : case PLUS:
6321 39658056 : case MINUS:
6322 39658056 : if (n_ops == ARRAY_SIZE (ops))
6323 : return NULL_RTX;
6324 :
6325 39658040 : ops[n_ops].op = XEXP (this_op, 1);
6326 39658040 : ops[n_ops].neg = (this_code == MINUS) ^ this_neg;
6327 39658040 : n_ops++;
6328 :
6329 39658040 : ops[i].op = XEXP (this_op, 0);
6330 39658040 : changed = 1;
6331 : /* If this operand was negated then we will potentially
6332 : canonicalize the expression. Similarly if we don't
6333 : place the operands adjacent we're re-ordering the
6334 : expression and thus might be performing a
6335 : canonicalization. Ignore register re-ordering.
6336 : ??? It might be better to shuffle the ops array here,
6337 : but then (plus (plus (A, B), plus (C, D))) wouldn't
6338 : be seen as non-canonical. */
6339 39658040 : if (this_neg
6340 38956756 : || (i != n_ops - 2
6341 38347457 : && !(REG_P (ops[i].op) && REG_P (ops[n_ops - 1].op))))
6342 243795687 : canonicalized = 1;
6343 : break;
6344 :
6345 2155 : case NEG:
6346 2155 : ops[i].op = XEXP (this_op, 0);
6347 2155 : ops[i].neg = ! this_neg;
6348 2155 : changed = 1;
6349 2155 : canonicalized = 1;
6350 2155 : break;
6351 :
6352 1606084 : case CONST:
6353 1606084 : if (n_ops != ARRAY_SIZE (ops)
6354 1606084 : && GET_CODE (XEXP (this_op, 0)) == PLUS
6355 1472552 : && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
6356 1451776 : && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
6357 : {
6358 1451776 : ops[i].op = XEXP (XEXP (this_op, 0), 0);
6359 1451776 : ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
6360 1451776 : ops[n_ops].neg = this_neg;
6361 1451776 : n_ops++;
6362 1451776 : changed = 1;
6363 1451776 : canonicalized = 1;
6364 : }
6365 : break;
6366 :
6367 66866 : case NOT:
6368 : /* ~a -> (-a - 1) */
6369 66866 : if (n_ops != ARRAY_SIZE (ops))
6370 : {
6371 66866 : ops[n_ops].op = CONSTM1_RTX (mode);
6372 66866 : ops[n_ops++].neg = this_neg;
6373 66866 : ops[i].op = XEXP (this_op, 0);
6374 66866 : ops[i].neg = !this_neg;
6375 66866 : changed = 1;
6376 66866 : canonicalized = 1;
6377 : }
6378 : break;
6379 :
6380 121741213 : CASE_CONST_SCALAR_INT:
6381 121741213 : case CONST_POLY_INT:
6382 121741213 : n_constants++;
6383 121741213 : if (this_neg)
6384 : {
6385 1212725 : ops[i].op = neg_poly_int_rtx (mode, this_op);
6386 1212725 : ops[i].neg = 0;
6387 1212725 : changed = 1;
6388 1212725 : canonicalized = 1;
6389 : }
6390 : break;
6391 :
6392 : default:
6393 : break;
6394 : }
6395 : }
6396 : }
6397 79991786 : while (changed);
6398 :
6399 39340345 : if (n_constants > 1)
6400 24165881 : canonicalized = 1;
6401 :
6402 39340345 : gcc_assert (n_ops >= 2);
6403 :
6404 : /* If we only have two operands, we can avoid the loops. */
6405 39340345 : if (n_ops == 2)
6406 : {
6407 0 : enum rtx_code code = ops[0].neg || ops[1].neg ? MINUS : PLUS;
6408 0 : rtx lhs, rhs;
6409 :
6410 : /* Get the two operands. Be careful with the order, especially for
6411 : the cases where code == MINUS. */
6412 0 : if (ops[0].neg && ops[1].neg)
6413 : {
6414 0 : lhs = gen_rtx_NEG (mode, ops[0].op);
6415 0 : rhs = ops[1].op;
6416 : }
6417 0 : else if (ops[0].neg)
6418 : {
6419 0 : lhs = ops[1].op;
6420 0 : rhs = ops[0].op;
6421 : }
6422 : else
6423 : {
6424 0 : lhs = ops[0].op;
6425 0 : rhs = ops[1].op;
6426 : }
6427 :
6428 0 : return simplify_const_binary_operation (code, mode, lhs, rhs);
6429 : }
6430 :
6431 : /* Now simplify each pair of operands until nothing changes. */
6432 64507702 : while (1)
6433 : {
6434 : /* Insertion sort is good enough for a small array. */
6435 170634089 : for (i = 1; i < n_ops; i++)
6436 : {
6437 106126387 : struct simplify_plus_minus_op_data save;
6438 106126387 : int cmp;
6439 :
6440 106126387 : j = i - 1;
6441 106126387 : cmp = simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op);
6442 106126387 : if (cmp <= 0)
6443 93406632 : continue;
6444 : /* Just swapping registers doesn't count as canonicalization. */
6445 12719755 : if (cmp != 1)
6446 9767735 : canonicalized = 1;
6447 :
6448 12719755 : save = ops[i];
6449 15097119 : do
6450 15097119 : ops[j + 1] = ops[j];
6451 15097119 : while (j--
6452 27816874 : && simplify_plus_minus_op_data_cmp (ops[j].op, save.op) > 0);
6453 12719755 : ops[j + 1] = save;
6454 : }
6455 :
6456 64507702 : changed = 0;
6457 170634089 : for (i = n_ops - 1; i > 0; i--)
6458 254589558 : for (j = i - 1; j >= 0; j--)
6459 : {
6460 149357705 : rtx lhs = ops[j].op, rhs = ops[i].op;
6461 149357705 : int lneg = ops[j].neg, rneg = ops[i].neg;
6462 :
6463 149357705 : if (lhs != 0 && rhs != 0)
6464 : {
6465 123446895 : enum rtx_code ncode = PLUS;
6466 :
6467 123446895 : if (lneg != rneg)
6468 : {
6469 11694003 : ncode = MINUS;
6470 11694003 : if (lneg)
6471 7378729 : std::swap (lhs, rhs);
6472 : }
6473 111752892 : else if (swap_commutative_operands_p (lhs, rhs))
6474 419274 : std::swap (lhs, rhs);
6475 :
6476 123446895 : if ((GET_CODE (lhs) == CONST || CONST_INT_P (lhs))
6477 29128035 : && (GET_CODE (rhs) == CONST || CONST_INT_P (rhs)))
6478 : {
6479 24320115 : rtx tem_lhs, tem_rhs;
6480 :
6481 24320115 : tem_lhs = GET_CODE (lhs) == CONST ? XEXP (lhs, 0) : lhs;
6482 24320115 : tem_rhs = GET_CODE (rhs) == CONST ? XEXP (rhs, 0) : rhs;
6483 24320115 : tem = simplify_binary_operation (ncode, mode, tem_lhs,
6484 : tem_rhs);
6485 :
6486 24320115 : if (tem && !CONSTANT_P (tem))
6487 1751 : tem = gen_rtx_CONST (GET_MODE (tem), tem);
6488 : }
6489 : else
6490 99126780 : tem = simplify_binary_operation (ncode, mode, lhs, rhs);
6491 :
6492 99128531 : if (tem)
6493 : {
6494 : /* Reject "simplifications" that just wrap the two
6495 : arguments in a CONST. Failure to do so can result
6496 : in infinite recursion with simplify_binary_operation
6497 : when it calls us to simplify CONST operations.
6498 : Also, if we find such a simplification, don't try
6499 : any more combinations with this rhs: We must have
6500 : something like symbol+offset, ie. one of the
6501 : trivial CONST expressions we handle later. */
6502 26498643 : if (GET_CODE (tem) == CONST
6503 896285 : && GET_CODE (XEXP (tem, 0)) == ncode
6504 895734 : && XEXP (XEXP (tem, 0), 0) == lhs
6505 894534 : && XEXP (XEXP (tem, 0), 1) == rhs)
6506 : break;
6507 25604109 : lneg &= rneg;
6508 25604109 : if (GET_CODE (tem) == NEG)
6509 45153 : tem = XEXP (tem, 0), lneg = !lneg;
6510 25604109 : if (poly_int_rtx_p (tem) && lneg)
6511 0 : tem = neg_poly_int_rtx (mode, tem), lneg = 0;
6512 :
6513 25604109 : ops[i].op = tem;
6514 25604109 : ops[i].neg = lneg;
6515 25604109 : ops[j].op = NULL_RTX;
6516 25604109 : changed = 1;
6517 25604109 : canonicalized = 1;
6518 : }
6519 : }
6520 : }
6521 :
6522 64507702 : if (!changed)
6523 : break;
6524 :
6525 : /* Pack all the operands to the lower-numbered entries. */
6526 101548407 : for (i = 0, j = 0; j < n_ops; j++)
6527 76381050 : if (ops[j].op)
6528 : {
6529 50776941 : ops[i] = ops[j];
6530 50776941 : i++;
6531 : }
6532 : n_ops = i;
6533 : }
6534 :
6535 : /* If nothing changed, check that rematerialization of rtl instructions
6536 : is still required. */
6537 39340345 : if (!canonicalized)
6538 : {
6539 : /* Perform rematerialization if only all operands are registers and
6540 : all operations are PLUS. */
6541 : /* ??? Also disallow (non-global, non-frame) fixed registers to work
6542 : around rs6000 and how it uses the CA register. See PR67145. */
6543 4926058 : for (i = 0; i < n_ops; i++)
6544 3968964 : if (ops[i].neg
6545 3684395 : || !REG_P (ops[i].op)
6546 7149282 : || (REGNO (ops[i].op) < FIRST_PSEUDO_REGISTER
6547 306988 : && fixed_regs[REGNO (ops[i].op)]
6548 235 : && !global_regs[REGNO (ops[i].op)]
6549 235 : && ops[i].op != frame_pointer_rtx
6550 109 : && ops[i].op != arg_pointer_rtx
6551 99 : && ops[i].op != stack_pointer_rtx))
6552 : return NULL_RTX;
6553 957094 : goto gen_result;
6554 : }
6555 :
6556 : /* Create (minus -C X) instead of (neg (const (plus X C))). */
6557 37594605 : if (n_ops == 2
6558 23592750 : && CONST_INT_P (ops[1].op)
6559 22926600 : && CONSTANT_P (ops[0].op)
6560 162 : && ops[0].neg)
6561 56 : return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
6562 :
6563 : /* We suppressed creation of trivial CONST expressions in the
6564 : combination loop to avoid recursion. Create one manually now.
6565 : The combination loop should have ensured that there is exactly
6566 : one CONST_INT, and the sort will have ensured that it is last
6567 : in the array and that any other constant will be next-to-last. */
6568 :
6569 37594549 : if (n_ops > 1
6570 37091837 : && poly_int_rtx_p (ops[n_ops - 1].op)
6571 71971573 : && CONSTANT_P (ops[n_ops - 2].op))
6572 : {
6573 1526399 : rtx value = ops[n_ops - 1].op;
6574 1526399 : if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg)
6575 710230 : value = neg_poly_int_rtx (mode, value);
6576 1526399 : if (CONST_INT_P (value))
6577 : {
6578 3052798 : ops[n_ops - 2].op = plus_constant (mode, ops[n_ops - 2].op,
6579 1526399 : INTVAL (value));
6580 1526399 : n_ops--;
6581 : }
6582 : }
6583 :
6584 : /* Put a non-negated operand first, if possible. */
6585 :
6586 39340683 : for (i = 0; i < n_ops && ops[i].neg; i++)
6587 1746134 : continue;
6588 37594549 : if (i == n_ops)
6589 8680 : ops[0].op = gen_rtx_NEG (mode, ops[0].op);
6590 37585869 : else if (i != 0)
6591 : {
6592 1640240 : tem = ops[0].op;
6593 1640240 : ops[0] = ops[i];
6594 1640240 : ops[i].op = tem;
6595 1640240 : ops[i].neg = 1;
6596 : }
6597 :
6598 : /* Now make the result by performing the requested operations. */
6599 35945629 : gen_result:
6600 38551643 : result = ops[0].op;
6601 90351877 : for (i = 1; i < n_ops; i++)
6602 103600468 : result = gen_rtx_fmt_ee (ops[i].neg ? MINUS : PLUS,
6603 : mode, result, ops[i].op);
6604 :
6605 : return result;
6606 1746134 : }
6607 :
6608 : /* Check whether an operand is suitable for calling simplify_plus_minus. */
6609 : static bool
6610 536536418 : plus_minus_operand_p (const_rtx x)
6611 : {
6612 536536418 : return GET_CODE (x) == PLUS
6613 536536418 : || GET_CODE (x) == MINUS
6614 536536418 : || (GET_CODE (x) == CONST
6615 1967487 : && GET_CODE (XEXP (x, 0)) == PLUS
6616 1343904 : && CONSTANT_P (XEXP (XEXP (x, 0), 0))
6617 1270730 : && CONSTANT_P (XEXP (XEXP (x, 0), 1)));
6618 : }
6619 :
6620 : /* Like simplify_binary_operation except used for relational operators.
6621 : MODE is the mode of the result. If MODE is VOIDmode, both operands must
6622 : not also be VOIDmode.
6623 :
6624 : CMP_MODE specifies in which mode the comparison is done in, so it is
6625 : the mode of the operands. If CMP_MODE is VOIDmode, it is taken from
6626 : the operands or, if both are VOIDmode, the operands are compared in
6627 : "infinite precision". */
6628 : rtx
6629 132202702 : simplify_context::simplify_relational_operation (rtx_code code,
6630 : machine_mode mode,
6631 : machine_mode cmp_mode,
6632 : rtx op0, rtx op1)
6633 : {
6634 132202702 : rtx tem, trueop0, trueop1;
6635 :
6636 132202702 : if (cmp_mode == VOIDmode)
6637 29184262 : cmp_mode = GET_MODE (op0);
6638 29184262 : if (cmp_mode == VOIDmode)
6639 253268 : cmp_mode = GET_MODE (op1);
6640 :
6641 132202702 : tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
6642 132202702 : if (tem)
6643 785061 : return relational_result (mode, cmp_mode, tem);
6644 :
6645 : /* For the following tests, ensure const0_rtx is op1. */
6646 131417641 : if (swap_commutative_operands_p (op0, op1)
6647 131417641 : || (op0 == const0_rtx && op1 != const0_rtx))
6648 2625493 : std::swap (op0, op1), code = swap_condition (code);
6649 :
6650 : /* If op0 is a compare, extract the comparison arguments from it. */
6651 131417641 : if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
6652 14292474 : return simplify_gen_relational (code, mode, VOIDmode,
6653 14292474 : XEXP (op0, 0), XEXP (op0, 1));
6654 :
6655 117125167 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
6656 : return NULL_RTX;
6657 :
6658 85939757 : trueop0 = avoid_constant_pool_reference (op0);
6659 85939757 : trueop1 = avoid_constant_pool_reference (op1);
6660 85939757 : return simplify_relational_operation_1 (code, mode, cmp_mode,
6661 85939757 : trueop0, trueop1);
6662 : }
6663 :
6664 : /* This part of simplify_relational_operation is only used when CMP_MODE
6665 : is not in class MODE_CC (i.e. it is a real comparison).
6666 :
6667 : MODE is the mode of the result, while CMP_MODE specifies in which
6668 : mode the comparison is done in, so it is the mode of the operands. */
6669 :
6670 : rtx
6671 85939757 : simplify_context::simplify_relational_operation_1 (rtx_code code,
6672 : machine_mode mode,
6673 : machine_mode cmp_mode,
6674 : rtx op0, rtx op1)
6675 : {
6676 85939757 : enum rtx_code op0code = GET_CODE (op0);
6677 :
6678 85939757 : if (op1 == const0_rtx && COMPARISON_P (op0))
6679 : {
6680 : /* If op0 is a comparison, extract the comparison arguments
6681 : from it. */
6682 301547 : if (code == NE)
6683 : {
6684 134099 : if (GET_MODE (op0) == mode)
6685 178 : return simplify_rtx (op0);
6686 : else
6687 133921 : return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
6688 133921 : XEXP (op0, 0), XEXP (op0, 1));
6689 : }
6690 167448 : else if (code == EQ)
6691 : {
6692 135013 : enum rtx_code new_code = reversed_comparison_code (op0, NULL);
6693 135013 : if (new_code != UNKNOWN)
6694 134696 : return simplify_gen_relational (new_code, mode, VOIDmode,
6695 134696 : XEXP (op0, 0), XEXP (op0, 1));
6696 : }
6697 : }
6698 :
6699 : /* (LTU/GEU (PLUS a C) C), where C is constant, can be simplified to
6700 : (GEU/LTU a -C). Likewise for (LTU/GEU (PLUS a C) a). */
6701 85670962 : if ((code == LTU || code == GEU)
6702 5170416 : && GET_CODE (op0) == PLUS
6703 639410 : && CONST_INT_P (XEXP (op0, 1))
6704 420860 : && (rtx_equal_p (op1, XEXP (op0, 0))
6705 281872 : || rtx_equal_p (op1, XEXP (op0, 1)))
6706 : /* (LTU/GEU (PLUS a 0) 0) is not the same as (GEU/LTU a 0). */
6707 85873341 : && XEXP (op0, 1) != const0_rtx)
6708 : {
6709 202379 : rtx new_cmp
6710 202379 : = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
6711 203934 : return simplify_gen_relational ((code == LTU ? GEU : LTU), mode,
6712 202379 : cmp_mode, XEXP (op0, 0), new_cmp);
6713 : }
6714 :
6715 : /* (GTU (PLUS a C) (C - 1)) where C is a non-zero constant can be
6716 : transformed into (LTU a -C). */
6717 85468583 : if (code == GTU && GET_CODE (op0) == PLUS && CONST_INT_P (op1)
6718 322502 : && CONST_INT_P (XEXP (op0, 1))
6719 242216 : && (UINTVAL (op1) == UINTVAL (XEXP (op0, 1)) - 1)
6720 20188 : && XEXP (op0, 1) != const0_rtx)
6721 : {
6722 20188 : rtx new_cmp
6723 20188 : = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
6724 20188 : return simplify_gen_relational (LTU, mode, cmp_mode,
6725 20188 : XEXP (op0, 0), new_cmp);
6726 : }
6727 :
6728 : /* Canonicalize (LTU/GEU (PLUS a b) b) as (LTU/GEU (PLUS a b) a). */
6729 85448395 : if ((code == LTU || code == GEU)
6730 4968037 : && GET_CODE (op0) == PLUS
6731 437031 : && rtx_equal_p (op1, XEXP (op0, 1))
6732 : /* Don't recurse "infinitely" for (LTU/GEU (PLUS b b) b). */
6733 85455208 : && !rtx_equal_p (op1, XEXP (op0, 0)))
6734 6813 : return simplify_gen_relational (code, mode, cmp_mode, op0,
6735 6813 : copy_rtx (XEXP (op0, 0)));
6736 :
6737 85441582 : if (op1 == const0_rtx)
6738 : {
6739 : /* Canonicalize (GTU x 0) as (NE x 0). */
6740 37367552 : if (code == GTU)
6741 76759 : return simplify_gen_relational (NE, mode, cmp_mode, op0, op1);
6742 : /* Canonicalize (LEU x 0) as (EQ x 0). */
6743 37290793 : if (code == LEU)
6744 33128 : return simplify_gen_relational (EQ, mode, cmp_mode, op0, op1);
6745 :
6746 37257665 : if ((code == NE || code == EQ)
6747 : /* Verify op0 is IOR */
6748 33490475 : && GET_CODE (op0) == IOR
6749 : /* only enters if op1 is 0 */
6750 : /* Verify IOR operand is NE */
6751 605880 : && GET_CODE (XEXP (op0, 0)) == NE
6752 21547 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) == cmp_mode
6753 : /* Verify second NE operand is 0 */
6754 374 : && XEXP (XEXP (op0, 0), 1) == CONST0_RTX (cmp_mode))
6755 : {
6756 31 : rtx t = gen_rtx_IOR (cmp_mode, XEXP (XEXP (op0, 0), 0), XEXP (op0, 1));
6757 31 : t = gen_rtx_fmt_ee (code, mode, t, CONST0_RTX (mode));
6758 31 : return t;
6759 : }
6760 :
6761 : }
6762 48074030 : else if (op1 == const1_rtx)
6763 : {
6764 3278109 : switch (code)
6765 : {
6766 10099 : case GE:
6767 : /* Canonicalize (GE x 1) as (GT x 0). */
6768 10099 : return simplify_gen_relational (GT, mode, cmp_mode,
6769 10099 : op0, const0_rtx);
6770 194880 : case GEU:
6771 : /* Canonicalize (GEU x 1) as (NE x 0). */
6772 194880 : return simplify_gen_relational (NE, mode, cmp_mode,
6773 194880 : op0, const0_rtx);
6774 10590 : case LT:
6775 : /* Canonicalize (LT x 1) as (LE x 0). */
6776 10590 : return simplify_gen_relational (LE, mode, cmp_mode,
6777 10590 : op0, const0_rtx);
6778 54332 : case LTU:
6779 : /* Canonicalize (LTU x 1) as (EQ x 0). */
6780 54332 : return simplify_gen_relational (EQ, mode, cmp_mode,
6781 54332 : op0, const0_rtx);
6782 : default:
6783 : break;
6784 : }
6785 : }
6786 44795921 : else if (op1 == constm1_rtx)
6787 : {
6788 : /* Canonicalize (LE x -1) as (LT x 0). */
6789 1162047 : if (code == LE)
6790 1566 : return simplify_gen_relational (LT, mode, cmp_mode, op0, const0_rtx);
6791 : /* Canonicalize (GT x -1) as (GE x 0). */
6792 1160481 : if (code == GT)
6793 5138 : return simplify_gen_relational (GE, mode, cmp_mode, op0, const0_rtx);
6794 : }
6795 :
6796 : /* (eq/ne (plus x cst1) cst2) simplifies to (eq/ne x (cst2 - cst1)) */
6797 81287869 : if ((code == EQ || code == NE)
6798 63335573 : && (op0code == PLUS || op0code == MINUS)
6799 2519729 : && CONSTANT_P (op1)
6800 920373 : && CONSTANT_P (XEXP (op0, 1))
6801 511395 : && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
6802 : {
6803 511361 : rtx x = XEXP (op0, 0);
6804 511361 : rtx c = XEXP (op0, 1);
6805 511361 : enum rtx_code invcode = op0code == PLUS ? MINUS : PLUS;
6806 511361 : rtx tem = simplify_gen_binary (invcode, cmp_mode, op1, c);
6807 :
6808 : /* Detect an infinite recursive condition, where we oscillate at this
6809 : simplification case between:
6810 : A + B == C <---> C - B == A,
6811 : where A, B, and C are all constants with non-simplifiable expressions,
6812 : usually SYMBOL_REFs. */
6813 511361 : if (GET_CODE (tem) == invcode
6814 57 : && CONSTANT_P (x)
6815 511379 : && rtx_equal_p (c, XEXP (tem, 1)))
6816 : return NULL_RTX;
6817 :
6818 511343 : return simplify_gen_relational (code, mode, cmp_mode, x, tem);
6819 : }
6820 :
6821 : /* (eq/ne (plus (x) (y)) y) simplifies to (eq/ne x 0). */
6822 62824212 : if ((code == EQ || code == NE)
6823 62824212 : && op0code == PLUS
6824 1656988 : && rtx_equal_p (XEXP (op0, 1), op1)
6825 248 : && !side_effects_p (op1)
6826 248 : && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
6827 224 : return simplify_gen_relational (code, mode, cmp_mode,
6828 224 : XEXP (op0, 0), CONST0_RTX (cmp_mode));
6829 :
6830 : /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is
6831 : the same as (zero_extract:SI FOO (const_int 1) BAR). */
6832 84543474 : scalar_int_mode int_mode, int_cmp_mode;
6833 84543474 : if (code == NE
6834 33833181 : && op1 == const0_rtx
6835 2284892 : && is_int_mode (mode, &int_mode)
6836 86753236 : && is_a <scalar_int_mode> (cmp_mode, &int_cmp_mode)
6837 : /* ??? Work-around BImode bugs in the ia64 backend. */
6838 2284892 : && int_mode != BImode
6839 2284872 : && int_cmp_mode != BImode
6840 2284872 : && nonzero_bits (op0, int_cmp_mode) == 1
6841 84543474 : && STORE_FLAG_VALUE == 1)
6842 150260 : return GET_MODE_SIZE (int_mode) > GET_MODE_SIZE (int_cmp_mode)
6843 75130 : ? simplify_gen_unary (ZERO_EXTEND, int_mode, op0, int_cmp_mode)
6844 19066 : : lowpart_subreg (int_mode, op0, int_cmp_mode);
6845 :
6846 : /* (eq/ne (xor x y) 0) simplifies to (eq/ne x y). */
6847 84468344 : if ((code == EQ || code == NE)
6848 62748858 : && op1 == const0_rtx
6849 33340348 : && op0code == XOR)
6850 14346 : return simplify_gen_relational (code, mode, cmp_mode,
6851 14346 : XEXP (op0, 0), XEXP (op0, 1));
6852 :
6853 : /* (eq/ne (xor x y) x) simplifies to (eq/ne y 0). */
6854 62734512 : if ((code == EQ || code == NE)
6855 62734512 : && op0code == XOR
6856 5199 : && rtx_equal_p (XEXP (op0, 0), op1)
6857 6 : && !side_effects_p (XEXP (op0, 0)))
6858 0 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 1),
6859 0 : CONST0_RTX (mode));
6860 :
6861 : /* Likewise (eq/ne (xor x y) y) simplifies to (eq/ne x 0). */
6862 84453998 : if ((code == EQ || code == NE)
6863 62734512 : && op0code == XOR
6864 5199 : && rtx_equal_p (XEXP (op0, 1), op1)
6865 84454166 : && !side_effects_p (XEXP (op0, 1)))
6866 168 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6867 168 : CONST0_RTX (mode));
6868 :
6869 : /* (eq/ne (xor x C1) C2) simplifies to (eq/ne x (C1^C2)). */
6870 84453830 : if ((code == EQ || code == NE)
6871 62734344 : && op0code == XOR
6872 5031 : && CONST_SCALAR_INT_P (op1)
6873 1432 : && CONST_SCALAR_INT_P (XEXP (op0, 1)))
6874 868 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6875 : simplify_gen_binary (XOR, cmp_mode,
6876 868 : XEXP (op0, 1), op1));
6877 :
6878 : /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or
6879 : constant folding if x/y is a constant. */
6880 62733476 : if ((code == EQ || code == NE)
6881 62733476 : && (op0code == AND || op0code == IOR)
6882 3636534 : && !side_effects_p (op1)
6883 3636428 : && op1 != CONST0_RTX (cmp_mode))
6884 : {
6885 : /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to
6886 : (eq/ne (and (not y) x) 0). */
6887 466440 : if ((op0code == AND && rtx_equal_p (XEXP (op0, 0), op1))
6888 935167 : || (op0code == IOR && rtx_equal_p (XEXP (op0, 1), op1)))
6889 : {
6890 24759 : rtx not_y = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 1),
6891 : cmp_mode);
6892 24759 : rtx lhs = simplify_gen_binary (AND, cmp_mode, not_y, XEXP (op0, 0));
6893 :
6894 24759 : return simplify_gen_relational (code, mode, cmp_mode, lhs,
6895 24759 : CONST0_RTX (cmp_mode));
6896 : }
6897 :
6898 : /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to
6899 : (eq/ne (and (not x) y) 0). */
6900 441783 : if ((op0code == AND && rtx_equal_p (XEXP (op0, 1), op1))
6901 865693 : || (op0code == IOR && rtx_equal_p (XEXP (op0, 0), op1)))
6902 : {
6903 44719 : rtx not_x = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 0),
6904 : cmp_mode);
6905 44719 : rtx lhs = simplify_gen_binary (AND, cmp_mode, not_x, XEXP (op0, 1));
6906 :
6907 44719 : return simplify_gen_relational (code, mode, cmp_mode, lhs,
6908 44719 : CONST0_RTX (cmp_mode));
6909 : }
6910 : }
6911 :
6912 : /* Optimize (cmp (and/ior x C1) C2) depending on the CMP and C1 and C2's
6913 : relationship. */
6914 84383484 : if ((op0code == AND || op0code == IOR)
6915 3817198 : && CONST_INT_P (op1)
6916 3636616 : && CONST_INT_P (XEXP (op0, 1)))
6917 : {
6918 2349186 : unsigned HOST_WIDE_INT c1 = UINTVAL (XEXP (op0, 1));
6919 2349186 : unsigned HOST_WIDE_INT c2 = UINTVAL (op1);
6920 :
6921 : /* For AND operations:
6922 : - (x & c1) == c2 when some bits are set in c2 but not in c1 -> false
6923 : - (x & c1) != c2 when some bits are set in c2 but not in c1 -> true
6924 : - (x & c1) >= c2 when c1 is less than c2 -> false
6925 : - (x & c1) < c2 when c1 is less than c2 -> true
6926 : - (x & c1) > c2 when c1 is less than or equal to c2 -> false
6927 : - (x & c1) <= c2 when c1 is less than or equal to c2 -> true
6928 :
6929 : For IOR operations:
6930 : - (x | c1) == c2 when some bits are set in c1 but not in c2 -> false
6931 : - (x | c1) != c2 when some bits are set in c1 but not in c2 -> true
6932 : - (x | c1) <= c2 when c1 is greater than c2 -> false
6933 : - (x | c1) > c2 when c1 is greater than c2 -> true
6934 : - (x | c1) < c2 when c1 is greater than or equal to c2 -> false
6935 : - (x | c1) >= c2 when c1 is greater than or equal to c2 -> true */
6936 2349186 : if ((op0code == AND
6937 2344848 : && ((code == EQ && (c1 & c2) != c2)
6938 2344831 : || (code == GEU && c1 < c2)
6939 2344831 : || (code == GTU && c1 <= c2)))
6940 2349169 : || ((op0code == IOR
6941 4338 : && ((code == EQ && (c1 & c2) != c1)
6942 4334 : || (code == LEU && c1 > c2)
6943 4334 : || (code == LTU && c1 >= c2)))))
6944 21 : return const0_rtx;
6945 :
6946 2349165 : if ((op0code == AND
6947 2344831 : && ((code == NE && (c1 & c2) != c2)
6948 2344748 : || (code == LTU && c1 < c2)
6949 2344748 : || (code == LEU && c1 <= c2)))
6950 2349082 : || ((op0code == IOR
6951 4334 : && ((code == NE && (c1 & c2) != c1)
6952 4274 : || (code == GTU && c1 > c2)
6953 4274 : || (code == GEU && c1 >= c2)))))
6954 143 : return const_true_rtx;
6955 : }
6956 :
6957 : /* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped. */
6958 84383320 : if ((code == EQ || code == NE)
6959 62663834 : && GET_CODE (op0) == BSWAP
6960 316 : && CONST_SCALAR_INT_P (op1))
6961 85 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6962 : simplify_gen_unary (BSWAP, cmp_mode,
6963 85 : op1, cmp_mode));
6964 :
6965 : /* (eq/ne (bswap x) (bswap y)) simplifies to (eq/ne x y). */
6966 62663749 : if ((code == EQ || code == NE)
6967 62663749 : && GET_CODE (op0) == BSWAP
6968 231 : && GET_CODE (op1) == BSWAP)
6969 18 : return simplify_gen_relational (code, mode, cmp_mode,
6970 18 : XEXP (op0, 0), XEXP (op1, 0));
6971 :
6972 84383217 : if (op0code == POPCOUNT && op1 == const0_rtx)
6973 0 : switch (code)
6974 : {
6975 0 : case EQ:
6976 0 : case LE:
6977 0 : case LEU:
6978 : /* (eq (popcount x) (const_int 0)) -> (eq x (const_int 0)). */
6979 0 : return simplify_gen_relational (EQ, mode, GET_MODE (XEXP (op0, 0)),
6980 : XEXP (op0, 0),
6981 0 : CONST0_RTX (GET_MODE (XEXP (op0, 0))));
6982 :
6983 0 : case NE:
6984 0 : case GT:
6985 0 : case GTU:
6986 : /* (ne (popcount x) (const_int 0)) -> (ne x (const_int 0)). */
6987 0 : return simplify_gen_relational (NE, mode, GET_MODE (XEXP (op0, 0)),
6988 : XEXP (op0, 0),
6989 0 : CONST0_RTX (GET_MODE (XEXP (op0, 0))));
6990 :
6991 : default:
6992 : break;
6993 : }
6994 :
6995 : /* (ne:SI (subreg:QI (ashift:SI x 7) 0) 0) -> (and:SI x 1). */
6996 84383217 : if (code == NE
6997 33714495 : && op1 == const0_rtx
6998 17448298 : && (op0code == TRUNCATE
6999 155274 : || (partial_subreg_p (op0)
7000 154547 : && subreg_lowpart_p (op0)))
7001 131522 : && SCALAR_INT_MODE_P (mode)
7002 84383217 : && STORE_FLAG_VALUE == 1)
7003 : {
7004 34796 : rtx tmp = XEXP (op0, 0);
7005 34796 : if (GET_CODE (tmp) == ASHIFT
7006 2706 : && GET_MODE (tmp) == mode
7007 241 : && CONST_INT_P (XEXP (tmp, 1))
7008 241 : && is_int_mode (GET_MODE (op0), &int_mode)
7009 35037 : && INTVAL (XEXP (tmp, 1)) == GET_MODE_PRECISION (int_mode) - 1)
7010 241 : return simplify_gen_binary (AND, mode, XEXP (tmp, 0), const1_rtx);
7011 : }
7012 :
7013 : /* For two unsigned booleans A and B:
7014 :
7015 : A > B == ~B & A
7016 : A >= B == ~B | A
7017 : A < B == ~A & B
7018 : A <= B == ~A | B
7019 : A == B == ~A ^ B (== ~B ^ A)
7020 : A != B == A ^ B
7021 :
7022 : For signed comparisons, we have to take STORE_FLAG_VALUE into account,
7023 : with the rules above applying for positive STORE_FLAG_VALUE and with
7024 : the relations reversed for negative STORE_FLAG_VALUE. */
7025 84382976 : if (is_a<scalar_int_mode> (cmp_mode)
7026 81629704 : && COMPARISON_P (op0)
7027 84497566 : && COMPARISON_P (op1))
7028 : {
7029 9881 : rtx t = NULL_RTX;
7030 9881 : if (code == GTU || code == (STORE_FLAG_VALUE > 0 ? GT : LT))
7031 723 : t = simplify_logical_relational_operation (AND, mode, op1, op0, true);
7032 : else if (code == GEU || code == (STORE_FLAG_VALUE > 0 ? GE : LE))
7033 720 : t = simplify_logical_relational_operation (IOR, mode, op1, op0, true);
7034 : else if (code == LTU || code == (STORE_FLAG_VALUE > 0 ? LT : GT))
7035 720 : t = simplify_logical_relational_operation (AND, mode, op0, op1, true);
7036 : else if (code == LEU || code == (STORE_FLAG_VALUE > 0 ? LE : GE))
7037 720 : t = simplify_logical_relational_operation (IOR, mode, op0, op1, true);
7038 : else if (code == EQ)
7039 3152 : t = simplify_logical_relational_operation (XOR, mode, op0, op1, true);
7040 : else if (code == NE)
7041 3846 : t = simplify_logical_relational_operation (XOR, mode, op0, op1);
7042 : if (t)
7043 : return t;
7044 : }
7045 :
7046 : return NULL_RTX;
7047 : }
7048 :
7049 : enum
7050 : {
7051 : CMP_EQ = 1,
7052 : CMP_LT = 2,
7053 : CMP_GT = 4,
7054 : CMP_LTU = 8,
7055 : CMP_GTU = 16
7056 : };
7057 :
7058 :
7059 : /* Convert the known results for EQ, LT, GT, LTU, GTU contained in
7060 : KNOWN_RESULT to a CONST_INT, based on the requested comparison CODE
7061 : For KNOWN_RESULT to make sense it should be either CMP_EQ, or the
7062 : logical OR of one of (CMP_LT, CMP_GT) and one of (CMP_LTU, CMP_GTU).
7063 : For floating-point comparisons, assume that the operands were ordered. */
7064 :
7065 : static rtx
7066 722395 : comparison_result (enum rtx_code code, int known_results)
7067 : {
7068 722395 : switch (code)
7069 : {
7070 131925 : case EQ:
7071 131925 : case UNEQ:
7072 131925 : return (known_results & CMP_EQ) ? const_true_rtx : const0_rtx;
7073 450663 : case NE:
7074 450663 : case LTGT:
7075 450663 : return (known_results & CMP_EQ) ? const0_rtx : const_true_rtx;
7076 :
7077 9380 : case LT:
7078 9380 : case UNLT:
7079 9380 : return (known_results & CMP_LT) ? const_true_rtx : const0_rtx;
7080 8683 : case GE:
7081 8683 : case UNGE:
7082 8683 : return (known_results & CMP_LT) ? const0_rtx : const_true_rtx;
7083 :
7084 12754 : case GT:
7085 12754 : case UNGT:
7086 12754 : return (known_results & CMP_GT) ? const_true_rtx : const0_rtx;
7087 15229 : case LE:
7088 15229 : case UNLE:
7089 15229 : return (known_results & CMP_GT) ? const0_rtx : const_true_rtx;
7090 :
7091 25051 : case LTU:
7092 25051 : return (known_results & CMP_LTU) ? const_true_rtx : const0_rtx;
7093 8846 : case GEU:
7094 8846 : return (known_results & CMP_LTU) ? const0_rtx : const_true_rtx;
7095 :
7096 49449 : case GTU:
7097 49449 : return (known_results & CMP_GTU) ? const_true_rtx : const0_rtx;
7098 10349 : case LEU:
7099 10349 : return (known_results & CMP_GTU) ? const0_rtx : const_true_rtx;
7100 :
7101 0 : case ORDERED:
7102 0 : return const_true_rtx;
7103 66 : case UNORDERED:
7104 66 : return const0_rtx;
7105 0 : default:
7106 0 : gcc_unreachable ();
7107 : }
7108 : }
7109 :
7110 : /* Check if the given comparison (done in the given MODE) is actually
7111 : a tautology or a contradiction. If the mode is VOIDmode, the
7112 : comparison is done in "infinite precision". If no simplification
7113 : is possible, this function returns zero. Otherwise, it returns
7114 : either const_true_rtx or const0_rtx. */
7115 :
7116 : rtx
7117 132292846 : simplify_const_relational_operation (enum rtx_code code,
7118 : machine_mode mode,
7119 : rtx op0, rtx op1)
7120 : {
7121 139351884 : rtx tem;
7122 139351884 : rtx trueop0;
7123 139351884 : rtx trueop1;
7124 :
7125 139351884 : gcc_assert (mode != VOIDmode
7126 : || (GET_MODE (op0) == VOIDmode
7127 : && GET_MODE (op1) == VOIDmode));
7128 :
7129 : /* We only handle MODE_CC comparisons that are COMPARE against zero. */
7130 139351884 : if (GET_MODE_CLASS (mode) == MODE_CC
7131 45484976 : && (op1 != const0_rtx
7132 45484976 : || GET_CODE (op0) != COMPARE))
7133 : return NULL_RTX;
7134 :
7135 : /* If op0 is a compare, extract the comparison arguments from it. */
7136 108166474 : if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
7137 : {
7138 14299566 : op1 = XEXP (op0, 1);
7139 14299566 : op0 = XEXP (op0, 0);
7140 :
7141 14299566 : if (GET_MODE (op0) != VOIDmode)
7142 14169648 : mode = GET_MODE (op0);
7143 129918 : else if (GET_MODE (op1) != VOIDmode)
7144 97447 : mode = GET_MODE (op1);
7145 : else
7146 : return 0;
7147 : }
7148 :
7149 : /* We can't simplify MODE_CC values since we don't know what the
7150 : actual comparison is. */
7151 108134003 : if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
7152 : return 0;
7153 :
7154 : /* Make sure the constant is second. */
7155 108134003 : if (swap_commutative_operands_p (op0, op1))
7156 : {
7157 3008072 : std::swap (op0, op1);
7158 3008072 : code = swap_condition (code);
7159 : }
7160 :
7161 108134003 : trueop0 = avoid_constant_pool_reference (op0);
7162 108134003 : trueop1 = avoid_constant_pool_reference (op1);
7163 :
7164 : /* For integer comparisons of A and B maybe we can simplify A - B and can
7165 : then simplify a comparison of that with zero. If A and B are both either
7166 : a register or a CONST_INT, this can't help; testing for these cases will
7167 : prevent infinite recursion here and speed things up.
7168 :
7169 : We can only do this for EQ and NE comparisons as otherwise we may
7170 : lose or introduce overflow which we cannot disregard as undefined as
7171 : we do not know the signedness of the operation on either the left or
7172 : the right hand side of the comparison. */
7173 :
7174 108134003 : if (INTEGRAL_MODE_P (mode)
7175 105428010 : && trueop1 != CONST0_RTX (mode)
7176 54368919 : && (code == EQ || code == NE)
7177 34549531 : && ! ((REG_P (op0)
7178 10120286 : || CONST_SCALAR_INT_P (trueop0)
7179 10092203 : || CONST_VECTOR_P (trueop0))
7180 24457348 : && (REG_P (op1)
7181 14683600 : || CONST_SCALAR_INT_P (trueop1)
7182 3436443 : || CONST_VECTOR_P (trueop1)))
7183 13525639 : && (tem = simplify_binary_operation (MINUS, mode, op0, op1)) != 0
7184 : /* We cannot do this if tem is a nonzero address. */
7185 7059040 : && ! nonzero_address_p (tem))
7186 7059038 : return simplify_const_relational_operation (signed_condition (code),
7187 7059038 : mode, tem, CONST0_RTX (mode));
7188 :
7189 101074965 : if (! HONOR_NANS (mode) && code == ORDERED)
7190 0 : return const_true_rtx;
7191 :
7192 101074965 : if (! HONOR_NANS (mode) && code == UNORDERED)
7193 8 : return const0_rtx;
7194 :
7195 : /* For modes without NaNs, if the two operands are equal, we know the
7196 : result except if they have side-effects. Even with NaNs we know
7197 : the result of unordered comparisons and, if signaling NaNs are
7198 : irrelevant, also the result of LT/GT/LTGT. */
7199 101074957 : if ((! HONOR_NANS (trueop0)
7200 2214413 : || code == UNEQ || code == UNLE || code == UNGE
7201 : || ((code == LT || code == GT || code == LTGT)
7202 919532 : && ! HONOR_SNANS (trueop0)))
7203 99887167 : && rtx_equal_p (trueop0, trueop1)
7204 101590143 : && ! side_effects_p (trueop0))
7205 515093 : return comparison_result (code, CMP_EQ);
7206 :
7207 : /* If the operands are floating-point constants, see if we can fold
7208 : the result. */
7209 100559864 : if (CONST_DOUBLE_AS_FLOAT_P (trueop0)
7210 1497 : && CONST_DOUBLE_AS_FLOAT_P (trueop1)
7211 1497 : && SCALAR_FLOAT_MODE_P (GET_MODE (trueop0)))
7212 : {
7213 1497 : const REAL_VALUE_TYPE *d0 = CONST_DOUBLE_REAL_VALUE (trueop0);
7214 1497 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
7215 :
7216 : /* Comparisons are unordered iff at least one of the values is NaN. */
7217 1497 : if (REAL_VALUE_ISNAN (*d0) || REAL_VALUE_ISNAN (*d1))
7218 173 : switch (code)
7219 : {
7220 0 : case UNEQ:
7221 0 : case UNLT:
7222 0 : case UNGT:
7223 0 : case UNLE:
7224 0 : case UNGE:
7225 0 : case NE:
7226 0 : case UNORDERED:
7227 0 : return const_true_rtx;
7228 173 : case EQ:
7229 173 : case LT:
7230 173 : case GT:
7231 173 : case LE:
7232 173 : case GE:
7233 173 : case LTGT:
7234 173 : case ORDERED:
7235 173 : return const0_rtx;
7236 : default:
7237 : return 0;
7238 : }
7239 :
7240 1484 : return comparison_result (code,
7241 1484 : (real_equal (d0, d1) ? CMP_EQ :
7242 1484 : real_less (d0, d1) ? CMP_LT : CMP_GT));
7243 : }
7244 :
7245 : /* Otherwise, see if the operands are both integers. */
7246 100558367 : if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
7247 97399710 : && CONST_SCALAR_INT_P (trueop0) && CONST_SCALAR_INT_P (trueop1))
7248 : {
7249 : /* It would be nice if we really had a mode here. However, the
7250 : largest int representable on the target is as good as
7251 : infinite. */
7252 205978 : machine_mode cmode = (mode == VOIDmode) ? MAX_MODE_INT : mode;
7253 205978 : rtx_mode_t ptrueop0 = rtx_mode_t (trueop0, cmode);
7254 205978 : rtx_mode_t ptrueop1 = rtx_mode_t (trueop1, cmode);
7255 :
7256 205978 : if (wi::eq_p (ptrueop0, ptrueop1))
7257 0 : return comparison_result (code, CMP_EQ);
7258 : else
7259 : {
7260 205978 : int cr = wi::lts_p (ptrueop0, ptrueop1) ? CMP_LT : CMP_GT;
7261 205978 : cr |= wi::ltu_p (ptrueop0, ptrueop1) ? CMP_LTU : CMP_GTU;
7262 205978 : return comparison_result (code, cr);
7263 : }
7264 : }
7265 :
7266 : /* Optimize comparisons with upper and lower bounds. */
7267 100352389 : scalar_int_mode int_mode;
7268 100352389 : if (CONST_INT_P (trueop1)
7269 70043777 : && is_a <scalar_int_mode> (mode, &int_mode)
7270 70043777 : && HWI_COMPUTABLE_MODE_P (int_mode)
7271 169939988 : && !side_effects_p (trueop0))
7272 : {
7273 69436198 : int sign;
7274 69436198 : unsigned HOST_WIDE_INT nonzero = nonzero_bits (trueop0, int_mode);
7275 69436198 : HOST_WIDE_INT val = INTVAL (trueop1);
7276 69436198 : HOST_WIDE_INT mmin, mmax;
7277 :
7278 69436198 : if (code == GEU
7279 69436198 : || code == LEU
7280 66178875 : || code == GTU
7281 66178875 : || code == LTU)
7282 : sign = 0;
7283 : else
7284 69436198 : sign = 1;
7285 :
7286 : /* Get a reduced range if the sign bit is zero. */
7287 69436198 : if (nonzero <= (GET_MODE_MASK (int_mode) >> 1))
7288 : {
7289 6277779 : mmin = 0;
7290 6277779 : mmax = nonzero;
7291 : }
7292 : else
7293 : {
7294 63158419 : rtx mmin_rtx, mmax_rtx;
7295 63158419 : get_mode_bounds (int_mode, sign, int_mode, &mmin_rtx, &mmax_rtx);
7296 :
7297 63158419 : mmin = INTVAL (mmin_rtx);
7298 63158419 : mmax = INTVAL (mmax_rtx);
7299 63158419 : if (sign)
7300 : {
7301 57061579 : unsigned int sign_copies
7302 57061579 : = num_sign_bit_copies (trueop0, int_mode);
7303 :
7304 57061579 : mmin >>= (sign_copies - 1);
7305 57061579 : mmax >>= (sign_copies - 1);
7306 : }
7307 : }
7308 :
7309 69436198 : switch (code)
7310 : {
7311 : /* x >= y is always true for y <= mmin, always false for y > mmax. */
7312 535227 : case GEU:
7313 535227 : if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
7314 6106 : return const_true_rtx;
7315 529121 : if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
7316 48 : return const0_rtx;
7317 : break;
7318 945701 : case GE:
7319 945701 : if (val <= mmin)
7320 2078 : return const_true_rtx;
7321 943623 : if (val > mmax)
7322 0 : return const0_rtx;
7323 : break;
7324 :
7325 : /* x <= y is always true for y >= mmax, always false for y < mmin. */
7326 2722096 : case LEU:
7327 2722096 : if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
7328 15382 : return const_true_rtx;
7329 2706714 : if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
7330 0 : return const0_rtx;
7331 : break;
7332 2577237 : case LE:
7333 2577237 : if (val >= mmax)
7334 446 : return const_true_rtx;
7335 2576791 : if (val < mmin)
7336 0 : return const0_rtx;
7337 : break;
7338 :
7339 25176370 : case EQ:
7340 : /* x == y is always false for y out of range. */
7341 25176370 : if (val < mmin || val > mmax)
7342 485 : return const0_rtx;
7343 : break;
7344 :
7345 : /* x > y is always false for y >= mmax, always true for y < mmin. */
7346 2462483 : case GTU:
7347 2462483 : if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
7348 40302 : return const0_rtx;
7349 2422181 : if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
7350 0 : return const_true_rtx;
7351 : break;
7352 1827454 : case GT:
7353 1827454 : if (val >= mmax)
7354 329 : return const0_rtx;
7355 1827125 : if (val < mmin)
7356 2 : return const_true_rtx;
7357 : break;
7358 :
7359 : /* x < y is always false for y <= mmin, always true for y > mmax. */
7360 841991 : case LTU:
7361 841991 : if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
7362 3949 : return const0_rtx;
7363 838042 : if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
7364 76983 : return const_true_rtx;
7365 : break;
7366 1087606 : case LT:
7367 1087606 : if (val <= mmin)
7368 2365 : return const0_rtx;
7369 1085241 : if (val > mmax)
7370 3303 : return const_true_rtx;
7371 : break;
7372 :
7373 31260033 : case NE:
7374 : /* x != y is always true for y out of range. */
7375 31260033 : if (val < mmin || val > mmax)
7376 122 : return const_true_rtx;
7377 : break;
7378 :
7379 : default:
7380 : break;
7381 : }
7382 : }
7383 :
7384 : /* Optimize integer comparisons with zero. */
7385 100200489 : if (is_a <scalar_int_mode> (mode, &int_mode)
7386 97084913 : && trueop1 == const0_rtx
7387 50320660 : && !side_effects_p (trueop0))
7388 : {
7389 : /* Some addresses are known to be nonzero. We don't know
7390 : their sign, but equality comparisons are known. */
7391 50167246 : if (nonzero_address_p (trueop0))
7392 : {
7393 533 : if (code == EQ || code == LEU)
7394 278 : return const0_rtx;
7395 255 : if (code == NE || code == GTU)
7396 255 : return const_true_rtx;
7397 : }
7398 :
7399 : /* See if the first operand is an IOR with a constant. If so, we
7400 : may be able to determine the result of this comparison. */
7401 50166713 : if (GET_CODE (op0) == IOR)
7402 : {
7403 696776 : rtx inner_const = avoid_constant_pool_reference (XEXP (op0, 1));
7404 696776 : if (CONST_INT_P (inner_const) && inner_const != const0_rtx)
7405 : {
7406 221 : int sign_bitnum = GET_MODE_PRECISION (int_mode) - 1;
7407 442 : int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
7408 221 : && (UINTVAL (inner_const)
7409 221 : & (HOST_WIDE_INT_1U
7410 : << sign_bitnum)));
7411 :
7412 221 : switch (code)
7413 : {
7414 : case EQ:
7415 : case LEU:
7416 : return const0_rtx;
7417 0 : case NE:
7418 0 : case GTU:
7419 0 : return const_true_rtx;
7420 17 : case LT:
7421 17 : case LE:
7422 17 : if (has_sign)
7423 2 : return const_true_rtx;
7424 : break;
7425 202 : case GT:
7426 202 : case GE:
7427 202 : if (has_sign)
7428 : return const0_rtx;
7429 : break;
7430 : default:
7431 : break;
7432 : }
7433 : }
7434 : }
7435 : }
7436 :
7437 : /* Optimize comparison of ABS with zero. */
7438 50670776 : if (trueop1 == CONST0_RTX (mode) && !side_effects_p (trueop0)
7439 150716809 : && (GET_CODE (trueop0) == ABS
7440 50516486 : || (GET_CODE (trueop0) == FLOAT_EXTEND
7441 100 : && GET_CODE (XEXP (trueop0, 0)) == ABS)))
7442 : {
7443 563 : switch (code)
7444 : {
7445 60 : case LT:
7446 : /* Optimize abs(x) < 0.0. */
7447 60 : if (!INTEGRAL_MODE_P (mode) && !HONOR_SNANS (mode))
7448 0 : return const0_rtx;
7449 : break;
7450 :
7451 42 : case GE:
7452 : /* Optimize abs(x) >= 0.0. */
7453 42 : if (!INTEGRAL_MODE_P (mode) && !HONOR_NANS (mode))
7454 0 : return const_true_rtx;
7455 : break;
7456 :
7457 0 : case UNGE:
7458 : /* Optimize ! (abs(x) < 0.0). */
7459 0 : return const_true_rtx;
7460 :
7461 : default:
7462 : break;
7463 : }
7464 : }
7465 :
7466 : return 0;
7467 : }
7468 :
7469 : /* Recognize expressions of the form (X CMP 0) ? VAL : OP (X)
7470 : where OP is CLZ or CTZ and VAL is the value from CLZ_DEFINED_VALUE_AT_ZERO
7471 : or CTZ_DEFINED_VALUE_AT_ZERO respectively and return OP (X) if the expression
7472 : can be simplified to that or NULL_RTX if not.
7473 : Assume X is compared against zero with CMP_CODE and the true
7474 : arm is TRUE_VAL and the false arm is FALSE_VAL. */
7475 :
7476 : rtx
7477 31525063 : simplify_context::simplify_cond_clz_ctz (rtx x, rtx_code cmp_code,
7478 : rtx true_val, rtx false_val)
7479 : {
7480 31525063 : if (cmp_code != EQ && cmp_code != NE)
7481 : return NULL_RTX;
7482 :
7483 : /* Result on X == 0 and X !=0 respectively. */
7484 22632483 : rtx on_zero, on_nonzero;
7485 22632483 : if (cmp_code == EQ)
7486 : {
7487 : on_zero = true_val;
7488 : on_nonzero = false_val;
7489 : }
7490 : else
7491 : {
7492 12362784 : on_zero = false_val;
7493 12362784 : on_nonzero = true_val;
7494 : }
7495 :
7496 22632483 : rtx_code op_code = GET_CODE (on_nonzero);
7497 22632483 : if ((op_code != CLZ && op_code != CTZ)
7498 1986 : || !rtx_equal_p (XEXP (on_nonzero, 0), x)
7499 22633501 : || !CONST_INT_P (on_zero))
7500 : return NULL_RTX;
7501 :
7502 263 : HOST_WIDE_INT op_val;
7503 263 : scalar_int_mode mode ATTRIBUTE_UNUSED
7504 263 : = as_a <scalar_int_mode> (GET_MODE (XEXP (on_nonzero, 0)));
7505 0 : if (((op_code == CLZ && CLZ_DEFINED_VALUE_AT_ZERO (mode, op_val))
7506 526 : || (op_code == CTZ && CTZ_DEFINED_VALUE_AT_ZERO (mode, op_val)))
7507 287 : && op_val == INTVAL (on_zero))
7508 0 : return on_nonzero;
7509 :
7510 : return NULL_RTX;
7511 : }
7512 :
7513 : /* Try to simplify X given that it appears within operand OP of a
7514 : VEC_MERGE operation whose mask is MASK. X need not use the same
7515 : vector mode as the VEC_MERGE, but it must have the same number of
7516 : elements.
7517 :
7518 : Return the simplified X on success, otherwise return NULL_RTX. */
7519 :
7520 : rtx
7521 2119860 : simplify_context::simplify_merge_mask (rtx x, rtx mask, int op)
7522 : {
7523 2119860 : gcc_assert (VECTOR_MODE_P (GET_MODE (x)));
7524 4239720 : poly_uint64 nunits = GET_MODE_NUNITS (GET_MODE (x));
7525 2119860 : if (GET_CODE (x) == VEC_MERGE && rtx_equal_p (XEXP (x, 2), mask))
7526 : {
7527 5491 : if (side_effects_p (XEXP (x, 1 - op)))
7528 : return NULL_RTX;
7529 :
7530 5267 : return XEXP (x, op);
7531 : }
7532 2114369 : if (UNARY_P (x)
7533 360848 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
7534 2172189 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits))
7535 : {
7536 24264 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
7537 24264 : if (top0)
7538 448 : return simplify_gen_unary (GET_CODE (x), GET_MODE (x), top0,
7539 448 : GET_MODE (XEXP (x, 0)));
7540 : }
7541 2113921 : if (BINARY_P (x)
7542 208537 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
7543 416446 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
7544 180908 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
7545 2402281 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits))
7546 : {
7547 144180 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
7548 144180 : rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
7549 144180 : if (top0 || top1)
7550 : {
7551 952 : if (COMPARISON_P (x))
7552 0 : return simplify_gen_relational (GET_CODE (x), GET_MODE (x),
7553 0 : GET_MODE (XEXP (x, 0)) != VOIDmode
7554 : ? GET_MODE (XEXP (x, 0))
7555 0 : : GET_MODE (XEXP (x, 1)),
7556 : top0 ? top0 : XEXP (x, 0),
7557 0 : top1 ? top1 : XEXP (x, 1));
7558 : else
7559 952 : return simplify_gen_binary (GET_CODE (x), GET_MODE (x),
7560 : top0 ? top0 : XEXP (x, 0),
7561 952 : top1 ? top1 : XEXP (x, 1));
7562 : }
7563 : }
7564 2112969 : if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY
7565 61044 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
7566 122088 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
7567 61044 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
7568 122088 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits)
7569 61044 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 2)))
7570 2129701 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 2))), nunits))
7571 : {
7572 8366 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
7573 8366 : rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
7574 8366 : rtx top2 = simplify_merge_mask (XEXP (x, 2), mask, op);
7575 8366 : if (top0 || top1 || top2)
7576 448 : return simplify_gen_ternary (GET_CODE (x), GET_MODE (x),
7577 448 : GET_MODE (XEXP (x, 0)),
7578 : top0 ? top0 : XEXP (x, 0),
7579 : top1 ? top1 : XEXP (x, 1),
7580 448 : top2 ? top2 : XEXP (x, 2));
7581 : }
7582 : return NULL_RTX;
7583 : }
7584 :
7585 :
7586 : /* Simplify CODE, an operation with result mode MODE and three operands,
7587 : OP0, OP1, and OP2. OP0_MODE was the mode of OP0 before it became
7588 : a constant. Return 0 if no simplifications is possible. */
7589 :
7590 : rtx
7591 43855860 : simplify_context::simplify_ternary_operation (rtx_code code, machine_mode mode,
7592 : machine_mode op0_mode,
7593 : rtx op0, rtx op1, rtx op2)
7594 : {
7595 43855860 : bool any_change = false;
7596 43855860 : rtx tem, trueop2;
7597 43855860 : scalar_int_mode int_mode, int_op0_mode;
7598 43855860 : unsigned int n_elts;
7599 :
7600 43855860 : switch (code)
7601 : {
7602 335456 : case FMA:
7603 : /* Simplify negations around the multiplication. */
7604 : /* -a * -b + c => a * b + c. */
7605 335456 : if (GET_CODE (op0) == NEG)
7606 : {
7607 82675 : tem = simplify_unary_operation (NEG, mode, op1, mode);
7608 82675 : if (tem)
7609 268 : op1 = tem, op0 = XEXP (op0, 0), any_change = true;
7610 : }
7611 252781 : else if (GET_CODE (op1) == NEG)
7612 : {
7613 1068 : tem = simplify_unary_operation (NEG, mode, op0, mode);
7614 1068 : if (tem)
7615 0 : op0 = tem, op1 = XEXP (op1, 0), any_change = true;
7616 : }
7617 :
7618 : /* Canonicalize the two multiplication operands. */
7619 : /* a * -b + c => -b * a + c. */
7620 335456 : if (swap_commutative_operands_p (op0, op1))
7621 : std::swap (op0, op1), any_change = true;
7622 :
7623 305539 : if (any_change)
7624 30176 : return gen_rtx_FMA (mode, op0, op1, op2);
7625 : return NULL_RTX;
7626 :
7627 764487 : case SIGN_EXTRACT:
7628 764487 : case ZERO_EXTRACT:
7629 764487 : if (CONST_INT_P (op0)
7630 17468 : && CONST_INT_P (op1)
7631 17468 : && CONST_INT_P (op2)
7632 43855892 : && is_a <scalar_int_mode> (mode, &int_mode)
7633 32 : && INTVAL (op1) + INTVAL (op2) <= GET_MODE_PRECISION (int_mode)
7634 764519 : && HWI_COMPUTABLE_MODE_P (int_mode))
7635 : {
7636 : /* Extracting a bit-field from a constant */
7637 32 : unsigned HOST_WIDE_INT val = UINTVAL (op0);
7638 32 : HOST_WIDE_INT op1val = INTVAL (op1);
7639 32 : HOST_WIDE_INT op2val = INTVAL (op2);
7640 32 : if (!BITS_BIG_ENDIAN)
7641 32 : val >>= op2val;
7642 : else if (is_a <scalar_int_mode> (op0_mode, &int_op0_mode))
7643 : val >>= GET_MODE_PRECISION (int_op0_mode) - op2val - op1val;
7644 : else
7645 : /* Not enough information to calculate the bit position. */
7646 : break;
7647 :
7648 32 : if (HOST_BITS_PER_WIDE_INT != op1val)
7649 : {
7650 : /* First zero-extend. */
7651 29 : val &= (HOST_WIDE_INT_1U << op1val) - 1;
7652 : /* If desired, propagate sign bit. */
7653 29 : if (code == SIGN_EXTRACT
7654 5 : && (val & (HOST_WIDE_INT_1U << (op1val - 1)))
7655 5 : != 0)
7656 2 : val |= ~ ((HOST_WIDE_INT_1U << op1val) - 1);
7657 : }
7658 :
7659 32 : return gen_int_mode (val, int_mode);
7660 : }
7661 : break;
7662 :
7663 41696841 : case IF_THEN_ELSE:
7664 41696841 : if (CONST_INT_P (op0))
7665 201008 : return op0 != const0_rtx ? op1 : op2;
7666 :
7667 : /* Convert c ? a : a into "a". Beware that two rtx_equal_p MEMs can
7668 : still carry different memory attributes, in particular incompatible
7669 : alias sets; returning one of them would narrow the aliasing of the
7670 : result to that operand's, which is unsound (PR125683). When the
7671 : attributes differ, fold to a copy that keeps only what both operands
7672 : guarantee, like merge_memattrs does when cross-jumping commons two
7673 : memory references. */
7674 41495833 : if (rtx_equal_p (op1, op2) && ! side_effects_p (op0))
7675 : {
7676 5343 : if (op1 == op2
7677 2914 : || !MEM_P (op1)
7678 5365 : || (mem_attrs_eq_p (get_mem_attrs (op1), get_mem_attrs (op2))
7679 8 : && MEM_READONLY_P (op1) == MEM_READONLY_P (op2)
7680 8 : && MEM_NOTRAP_P (op1) == MEM_NOTRAP_P (op2)
7681 8 : && MEM_POINTER (op1) == MEM_POINTER (op2)))
7682 : return op1;
7683 :
7684 : /* For BLKmode the size in MEM_ATTRS describes the access itself,
7685 : so it cannot be dropped. Volatility is not merged either: it
7686 : constrains when the access happens rather than describing the
7687 : memory, so unlike the flags below it cannot be weakened to what
7688 : both operands allow. Dropping it would lose a required access;
7689 : merge_memattrs and noce_try_cmove_arith instead set it, which is
7690 : sound but claims more than either operand did. Those two have to
7691 : put something on a reference they are already committed to, while
7692 : this fold is free to do nothing, and if-conversion never reaches
7693 : it with a volatile operand in any case: side_effects_p is true
7694 : for one, so noce_operand_ok rejects it. Decline the fold. */
7695 14 : if (GET_MODE (op1) != BLKmode
7696 14 : && MEM_VOLATILE_P (op1) == MEM_VOLATILE_P (op2))
7697 : {
7698 14 : rtx mem = shallow_copy_rtx (op1);
7699 :
7700 14 : if (MEM_ALIAS_SET (op1) != MEM_ALIAS_SET (op2))
7701 1 : set_mem_alias_set (mem, 0);
7702 :
7703 14 : if (!mem_expr_equal_p (MEM_EXPR (op1), MEM_EXPR (op2)))
7704 : {
7705 14 : set_mem_expr (mem, NULL_TREE);
7706 14 : clear_mem_offset (mem);
7707 : }
7708 0 : else if (MEM_OFFSET_KNOWN_P (op1) != MEM_OFFSET_KNOWN_P (op2)
7709 0 : || (MEM_OFFSET_KNOWN_P (op1)
7710 0 : && maybe_ne (MEM_OFFSET (op1), MEM_OFFSET (op2))))
7711 0 : clear_mem_offset (mem);
7712 :
7713 : /* Unlike merge_memattrs, which fixes up two references that
7714 : both stay in the stream, this returns a single reference
7715 : that stands in for either arm, so keep the size only when
7716 : both agree rather than taking the larger one. */
7717 28 : if (!MEM_SIZE_KNOWN_P (op1) || !MEM_SIZE_KNOWN_P (op2)
7718 28 : || maybe_ne (MEM_SIZE (op1), MEM_SIZE (op2)))
7719 0 : clear_mem_size (mem);
7720 :
7721 14 : set_mem_align (mem, MIN (MEM_ALIGN (op1), MEM_ALIGN (op2)));
7722 :
7723 : /* MEM_READONLY_P, MEM_NOTRAP_P and MEM_POINTER are rtx flag
7724 : bits rather than MEM_ATTRS fields, so shallow_copy_rtx has
7725 : already taken them from OP1 and they need clearing by hand.
7726 : Each asserts something about the reference, so the copy may
7727 : only keep it when both operands do, as merge_memattrs does
7728 : for the first two. */
7729 14 : if (MEM_READONLY_P (op1) != MEM_READONLY_P (op2))
7730 0 : MEM_READONLY_P (mem) = 0;
7731 14 : if (MEM_NOTRAP_P (op1) != MEM_NOTRAP_P (op2))
7732 0 : MEM_NOTRAP_P (mem) = 0;
7733 14 : if (MEM_POINTER (op1) != MEM_POINTER (op2))
7734 0 : MEM_POINTER (mem) = 0;
7735 :
7736 : return mem;
7737 : }
7738 : }
7739 :
7740 : /* Convert a != b ? a : b into "a". */
7741 41490490 : if (GET_CODE (op0) == NE
7742 16191497 : && ! side_effects_p (op0)
7743 16142799 : && ! HONOR_NANS (mode)
7744 15952365 : && ! HONOR_SIGNED_ZEROS (mode)
7745 57442855 : && ((rtx_equal_p (XEXP (op0, 0), op1)
7746 113219 : && rtx_equal_p (XEXP (op0, 1), op2))
7747 15952039 : || (rtx_equal_p (XEXP (op0, 0), op2)
7748 3750 : && rtx_equal_p (XEXP (op0, 1), op1))))
7749 : return op1;
7750 :
7751 : /* Convert a == b ? a : b into "b". */
7752 41489923 : if (GET_CODE (op0) == EQ
7753 12866630 : && ! side_effects_p (op0)
7754 12847608 : && ! HONOR_NANS (mode)
7755 12822470 : && ! HONOR_SIGNED_ZEROS (mode)
7756 54312393 : && ((rtx_equal_p (XEXP (op0, 0), op1)
7757 15188 : && rtx_equal_p (XEXP (op0, 1), op2))
7758 12822467 : || (rtx_equal_p (XEXP (op0, 0), op2)
7759 7885 : && rtx_equal_p (XEXP (op0, 1), op1))))
7760 : return op2;
7761 :
7762 : /* Convert a != 0 ? -a : 0 into "-a". */
7763 41489902 : if (GET_CODE (op0) == NE
7764 16190930 : && ! side_effects_p (op0)
7765 16142232 : && ! HONOR_NANS (mode)
7766 15951798 : && ! HONOR_SIGNED_ZEROS (mode)
7767 15951798 : && XEXP (op0, 1) == CONST0_RTX (mode)
7768 12172196 : && op2 == CONST0_RTX (mode)
7769 188555 : && GET_CODE (op1) == NEG
7770 41489941 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0)))
7771 : return op1;
7772 :
7773 : /* Convert a == 0 ? 0 : -a into "-a". */
7774 41489893 : if (GET_CODE (op0) == EQ
7775 12866609 : && ! side_effects_p (op0)
7776 12847587 : && ! HONOR_NANS (mode)
7777 12822449 : && ! HONOR_SIGNED_ZEROS (mode)
7778 12822449 : && op1 == CONST0_RTX (mode)
7779 43570 : && XEXP (op0, 1) == CONST0_RTX (mode)
7780 22981 : && GET_CODE (op2) == NEG
7781 41489899 : && rtx_equal_p (XEXP (op0, 0), XEXP (op2, 0)))
7782 : return op2;
7783 :
7784 : /* Convert (!c) != {0,...,0} ? a : b into
7785 : c != {0,...,0} ? b : a for vector modes. */
7786 41489887 : if (VECTOR_MODE_P (GET_MODE (op1))
7787 14795 : && GET_CODE (op0) == NE
7788 446 : && GET_CODE (XEXP (op0, 0)) == NOT
7789 0 : && GET_CODE (XEXP (op0, 1)) == CONST_VECTOR)
7790 : {
7791 0 : rtx cv = XEXP (op0, 1);
7792 0 : int nunits;
7793 0 : bool ok = true;
7794 0 : if (!CONST_VECTOR_NUNITS (cv).is_constant (&nunits))
7795 : ok = false;
7796 : else
7797 0 : for (int i = 0; i < nunits; ++i)
7798 0 : if (CONST_VECTOR_ELT (cv, i) != const0_rtx)
7799 : {
7800 : ok = false;
7801 : break;
7802 : }
7803 0 : if (ok)
7804 : {
7805 0 : rtx new_op0 = gen_rtx_NE (GET_MODE (op0),
7806 : XEXP (XEXP (op0, 0), 0),
7807 : XEXP (op0, 1));
7808 0 : rtx retval = gen_rtx_IF_THEN_ELSE (mode, new_op0, op2, op1);
7809 0 : return retval;
7810 : }
7811 : }
7812 :
7813 : /* Convert x == 0 ? N : clz (x) into clz (x) when
7814 : CLZ_DEFINED_VALUE_AT_ZERO is defined to N for the mode of x.
7815 : Similarly for ctz (x). */
7816 41488892 : if (COMPARISON_P (op0) && !side_effects_p (op0)
7817 82878345 : && XEXP (op0, 1) == const0_rtx)
7818 : {
7819 31525063 : rtx simplified
7820 31525063 : = simplify_cond_clz_ctz (XEXP (op0, 0), GET_CODE (op0),
7821 : op1, op2);
7822 31525063 : if (simplified)
7823 : return simplified;
7824 : }
7825 :
7826 41489887 : if (COMPARISON_P (op0) && ! side_effects_p (op0))
7827 : {
7828 82857477 : machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
7829 41388458 : ? GET_MODE (XEXP (op0, 1))
7830 : : GET_MODE (XEXP (op0, 0)));
7831 41388458 : rtx temp;
7832 :
7833 : /* Look for happy constants in op1 and op2. */
7834 41388458 : if (CONST_INT_P (op1) && CONST_INT_P (op2))
7835 : {
7836 234063 : HOST_WIDE_INT t = INTVAL (op1);
7837 234063 : HOST_WIDE_INT f = INTVAL (op2);
7838 :
7839 234063 : if (t == STORE_FLAG_VALUE && f == 0)
7840 55393 : code = GET_CODE (op0);
7841 178670 : else if (t == 0 && f == STORE_FLAG_VALUE)
7842 : {
7843 31313 : enum rtx_code tmp;
7844 31313 : tmp = reversed_comparison_code (op0, NULL);
7845 31313 : if (tmp == UNKNOWN)
7846 : break;
7847 : code = tmp;
7848 : }
7849 : else
7850 : break;
7851 :
7852 81557 : return simplify_gen_relational (code, mode, cmp_mode,
7853 81557 : XEXP (op0, 0), XEXP (op0, 1));
7854 : }
7855 :
7856 41154395 : temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
7857 : cmp_mode, XEXP (op0, 0),
7858 : XEXP (op0, 1));
7859 :
7860 : /* See if any simplifications were possible. */
7861 41154395 : if (temp)
7862 : {
7863 6941 : if (CONST_INT_P (temp))
7864 827 : return temp == const0_rtx ? op2 : op1;
7865 6114 : else if (temp)
7866 6114 : return gen_rtx_IF_THEN_ELSE (mode, temp, op1, op2);
7867 : }
7868 : }
7869 : break;
7870 :
7871 1059076 : case VEC_MERGE:
7872 1059076 : gcc_assert (GET_MODE (op0) == mode);
7873 1059076 : gcc_assert (GET_MODE (op1) == mode);
7874 1059076 : gcc_assert (VECTOR_MODE_P (mode));
7875 1059076 : trueop2 = avoid_constant_pool_reference (op2);
7876 1059076 : if (CONST_INT_P (trueop2)
7877 1791642 : && GET_MODE_NUNITS (mode).is_constant (&n_elts))
7878 : {
7879 732566 : unsigned HOST_WIDE_INT sel = UINTVAL (trueop2);
7880 732566 : unsigned HOST_WIDE_INT mask;
7881 732566 : if (n_elts == HOST_BITS_PER_WIDE_INT)
7882 : mask = -1;
7883 : else
7884 730089 : mask = (HOST_WIDE_INT_1U << n_elts) - 1;
7885 :
7886 732566 : if (!(sel & mask) && !side_effects_p (op0))
7887 : return op1;
7888 732141 : if ((sel & mask) == mask && !side_effects_p (op1))
7889 : return op0;
7890 :
7891 721040 : rtx trueop0 = avoid_constant_pool_reference (op0);
7892 721040 : rtx trueop1 = avoid_constant_pool_reference (op1);
7893 721040 : if (GET_CODE (trueop0) == CONST_VECTOR
7894 11228 : && GET_CODE (trueop1) == CONST_VECTOR)
7895 : {
7896 6859 : rtvec v = rtvec_alloc (n_elts);
7897 6859 : unsigned int i;
7898 :
7899 66536 : for (i = 0; i < n_elts; i++)
7900 52818 : RTVEC_ELT (v, i) = ((sel & (HOST_WIDE_INT_1U << i))
7901 52818 : ? CONST_VECTOR_ELT (trueop0, i)
7902 31062 : : CONST_VECTOR_ELT (trueop1, i));
7903 6859 : return gen_rtx_CONST_VECTOR (mode, v);
7904 : }
7905 :
7906 714181 : if (swap_commutative_operands_p (op0, op1)
7907 : /* Two operands have same precedence, then first bit of mask
7908 : select first operand. */
7909 714181 : || (!swap_commutative_operands_p (op1, op0) && !(sel & 1)))
7910 34451 : return simplify_gen_ternary (code, mode, mode, op1, op0,
7911 68902 : GEN_INT (~sel & mask));
7912 :
7913 : /* Replace (vec_merge (vec_merge a b m) c n) with (vec_merge b c n)
7914 : if no element from a appears in the result. */
7915 679730 : if (GET_CODE (op0) == VEC_MERGE)
7916 : {
7917 50029 : tem = avoid_constant_pool_reference (XEXP (op0, 2));
7918 50029 : if (CONST_INT_P (tem))
7919 : {
7920 34306 : unsigned HOST_WIDE_INT sel0 = UINTVAL (tem);
7921 34306 : if (!(sel & sel0 & mask) && !side_effects_p (XEXP (op0, 0)))
7922 99 : return simplify_gen_ternary (code, mode, mode,
7923 99 : XEXP (op0, 1), op1, op2);
7924 34207 : if (!(sel & ~sel0 & mask) && !side_effects_p (XEXP (op0, 1)))
7925 815 : return simplify_gen_ternary (code, mode, mode,
7926 815 : XEXP (op0, 0), op1, op2);
7927 :
7928 : /* Replace (vec_merge (vec_merge a b m) a n) with
7929 : (vec_merge a b (m|~n)). */
7930 33392 : if (rtx_equal_p (XEXP (op0, 0), op1)
7931 33392 : && ! side_effects_p (op1))
7932 169 : return simplify_gen_ternary (code, mode, mode,
7933 : op1, XEXP (op0, 1),
7934 338 : GEN_INT ((sel0 | ~sel) & mask));
7935 : /* Replace (vec_merge (vec_merge b a m) a n) with
7936 : (vec_merge b a (m&n)). */
7937 33223 : if (rtx_equal_p (XEXP (op0, 1), op1)
7938 33223 : && ! side_effects_p (op1))
7939 57 : return simplify_gen_ternary (code, mode, mode,
7940 : XEXP (op0, 0), op1,
7941 57 : GEN_INT (sel & sel0 & mask));
7942 : }
7943 : }
7944 678590 : if (GET_CODE (op1) == VEC_MERGE)
7945 : {
7946 580 : tem = avoid_constant_pool_reference (XEXP (op1, 2));
7947 580 : if (CONST_INT_P (tem))
7948 : {
7949 549 : unsigned HOST_WIDE_INT sel1 = UINTVAL (tem);
7950 549 : if (!(~sel & sel1 & mask) && !side_effects_p (XEXP (op1, 0)))
7951 518 : return simplify_gen_ternary (code, mode, mode,
7952 518 : op0, XEXP (op1, 1), op2);
7953 31 : if (!(~sel & ~sel1 & mask) && !side_effects_p (XEXP (op1, 1)))
7954 4 : return simplify_gen_ternary (code, mode, mode,
7955 4 : op0, XEXP (op1, 0), op2);
7956 :
7957 : /* Replace (vec_merge a (vec_merge a b m) n) with
7958 : (vec_merge a b (m|n)). */
7959 27 : if (rtx_equal_p (XEXP (op1, 0), op0)
7960 27 : && ! side_effects_p (op0))
7961 1 : return simplify_gen_ternary (code, mode, mode,
7962 : op0, XEXP (op1, 1),
7963 1 : GEN_INT ((sel | sel1) & mask));
7964 :
7965 : /* Replace (vec_merge a (vec_merge b a m) n) with
7966 : (vec_merge a b (~m|n)). */
7967 26 : if (rtx_equal_p (XEXP (op1, 1), op0)
7968 26 : && ! side_effects_p (op0))
7969 0 : return simplify_gen_ternary (code, mode, mode,
7970 : op0, XEXP (op1, 0),
7971 0 : GEN_INT ((sel | ~sel1) & mask));
7972 : }
7973 : }
7974 :
7975 : /* Replace (vec_merge (vec_duplicate (vec_select a parallel (i))) a 1 << i)
7976 : with a. */
7977 678067 : if (GET_CODE (op0) == VEC_DUPLICATE
7978 365753 : && GET_CODE (XEXP (op0, 0)) == VEC_SELECT
7979 2224 : && GET_CODE (XEXP (XEXP (op0, 0), 1)) == PARALLEL
7980 682515 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (op0, 0))), 1))
7981 : {
7982 2156 : tem = XVECEXP ((XEXP (XEXP (op0, 0), 1)), 0, 0);
7983 2156 : if (CONST_INT_P (tem) && CONST_INT_P (op2))
7984 : {
7985 2156 : if (XEXP (XEXP (op0, 0), 0) == op1
7986 2 : && UINTVAL (op2) == HOST_WIDE_INT_1U << UINTVAL (tem))
7987 : return op1;
7988 : }
7989 : }
7990 : /* Replace (vec_merge (vec_duplicate (X)) (const_vector [A, B])
7991 : (const_int N))
7992 : with (vec_concat (X) (B)) if N == 1 or
7993 : (vec_concat (A) (X)) if N == 2. */
7994 678065 : if (GET_CODE (op0) == VEC_DUPLICATE
7995 365751 : && GET_CODE (op1) == CONST_VECTOR
7996 521308 : && known_eq (CONST_VECTOR_NUNITS (op1), 2)
7997 1802 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7998 678966 : && IN_RANGE (sel, 1, 2))
7999 : {
8000 899 : rtx newop0 = XEXP (op0, 0);
8001 899 : rtx newop1 = CONST_VECTOR_ELT (op1, 2 - sel);
8002 899 : if (sel == 2)
8003 111 : std::swap (newop0, newop1);
8004 899 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
8005 : }
8006 : /* Replace (vec_merge (vec_duplicate x) (vec_concat (y) (z)) (const_int N))
8007 : with (vec_concat x z) if N == 1, or (vec_concat y x) if N == 2.
8008 : Only applies for vectors of two elements. */
8009 677166 : if (GET_CODE (op0) == VEC_DUPLICATE
8010 364852 : && GET_CODE (op1) == VEC_CONCAT
8011 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
8012 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
8013 677166 : && IN_RANGE (sel, 1, 2))
8014 : {
8015 0 : rtx newop0 = XEXP (op0, 0);
8016 0 : rtx newop1 = XEXP (op1, 2 - sel);
8017 0 : rtx otherop = XEXP (op1, sel - 1);
8018 0 : if (sel == 2)
8019 0 : std::swap (newop0, newop1);
8020 : /* Don't want to throw away the other part of the vec_concat if
8021 : it has side-effects. */
8022 0 : if (!side_effects_p (otherop))
8023 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
8024 : }
8025 :
8026 : /* Replace:
8027 :
8028 : (vec_merge:outer (vec_duplicate:outer x:inner)
8029 : (subreg:outer y:inner 0)
8030 : (const_int N))
8031 :
8032 : with (vec_concat:outer x:inner y:inner) if N == 1,
8033 : or (vec_concat:outer y:inner x:inner) if N == 2.
8034 :
8035 : Implicitly, this means we have a paradoxical subreg, but such
8036 : a check is cheap, so make it anyway.
8037 :
8038 : Only applies for vectors of two elements. */
8039 677166 : if (GET_CODE (op0) == VEC_DUPLICATE
8040 364852 : && GET_CODE (op1) == SUBREG
8041 35113 : && GET_MODE (op1) == GET_MODE (op0)
8042 35113 : && GET_MODE (SUBREG_REG (op1)) == GET_MODE (XEXP (op0, 0))
8043 0 : && paradoxical_subreg_p (op1)
8044 0 : && subreg_lowpart_p (op1)
8045 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
8046 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
8047 677166 : && IN_RANGE (sel, 1, 2))
8048 : {
8049 0 : rtx newop0 = XEXP (op0, 0);
8050 0 : rtx newop1 = SUBREG_REG (op1);
8051 0 : if (sel == 2)
8052 0 : std::swap (newop0, newop1);
8053 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
8054 : }
8055 :
8056 : /* Same as above but with switched operands:
8057 : Replace (vec_merge:outer (subreg:outer x:inner 0)
8058 : (vec_duplicate:outer y:inner)
8059 : (const_int N))
8060 :
8061 : with (vec_concat:outer x:inner y:inner) if N == 1,
8062 : or (vec_concat:outer y:inner x:inner) if N == 2. */
8063 677166 : if (GET_CODE (op1) == VEC_DUPLICATE
8064 56557 : && GET_CODE (op0) == SUBREG
8065 20686 : && GET_MODE (op0) == GET_MODE (op1)
8066 20686 : && GET_MODE (SUBREG_REG (op0)) == GET_MODE (XEXP (op1, 0))
8067 0 : && paradoxical_subreg_p (op0)
8068 0 : && subreg_lowpart_p (op0)
8069 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
8070 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
8071 677166 : && IN_RANGE (sel, 1, 2))
8072 : {
8073 0 : rtx newop0 = SUBREG_REG (op0);
8074 0 : rtx newop1 = XEXP (op1, 0);
8075 0 : if (sel == 2)
8076 0 : std::swap (newop0, newop1);
8077 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
8078 : }
8079 :
8080 : /* Replace (vec_merge (vec_duplicate x) (vec_duplicate y)
8081 : (const_int n))
8082 : with (vec_concat x y) or (vec_concat y x) depending on value
8083 : of N. */
8084 677166 : if (GET_CODE (op0) == VEC_DUPLICATE
8085 364852 : && GET_CODE (op1) == VEC_DUPLICATE
8086 208 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
8087 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
8088 677166 : && IN_RANGE (sel, 1, 2))
8089 : {
8090 0 : rtx newop0 = XEXP (op0, 0);
8091 0 : rtx newop1 = XEXP (op1, 0);
8092 0 : if (sel == 2)
8093 0 : std::swap (newop0, newop1);
8094 :
8095 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
8096 : }
8097 : }
8098 :
8099 1003676 : if (rtx_equal_p (op0, op1)
8100 1003676 : && !side_effects_p (op2) && !side_effects_p (op1))
8101 : return op0;
8102 :
8103 1003378 : if (!side_effects_p (op2))
8104 : {
8105 999590 : rtx top0
8106 999590 : = may_trap_p (op0) ? NULL_RTX : simplify_merge_mask (op0, op2, 0);
8107 999590 : rtx top1
8108 999590 : = may_trap_p (op1) ? NULL_RTX : simplify_merge_mask (op1, op2, 1);
8109 999590 : if (top0 || top1)
8110 998 : return simplify_gen_ternary (code, mode, mode,
8111 : top0 ? top0 : op0,
8112 819 : top1 ? top1 : op1, op2);
8113 : }
8114 :
8115 : break;
8116 :
8117 0 : default:
8118 0 : gcc_unreachable ();
8119 : }
8120 :
8121 : return 0;
8122 : }
8123 :
8124 : /* Try to calculate NUM_BYTES bytes of the target memory image of X,
8125 : starting at byte FIRST_BYTE. Return true on success and add the
8126 : bytes to BYTES, such that each byte has BITS_PER_UNIT bits and such
8127 : that the bytes follow target memory order. Leave BYTES unmodified
8128 : on failure.
8129 :
8130 : MODE is the mode of X. The caller must reserve NUM_BYTES bytes in
8131 : BYTES before calling this function. */
8132 :
8133 : bool
8134 13954147 : native_encode_rtx (machine_mode mode, rtx x, vec<target_unit> &bytes,
8135 : unsigned int first_byte, unsigned int num_bytes)
8136 : {
8137 : /* Check the mode is sensible. */
8138 13954147 : gcc_assert (GET_MODE (x) == VOIDmode
8139 : ? is_a <scalar_int_mode> (mode)
8140 : : mode == GET_MODE (x));
8141 :
8142 13954147 : if (GET_CODE (x) == CONST_VECTOR)
8143 : {
8144 : /* CONST_VECTOR_ELT follows target memory order, so no shuffling
8145 : is necessary. The only complication is that MODE_VECTOR_BOOL
8146 : vectors can have several elements per byte. */
8147 1125388 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
8148 : GET_MODE_NUNITS (mode));
8149 562694 : unsigned int elt = first_byte * BITS_PER_UNIT / elt_bits;
8150 562694 : if (elt_bits < BITS_PER_UNIT)
8151 : {
8152 : /* This is the only case in which elements can be smaller than
8153 : a byte. */
8154 0 : gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
8155 0 : auto mask = GET_MODE_MASK (GET_MODE_INNER (mode));
8156 0 : for (unsigned int i = 0; i < num_bytes; ++i)
8157 : {
8158 0 : target_unit value = 0;
8159 0 : for (unsigned int j = 0; j < BITS_PER_UNIT; j += elt_bits)
8160 : {
8161 0 : if (INTVAL (CONST_VECTOR_ELT (x, elt)))
8162 0 : value |= mask << j;
8163 0 : elt += 1;
8164 : }
8165 0 : bytes.quick_push (value);
8166 : }
8167 : return true;
8168 : }
8169 :
8170 562694 : unsigned int start = bytes.length ();
8171 562694 : unsigned int elt_bytes = GET_MODE_UNIT_SIZE (mode);
8172 : /* Make FIRST_BYTE relative to ELT. */
8173 562694 : first_byte %= elt_bytes;
8174 2813947 : while (num_bytes > 0)
8175 : {
8176 : /* Work out how many bytes we want from element ELT. */
8177 2251253 : unsigned int chunk_bytes = MIN (num_bytes, elt_bytes - first_byte);
8178 4502506 : if (!native_encode_rtx (GET_MODE_INNER (mode),
8179 : CONST_VECTOR_ELT (x, elt), bytes,
8180 : first_byte, chunk_bytes))
8181 : {
8182 0 : bytes.truncate (start);
8183 0 : return false;
8184 : }
8185 2251253 : elt += 1;
8186 2251253 : first_byte = 0;
8187 2251253 : num_bytes -= chunk_bytes;
8188 : }
8189 : return true;
8190 : }
8191 :
8192 : /* All subsequent cases are limited to scalars. */
8193 13391453 : scalar_mode smode;
8194 13391453 : if (!is_a <scalar_mode> (mode, &smode))
8195 : return false;
8196 :
8197 : /* Make sure that the region is in range. */
8198 13391453 : unsigned int end_byte = first_byte + num_bytes;
8199 13391453 : unsigned int mode_bytes = GET_MODE_SIZE (smode);
8200 13391453 : gcc_assert (end_byte <= mode_bytes);
8201 :
8202 13391453 : if (CONST_SCALAR_INT_P (x))
8203 : {
8204 : /* The target memory layout is affected by both BYTES_BIG_ENDIAN
8205 : and WORDS_BIG_ENDIAN. Use the subreg machinery to get the lsb
8206 : position of each byte. */
8207 12709905 : rtx_mode_t value (x, smode);
8208 12709905 : wide_int_ref value_wi (value);
8209 66875732 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
8210 : {
8211 : /* Always constant because the inputs are. */
8212 41455922 : unsigned int lsb
8213 41455922 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
8214 : /* Operate directly on the encoding rather than using
8215 : wi::extract_uhwi, so that we preserve the sign or zero
8216 : extension for modes that are not a whole number of bits in
8217 : size. (Zero extension is only used for the combination of
8218 : innermode == BImode && STORE_FLAG_VALUE == 1). */
8219 41455922 : unsigned int elt = lsb / HOST_BITS_PER_WIDE_INT;
8220 41455922 : unsigned int shift = lsb % HOST_BITS_PER_WIDE_INT;
8221 41455922 : unsigned HOST_WIDE_INT uhwi = value_wi.elt (elt);
8222 41455922 : bytes.quick_push (uhwi >> shift);
8223 : }
8224 12709905 : return true;
8225 : }
8226 :
8227 681548 : if (CONST_DOUBLE_P (x))
8228 : {
8229 : /* real_to_target produces an array of integers in target memory order.
8230 : All integers before the last one have 32 bits; the last one may
8231 : have 32 bits or fewer, depending on whether the mode bitsize
8232 : is divisible by 32. Each of these integers is then laid out
8233 : in target memory as any other integer would be. */
8234 653371 : long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
8235 653371 : real_to_target (el32, CONST_DOUBLE_REAL_VALUE (x), smode);
8236 :
8237 : /* The (maximum) number of target bytes per element of el32. */
8238 653371 : unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
8239 653371 : gcc_assert (bytes_per_el32 != 0);
8240 :
8241 : /* Build up the integers in a similar way to the CONST_SCALAR_INT_P
8242 : handling above. */
8243 4470554 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
8244 : {
8245 3817183 : unsigned int index = byte / bytes_per_el32;
8246 3817183 : unsigned int subbyte = byte % bytes_per_el32;
8247 3817183 : unsigned int int_bytes = MIN (bytes_per_el32,
8248 : mode_bytes - index * bytes_per_el32);
8249 : /* Always constant because the inputs are. */
8250 3817183 : unsigned int lsb
8251 3817183 : = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
8252 3817183 : bytes.quick_push ((unsigned long) el32[index] >> lsb);
8253 : }
8254 653371 : return true;
8255 : }
8256 :
8257 28177 : if (GET_CODE (x) == CONST_FIXED)
8258 : {
8259 0 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
8260 : {
8261 : /* Always constant because the inputs are. */
8262 0 : unsigned int lsb
8263 0 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
8264 0 : unsigned HOST_WIDE_INT piece = CONST_FIXED_VALUE_LOW (x);
8265 0 : if (lsb >= HOST_BITS_PER_WIDE_INT)
8266 : {
8267 0 : lsb -= HOST_BITS_PER_WIDE_INT;
8268 0 : piece = CONST_FIXED_VALUE_HIGH (x);
8269 : }
8270 0 : bytes.quick_push (piece >> lsb);
8271 : }
8272 : return true;
8273 : }
8274 :
8275 : return false;
8276 : }
8277 :
8278 : /* Read a vector of mode MODE from the target memory image given by BYTES,
8279 : starting at byte FIRST_BYTE. The vector is known to be encodable using
8280 : NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each,
8281 : and BYTES is known to have enough bytes to supply NPATTERNS *
8282 : NELTS_PER_PATTERN vector elements. Each element of BYTES contains
8283 : BITS_PER_UNIT bits and the bytes are in target memory order.
8284 :
8285 : Return the vector on success, otherwise return NULL_RTX. */
8286 :
8287 : rtx
8288 292333 : native_decode_vector_rtx (machine_mode mode, const vec<target_unit> &bytes,
8289 : unsigned int first_byte, unsigned int npatterns,
8290 : unsigned int nelts_per_pattern)
8291 : {
8292 292333 : rtx_vector_builder builder (mode, npatterns, nelts_per_pattern);
8293 :
8294 584666 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
8295 : GET_MODE_NUNITS (mode));
8296 292333 : if (elt_bits < BITS_PER_UNIT)
8297 : {
8298 : /* This is the only case in which elements can be smaller than a byte.
8299 : Element 0 is always in the lsb of the containing byte. */
8300 0 : gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
8301 0 : for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
8302 : {
8303 0 : unsigned int bit_index = first_byte * BITS_PER_UNIT + i * elt_bits;
8304 0 : unsigned int byte_index = bit_index / BITS_PER_UNIT;
8305 0 : unsigned int lsb = bit_index % BITS_PER_UNIT;
8306 0 : unsigned int value = bytes[byte_index] >> lsb;
8307 0 : builder.quick_push (gen_int_mode (value, GET_MODE_INNER (mode)));
8308 : }
8309 : }
8310 : else
8311 : {
8312 1186636 : for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
8313 : {
8314 1788606 : rtx x = native_decode_rtx (GET_MODE_INNER (mode), bytes, first_byte);
8315 894303 : if (!x)
8316 0 : return NULL_RTX;
8317 894303 : builder.quick_push (x);
8318 894303 : first_byte += elt_bits / BITS_PER_UNIT;
8319 : }
8320 : }
8321 292333 : return builder.build ();
8322 292333 : }
8323 :
8324 : /* Extract a PRECISION-bit integer from bytes [FIRST_BYTE, FIRST_BYTE + SIZE)
8325 : of target memory image BYTES. */
8326 :
8327 : wide_int
8328 11816908 : native_decode_int (const vec<target_unit> &bytes, unsigned int first_byte,
8329 : unsigned int size, unsigned int precision)
8330 : {
8331 : /* Pull the bytes msb first, so that we can use simple
8332 : shift-and-insert wide_int operations. */
8333 11816908 : wide_int result (wi::zero (precision));
8334 54465737 : for (unsigned int i = 0; i < size; ++i)
8335 : {
8336 42648829 : unsigned int lsb = (size - i - 1) * BITS_PER_UNIT;
8337 : /* Always constant because the inputs are. */
8338 42648829 : unsigned int subbyte
8339 42648829 : = subreg_size_offset_from_lsb (1, size, lsb).to_constant ();
8340 42648829 : result <<= BITS_PER_UNIT;
8341 42648829 : result |= bytes[first_byte + subbyte];
8342 : }
8343 11816908 : return result;
8344 : }
8345 :
8346 : /* Read an rtx of mode MODE from the target memory image given by BYTES,
8347 : starting at byte FIRST_BYTE. Each element of BYTES contains BITS_PER_UNIT
8348 : bits and the bytes are in target memory order. The image has enough
8349 : values to specify all bytes of MODE.
8350 :
8351 : Return the rtx on success, otherwise return NULL_RTX. */
8352 :
8353 : rtx
8354 12152224 : native_decode_rtx (machine_mode mode, const vec<target_unit> &bytes,
8355 : unsigned int first_byte)
8356 : {
8357 12152224 : if (VECTOR_MODE_P (mode))
8358 : {
8359 : /* If we know at compile time how many elements there are,
8360 : pull each element directly from BYTES. */
8361 89968 : unsigned int nelts;
8362 179936 : if (GET_MODE_NUNITS (mode).is_constant (&nelts))
8363 89968 : return native_decode_vector_rtx (mode, bytes, first_byte, nelts, 1);
8364 : return NULL_RTX;
8365 : }
8366 :
8367 12062256 : scalar_int_mode imode;
8368 12062256 : if (is_a <scalar_int_mode> (mode, &imode)
8369 11816908 : && GET_MODE_PRECISION (imode) <= MAX_BITSIZE_MODE_ANY_INT)
8370 : {
8371 11816908 : auto result = native_decode_int (bytes, first_byte,
8372 11816908 : GET_MODE_SIZE (imode),
8373 23633816 : GET_MODE_PRECISION (imode));
8374 11816908 : return immed_wide_int_const (result, imode);
8375 11816908 : }
8376 :
8377 245348 : scalar_float_mode fmode;
8378 245348 : if (is_a <scalar_float_mode> (mode, &fmode))
8379 : {
8380 : /* We need to build an array of integers in target memory order.
8381 : All integers before the last one have 32 bits; the last one may
8382 : have 32 bits or fewer, depending on whether the mode bitsize
8383 : is divisible by 32. */
8384 245318 : long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
8385 245318 : unsigned int num_el32 = CEIL (GET_MODE_BITSIZE (fmode), 32);
8386 245318 : memset (el32, 0, num_el32 * sizeof (long));
8387 :
8388 : /* The (maximum) number of target bytes per element of el32. */
8389 245318 : unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
8390 245318 : gcc_assert (bytes_per_el32 != 0);
8391 :
8392 245318 : unsigned int mode_bytes = GET_MODE_SIZE (fmode);
8393 1704976 : for (unsigned int byte = 0; byte < mode_bytes; ++byte)
8394 : {
8395 1459658 : unsigned int index = byte / bytes_per_el32;
8396 1459658 : unsigned int subbyte = byte % bytes_per_el32;
8397 1459658 : unsigned int int_bytes = MIN (bytes_per_el32,
8398 : mode_bytes - index * bytes_per_el32);
8399 : /* Always constant because the inputs are. */
8400 1459658 : unsigned int lsb
8401 1459658 : = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
8402 1459658 : el32[index] |= (unsigned long) bytes[first_byte + byte] << lsb;
8403 : }
8404 245318 : REAL_VALUE_TYPE r;
8405 245318 : real_from_target (&r, el32, fmode);
8406 245318 : return const_double_from_real_value (r, fmode);
8407 : }
8408 :
8409 30 : if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
8410 : {
8411 0 : scalar_mode smode = as_a <scalar_mode> (mode);
8412 0 : FIXED_VALUE_TYPE f;
8413 0 : f.data.low = 0;
8414 0 : f.data.high = 0;
8415 0 : f.mode = smode;
8416 :
8417 0 : unsigned int mode_bytes = GET_MODE_SIZE (smode);
8418 0 : for (unsigned int byte = 0; byte < mode_bytes; ++byte)
8419 : {
8420 : /* Always constant because the inputs are. */
8421 0 : unsigned int lsb
8422 0 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
8423 0 : unsigned HOST_WIDE_INT unit = bytes[first_byte + byte];
8424 0 : if (lsb >= HOST_BITS_PER_WIDE_INT)
8425 0 : f.data.high |= unit << (lsb - HOST_BITS_PER_WIDE_INT);
8426 : else
8427 0 : f.data.low |= unit << lsb;
8428 : }
8429 0 : return CONST_FIXED_FROM_FIXED_VALUE (f, mode);
8430 : }
8431 :
8432 : return NULL_RTX;
8433 : }
8434 :
8435 : /* Simplify a byte offset BYTE into CONST_VECTOR X. The main purpose
8436 : is to convert a runtime BYTE value into a constant one. */
8437 :
8438 : static poly_uint64
8439 352000 : simplify_const_vector_byte_offset (rtx x, poly_uint64 byte)
8440 : {
8441 : /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
8442 352000 : machine_mode mode = GET_MODE (x);
8443 704000 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
8444 : GET_MODE_NUNITS (mode));
8445 : /* The number of bits needed to encode one element from each pattern. */
8446 352000 : unsigned int sequence_bits = CONST_VECTOR_NPATTERNS (x) * elt_bits;
8447 :
8448 : /* Identify the start point in terms of a sequence number and a byte offset
8449 : within that sequence. */
8450 352000 : poly_uint64 first_sequence;
8451 352000 : unsigned HOST_WIDE_INT subbit;
8452 352000 : if (can_div_trunc_p (byte * BITS_PER_UNIT, sequence_bits,
8453 : &first_sequence, &subbit))
8454 : {
8455 352000 : unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
8456 352000 : if (nelts_per_pattern == 1)
8457 : /* This is a duplicated vector, so the value of FIRST_SEQUENCE
8458 : doesn't matter. */
8459 268969 : byte = subbit / BITS_PER_UNIT;
8460 83031 : else if (nelts_per_pattern == 2 && known_gt (first_sequence, 0U))
8461 : {
8462 : /* The subreg drops the first element from each pattern and
8463 : only uses the second element. Find the first sequence
8464 : that starts on a byte boundary. */
8465 5568 : subbit += least_common_multiple (sequence_bits, BITS_PER_UNIT);
8466 5568 : byte = subbit / BITS_PER_UNIT;
8467 : }
8468 : }
8469 352000 : return byte;
8470 : }
8471 :
8472 : /* Subroutine of simplify_subreg in which:
8473 :
8474 : - X is known to be a CONST_VECTOR
8475 : - OUTERMODE is known to be a vector mode
8476 :
8477 : Try to handle the subreg by operating on the CONST_VECTOR encoding
8478 : rather than on each individual element of the CONST_VECTOR.
8479 :
8480 : Return the simplified subreg on success, otherwise return NULL_RTX. */
8481 :
8482 : static rtx
8483 210387 : simplify_const_vector_subreg (machine_mode outermode, rtx x,
8484 : machine_mode innermode, unsigned int first_byte)
8485 : {
8486 : /* Paradoxical subregs of vectors have dubious semantics. */
8487 210387 : if (paradoxical_subreg_p (outermode, innermode))
8488 : return NULL_RTX;
8489 :
8490 : /* We can only preserve the semantics of a stepped pattern if the new
8491 : vector element is the same as the original one. */
8492 210221 : if (CONST_VECTOR_STEPPED_P (x)
8493 231157 : && GET_MODE_INNER (outermode) != GET_MODE_INNER (innermode))
8494 : return NULL_RTX;
8495 :
8496 : /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
8497 202365 : unsigned int x_elt_bits
8498 202365 : = vector_element_size (GET_MODE_PRECISION (innermode),
8499 : GET_MODE_NUNITS (innermode));
8500 202365 : unsigned int out_elt_bits
8501 202365 : = vector_element_size (GET_MODE_PRECISION (outermode),
8502 : GET_MODE_NUNITS (outermode));
8503 :
8504 : /* The number of bits needed to encode one element from every pattern
8505 : of the original vector. */
8506 202365 : unsigned int x_sequence_bits = CONST_VECTOR_NPATTERNS (x) * x_elt_bits;
8507 :
8508 : /* The number of bits needed to encode one element from every pattern
8509 : of the result. */
8510 202365 : unsigned int out_sequence_bits
8511 202365 : = least_common_multiple (x_sequence_bits, out_elt_bits);
8512 :
8513 : /* Work out the number of interleaved patterns in the output vector
8514 : and the number of encoded elements per pattern. */
8515 202365 : unsigned int out_npatterns = out_sequence_bits / out_elt_bits;
8516 202365 : unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
8517 :
8518 : /* The encoding scheme requires the number of elements to be a multiple
8519 : of the number of patterns, so that each pattern appears at least once
8520 : and so that the same number of elements appear from each pattern. */
8521 404730 : bool ok_p = multiple_p (GET_MODE_NUNITS (outermode), out_npatterns);
8522 202365 : unsigned int const_nunits;
8523 404730 : if (GET_MODE_NUNITS (outermode).is_constant (&const_nunits)
8524 202365 : && (!ok_p || out_npatterns * nelts_per_pattern > const_nunits))
8525 : {
8526 : /* Either the encoding is invalid, or applying it would give us
8527 : more elements than we need. Just encode each element directly. */
8528 : out_npatterns = const_nunits;
8529 : nelts_per_pattern = 1;
8530 : }
8531 : else if (!ok_p)
8532 : return NULL_RTX;
8533 :
8534 : /* Get enough bytes of X to form the new encoding. */
8535 202365 : unsigned int buffer_bits = out_npatterns * nelts_per_pattern * out_elt_bits;
8536 202365 : unsigned int buffer_bytes = CEIL (buffer_bits, BITS_PER_UNIT);
8537 202365 : auto_vec<target_unit, 128> buffer (buffer_bytes);
8538 202365 : if (!native_encode_rtx (innermode, x, buffer, first_byte, buffer_bytes))
8539 : return NULL_RTX;
8540 :
8541 : /* Re-encode the bytes as OUTERMODE. */
8542 202365 : return native_decode_vector_rtx (outermode, buffer, 0, out_npatterns,
8543 202365 : nelts_per_pattern);
8544 202365 : }
8545 :
8546 : /* Try to simplify a subreg of a constant by encoding the subreg region
8547 : as a sequence of target bytes and reading them back in the new mode.
8548 : Return the new value on success, otherwise return null.
8549 :
8550 : The subreg has outer mode OUTERMODE, inner mode INNERMODE, inner value X
8551 : and byte offset FIRST_BYTE. */
8552 :
8553 : static rtx
8554 10968051 : simplify_immed_subreg (fixed_size_mode outermode, rtx x,
8555 : machine_mode innermode, unsigned int first_byte)
8556 : {
8557 10968051 : unsigned int buffer_bytes = GET_MODE_SIZE (outermode);
8558 10968051 : auto_vec<target_unit, 128> buffer (buffer_bytes);
8559 :
8560 : /* Some ports misuse CCmode. */
8561 10968051 : if (GET_MODE_CLASS (outermode) == MODE_CC && CONST_INT_P (x))
8562 : return x;
8563 :
8564 : /* Paradoxical subregs read undefined values for bytes outside of the
8565 : inner value. However, we have traditionally always sign-extended
8566 : integer constants and zero-extended others. */
8567 10966045 : unsigned int inner_bytes = buffer_bytes;
8568 10966045 : if (paradoxical_subreg_p (outermode, innermode))
8569 : {
8570 1021722 : if (!GET_MODE_SIZE (innermode).is_constant (&inner_bytes))
8571 0 : return NULL_RTX;
8572 :
8573 510861 : target_unit filler = 0;
8574 510861 : if (CONST_SCALAR_INT_P (x) && wi::neg_p (rtx_mode_t (x, innermode)))
8575 52645 : filler = -1;
8576 :
8577 : /* Add any leading bytes due to big-endian layout. The number of
8578 : bytes must be constant because both modes have constant size. */
8579 510861 : unsigned int leading_bytes
8580 510861 : = -byte_lowpart_offset (outermode, innermode).to_constant ();
8581 510861 : for (unsigned int i = 0; i < leading_bytes; ++i)
8582 0 : buffer.quick_push (filler);
8583 :
8584 510861 : if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
8585 0 : return NULL_RTX;
8586 :
8587 : /* Add any trailing bytes due to little-endian layout. */
8588 6653732 : while (buffer.length () < buffer_bytes)
8589 2816005 : buffer.quick_push (filler);
8590 : }
8591 10455184 : else if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
8592 : return NULL_RTX;
8593 10966045 : rtx ret = native_decode_rtx (outermode, buffer, 0);
8594 10966045 : if (ret && FLOAT_MODE_P (outermode))
8595 : {
8596 129635 : auto_vec<target_unit, 128> buffer2 (buffer_bytes);
8597 129635 : if (!native_encode_rtx (outermode, ret, buffer2, 0, buffer_bytes))
8598 : return NULL_RTX;
8599 1426442 : for (unsigned int i = 0; i < buffer_bytes; ++i)
8600 1296842 : if (buffer[i] != buffer2[i])
8601 : return NULL_RTX;
8602 129635 : }
8603 : return ret;
8604 10968051 : }
8605 :
8606 : /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
8607 : Return 0 if no simplifications are possible. */
8608 : rtx
8609 74540864 : simplify_context::simplify_subreg (machine_mode outermode, rtx op,
8610 : machine_mode innermode, poly_uint64 byte)
8611 : {
8612 : /* Little bit of sanity checking. */
8613 74540864 : gcc_assert (innermode != VOIDmode);
8614 74540864 : gcc_assert (outermode != VOIDmode);
8615 74540864 : gcc_assert (innermode != BLKmode);
8616 74540864 : gcc_assert (outermode != BLKmode);
8617 :
8618 74540864 : gcc_assert (GET_MODE (op) == innermode
8619 : || GET_MODE (op) == VOIDmode);
8620 :
8621 149081728 : poly_uint64 outersize = GET_MODE_SIZE (outermode);
8622 74540864 : if (!multiple_p (byte, outersize))
8623 : return NULL_RTX;
8624 :
8625 149081688 : poly_uint64 innersize = GET_MODE_SIZE (innermode);
8626 74540844 : if (maybe_ge (byte, innersize))
8627 : return NULL_RTX;
8628 :
8629 74540844 : if (outermode == innermode && known_eq (byte, 0U))
8630 4603408 : return op;
8631 :
8632 69937436 : if (GET_CODE (op) == CONST_VECTOR)
8633 352000 : byte = simplify_const_vector_byte_offset (op, byte);
8634 :
8635 139874872 : if (multiple_p (byte, GET_MODE_UNIT_SIZE (innermode)))
8636 : {
8637 63922132 : rtx elt;
8638 :
8639 54829613 : if (VECTOR_MODE_P (outermode)
8640 27277557 : && GET_MODE_INNER (outermode) == GET_MODE_INNER (innermode)
8641 65689152 : && vec_duplicate_p (op, &elt))
8642 14288 : return gen_vec_duplicate (outermode, elt);
8643 :
8644 63916104 : if (outermode == GET_MODE_INNER (innermode)
8645 63916104 : && vec_duplicate_p (op, &elt))
8646 8260 : return elt;
8647 : }
8648 :
8649 69923148 : if (CONST_SCALAR_INT_P (op)
8650 59153535 : || CONST_DOUBLE_AS_FLOAT_P (op)
8651 59096222 : || CONST_FIXED_P (op)
8652 59096222 : || GET_CODE (op) == CONST_VECTOR)
8653 : {
8654 11170416 : unsigned HOST_WIDE_INT cbyte;
8655 11170416 : if (byte.is_constant (&cbyte))
8656 : {
8657 11170416 : if (GET_CODE (op) == CONST_VECTOR && VECTOR_MODE_P (outermode))
8658 : {
8659 210387 : rtx tmp = simplify_const_vector_subreg (outermode, op,
8660 : innermode, cbyte);
8661 210387 : if (tmp)
8662 11170416 : return tmp;
8663 : }
8664 :
8665 10968051 : fixed_size_mode fs_outermode;
8666 10968051 : if (is_a <fixed_size_mode> (outermode, &fs_outermode))
8667 10968051 : return simplify_immed_subreg (fs_outermode, op, innermode, cbyte);
8668 : }
8669 : }
8670 :
8671 : /* Changing mode twice with SUBREG => just change it once,
8672 : or not at all if changing back op starting mode. */
8673 58752732 : if (GET_CODE (op) == SUBREG)
8674 : {
8675 1329981 : machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
8676 2659962 : poly_uint64 innermostsize = GET_MODE_SIZE (innermostmode);
8677 1329981 : rtx newx;
8678 :
8679 : /* Make sure that the relationship between the two subregs is
8680 : known at compile time. */
8681 1329981 : if (!ordered_p (outersize, innermostsize))
8682 : return NULL_RTX;
8683 :
8684 1329981 : if (outermode == innermostmode
8685 658015 : && known_eq (byte, subreg_lowpart_offset (outermode, innermode))
8686 1987989 : && known_eq (SUBREG_BYTE (op),
8687 : subreg_lowpart_offset (innermode, innermostmode)))
8688 658008 : return SUBREG_REG (op);
8689 :
8690 : /* Work out the memory offset of the final OUTERMODE value relative
8691 : to the inner value of OP. */
8692 671973 : poly_int64 mem_offset = subreg_memory_offset (outermode,
8693 : innermode, byte);
8694 671973 : poly_int64 op_mem_offset = subreg_memory_offset (op);
8695 671973 : poly_int64 final_offset = mem_offset + op_mem_offset;
8696 :
8697 : /* See whether resulting subreg will be paradoxical. */
8698 671973 : if (!paradoxical_subreg_p (outermode, innermostmode))
8699 : {
8700 : /* Bail out in case resulting subreg would be incorrect. */
8701 1064442 : if (maybe_lt (final_offset, 0)
8702 1064435 : || maybe_ge (poly_uint64 (final_offset), innermostsize)
8703 1064435 : || !multiple_p (final_offset, outersize))
8704 : return NULL_RTX;
8705 : }
8706 : else
8707 : {
8708 139752 : poly_int64 required_offset = subreg_memory_offset (outermode,
8709 : innermostmode, 0);
8710 139752 : if (maybe_ne (final_offset, required_offset))
8711 1 : return NULL_RTX;
8712 : /* Paradoxical subregs always have byte offset 0. */
8713 139751 : final_offset = 0;
8714 : }
8715 :
8716 : /* Recurse for further possible simplifications. */
8717 671957 : newx = simplify_subreg (outermode, SUBREG_REG (op), innermostmode,
8718 671957 : final_offset);
8719 671957 : if (newx)
8720 : return newx;
8721 671550 : if (validate_subreg (outermode, innermostmode,
8722 671550 : SUBREG_REG (op), final_offset))
8723 : {
8724 615822 : newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
8725 615822 : if (SUBREG_PROMOTED_VAR_P (op)
8726 721 : && SUBREG_PROMOTED_SIGN (op) >= 0
8727 721 : && GET_MODE_CLASS (outermode) == MODE_INT
8728 717 : && known_ge (outersize, innersize)
8729 298 : && known_le (outersize, innermostsize)
8730 615832 : && subreg_lowpart_p (newx))
8731 : {
8732 10 : SUBREG_PROMOTED_VAR_P (newx) = 1;
8733 10 : SUBREG_PROMOTED_SET (newx, SUBREG_PROMOTED_GET (op));
8734 : }
8735 : return newx;
8736 : }
8737 : return NULL_RTX;
8738 : }
8739 :
8740 : /* SUBREG of a hard register => just change the register number
8741 : and/or mode. If the hard register is not valid in that mode,
8742 : suppress this simplification. If the hard register is the stack,
8743 : frame, or argument pointer, leave this as a SUBREG. */
8744 :
8745 57422751 : if (REG_P (op) && HARD_REGISTER_P (op))
8746 : {
8747 11044617 : unsigned int regno, final_regno;
8748 :
8749 11044617 : regno = REGNO (op);
8750 11044617 : final_regno = simplify_subreg_regno (regno, innermode, byte, outermode);
8751 11044617 : if (HARD_REGISTER_NUM_P (final_regno))
8752 : {
8753 11018924 : rtx x = gen_rtx_REG_offset (op, outermode, final_regno,
8754 : subreg_memory_offset (outermode,
8755 : innermode, byte));
8756 :
8757 : /* Propagate original regno. We don't have any way to specify
8758 : the offset inside original regno, so do so only for lowpart.
8759 : The information is used only by alias analysis that cannot
8760 : grog partial register anyway. */
8761 :
8762 11018924 : if (known_eq (subreg_lowpart_offset (outermode, innermode), byte))
8763 8248740 : ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op);
8764 : return x;
8765 : }
8766 : }
8767 :
8768 : /* If we have a SUBREG of a register that we are replacing and we are
8769 : replacing it with a MEM, make a new MEM and try replacing the
8770 : SUBREG with it. Don't do this if the MEM has a mode-dependent address
8771 : or if we would be widening it. */
8772 :
8773 46403827 : if (MEM_P (op)
8774 1656823 : && ! mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op))
8775 : /* Allow splitting of volatile memory references in case we don't
8776 : have instruction to move the whole thing. */
8777 1656820 : && (! MEM_VOLATILE_P (op)
8778 45536 : || ! have_insn_for (SET, innermode))
8779 : && !(STRICT_ALIGNMENT && MEM_ALIGN (op) < GET_MODE_ALIGNMENT (outermode))
8780 48015111 : && known_le (outersize, innersize))
8781 824590 : return adjust_address_nv (op, outermode, byte);
8782 :
8783 : /* Handle complex or vector values represented as CONCAT or VEC_CONCAT
8784 : of two parts. */
8785 45579237 : if (GET_CODE (op) == CONCAT
8786 45579237 : || GET_CODE (op) == VEC_CONCAT)
8787 : {
8788 275578 : poly_uint64 final_offset;
8789 275578 : rtx part, res;
8790 :
8791 275578 : machine_mode part_mode = GET_MODE (XEXP (op, 0));
8792 275578 : if (part_mode == VOIDmode)
8793 17 : part_mode = GET_MODE_INNER (GET_MODE (op));
8794 551156 : poly_uint64 part_size = GET_MODE_SIZE (part_mode);
8795 275578 : if (known_lt (byte, part_size))
8796 : {
8797 274077 : part = XEXP (op, 0);
8798 274077 : final_offset = byte;
8799 : }
8800 1501 : else if (known_ge (byte, part_size))
8801 : {
8802 1501 : part = XEXP (op, 1);
8803 1501 : final_offset = byte - part_size;
8804 : }
8805 : else
8806 : return NULL_RTX;
8807 :
8808 275578 : if (maybe_gt (final_offset + outersize, part_size))
8809 : return NULL_RTX;
8810 :
8811 128821 : part_mode = GET_MODE (part);
8812 128821 : if (part_mode == VOIDmode)
8813 0 : part_mode = GET_MODE_INNER (GET_MODE (op));
8814 128821 : res = simplify_subreg (outermode, part, part_mode, final_offset);
8815 128821 : if (res)
8816 : return res;
8817 306 : if (GET_MODE (part) != VOIDmode
8818 306 : && validate_subreg (outermode, part_mode, part, final_offset))
8819 306 : return gen_rtx_SUBREG (outermode, part, final_offset);
8820 : return NULL_RTX;
8821 : }
8822 :
8823 : /* Simplify
8824 : (subreg (vec_merge (X)
8825 : (vector)
8826 : (const_int ((1 << N) | M)))
8827 : (N * sizeof (outermode)))
8828 : to
8829 : (subreg (X) (N * sizeof (outermode)))
8830 : */
8831 45303659 : unsigned int idx;
8832 90607318 : if (constant_multiple_p (byte, GET_MODE_SIZE (outermode), &idx)
8833 45303659 : && idx < HOST_BITS_PER_WIDE_INT
8834 45303659 : && GET_CODE (op) == VEC_MERGE
8835 541870 : && GET_MODE_INNER (innermode) == outermode
8836 4849 : && CONST_INT_P (XEXP (op, 2))
8837 45307935 : && (UINTVAL (XEXP (op, 2)) & (HOST_WIDE_INT_1U << idx)) != 0)
8838 4267 : return simplify_gen_subreg (outermode, XEXP (op, 0), innermode, byte);
8839 :
8840 : /* A SUBREG resulting from a zero extension may fold to zero if
8841 : it extracts higher bits that the ZERO_EXTEND's source bits. */
8842 45299392 : if (GET_CODE (op) == ZERO_EXTEND && SCALAR_INT_MODE_P (innermode))
8843 : {
8844 232650 : poly_uint64 bitpos = subreg_lsb_1 (outermode, innermode, byte);
8845 232650 : if (known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (XEXP (op, 0)))))
8846 55269 : return CONST0_RTX (outermode);
8847 : }
8848 :
8849 : /* Optimize SUBREGS of scalar integral ASHIFT by a valid constant. */
8850 45244123 : if (GET_CODE (op) == ASHIFT
8851 1076389 : && SCALAR_INT_MODE_P (innermode)
8852 994635 : && CONST_INT_P (XEXP (op, 1))
8853 912406 : && INTVAL (XEXP (op, 1)) > 0
8854 47232918 : && known_gt (GET_MODE_BITSIZE (innermode), INTVAL (XEXP (op, 1))))
8855 : {
8856 912406 : HOST_WIDE_INT val = INTVAL (XEXP (op, 1));
8857 : /* A lowpart SUBREG of a ASHIFT by a constant may fold to zero. */
8858 912406 : if (known_eq (subreg_lowpart_offset (outermode, innermode), byte)
8859 1787436 : && known_le (GET_MODE_BITSIZE (outermode), val))
8860 193087 : return CONST0_RTX (outermode);
8861 : /* Optimize the highpart SUBREG of a suitable ASHIFT (ZERO_EXTEND). */
8862 753485 : if (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
8863 34839 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == outermode
8864 69368 : && known_eq (GET_MODE_BITSIZE (outermode), val)
8865 68332 : && known_eq (GET_MODE_BITSIZE (innermode), 2 * val)
8866 788324 : && known_eq (subreg_highpart_offset (outermode, innermode), byte))
8867 34166 : return XEXP (XEXP (op, 0), 0);
8868 : }
8869 :
8870 46661204 : auto distribute_subreg = [&](rtx op)
8871 : {
8872 1610168 : return simplify_subreg (outermode, op, innermode, byte);
8873 45051036 : };
8874 :
8875 : /* Try distributing the subreg through logic operations, if that
8876 : leads to all subexpressions being simplified. For example,
8877 : distributing the outer subreg in:
8878 :
8879 : (subreg:SI (not:QI (subreg:QI (reg:SI X) <lowpart>)) 0)
8880 :
8881 : gives:
8882 :
8883 : (not:SI (reg:SI X))
8884 :
8885 : This should be a win if the outermode is word_mode, since logical
8886 : operations on word_mode should (a) be no more expensive than logical
8887 : operations on subword modes and (b) are likely to be cheaper than
8888 : logical operations on multiword modes.
8889 :
8890 : Otherwise, handle the case where the subreg is non-narrowing and does
8891 : not change the number of words. The non-narrowing condition ensures
8892 : that we don't convert word_mode operations to subword operations. */
8893 45051036 : scalar_int_mode int_outermode, int_innermode;
8894 45051036 : if (is_a <scalar_int_mode> (outermode, &int_outermode)
8895 37925669 : && is_a <scalar_int_mode> (innermode, &int_innermode)
8896 81453174 : && (outermode == word_mode
8897 22022877 : || ((GET_MODE_PRECISION (int_outermode)
8898 22022877 : >= GET_MODE_PRECISION (int_innermode))
8899 4334943 : && (CEIL (GET_MODE_SIZE (int_outermode), UNITS_PER_WORD)
8900 4265192 : <= CEIL (GET_MODE_SIZE (int_innermode), UNITS_PER_WORD)))))
8901 18584048 : switch (GET_CODE (op))
8902 : {
8903 35118 : case NOT:
8904 35118 : if (rtx op0 = distribute_subreg (XEXP (op, 0)))
8905 1889 : return simplify_gen_unary (GET_CODE (op), outermode, op0, outermode);
8906 : break;
8907 :
8908 469784 : case AND:
8909 469784 : case IOR:
8910 469784 : case XOR:
8911 469784 : if (rtx op0 = distribute_subreg (XEXP (op, 0)))
8912 206193 : if (rtx op1 = distribute_subreg (XEXP (op, 1)))
8913 201528 : return simplify_gen_binary (GET_CODE (op), outermode, op0, op1);
8914 : break;
8915 :
8916 : default:
8917 : break;
8918 : }
8919 :
8920 44847619 : if (is_a <scalar_int_mode> (outermode, &int_outermode)
8921 37722252 : && is_a <scalar_int_mode> (innermode, &int_innermode)
8922 82569871 : && known_eq (byte, subreg_lowpart_offset (int_outermode, int_innermode)))
8923 : {
8924 : /* Handle polynomial integers. The upper bits of a paradoxical
8925 : subreg are undefined, so this is safe regardless of whether
8926 : we're truncating or extending. */
8927 33932021 : if (CONST_POLY_INT_P (op))
8928 : {
8929 : poly_wide_int val
8930 : = poly_wide_int::from (const_poly_int_value (op),
8931 : GET_MODE_PRECISION (int_outermode),
8932 : SIGNED);
8933 : return immed_wide_int_const (val, int_outermode);
8934 : }
8935 :
8936 33932021 : if (GET_MODE_PRECISION (int_outermode)
8937 33932021 : < GET_MODE_PRECISION (int_innermode))
8938 : {
8939 21230647 : rtx tem = simplify_truncation (int_outermode, op, int_innermode);
8940 21230647 : if (tem)
8941 : return tem;
8942 : }
8943 : }
8944 :
8945 : /* If the outer mode is not integral, try taking a subreg with the equivalent
8946 : integer outer mode and then bitcasting the result.
8947 : Other simplifications rely on integer to integer subregs and we'd
8948 : potentially miss out on optimizations otherwise. */
8949 86134532 : if (known_gt (GET_MODE_SIZE (innermode),
8950 : GET_MODE_SIZE (outermode))
8951 23087044 : && SCALAR_INT_MODE_P (innermode)
8952 21795133 : && !SCALAR_INT_MODE_P (outermode)
8953 66310588 : && int_mode_for_size (GET_MODE_BITSIZE (outermode),
8954 78139 : 0).exists (&int_outermode))
8955 : {
8956 78139 : rtx tem = simplify_subreg (int_outermode, op, innermode, byte);
8957 78139 : if (tem)
8958 1946 : return lowpart_subreg (outermode, tem, int_outermode);
8959 : }
8960 :
8961 : /* If OP is a vector comparison and the subreg is not changing the
8962 : number of elements or the size of the elements, change the result
8963 : of the comparison to the new mode. */
8964 43065320 : if (COMPARISON_P (op)
8965 304732 : && VECTOR_MODE_P (outermode)
8966 216283 : && VECTOR_MODE_P (innermode)
8967 648825 : && known_eq (GET_MODE_NUNITS (outermode), GET_MODE_NUNITS (innermode))
8968 43467329 : && known_eq (GET_MODE_UNIT_SIZE (outermode),
8969 : GET_MODE_UNIT_SIZE (innermode)))
8970 133659 : return simplify_gen_relational (GET_CODE (op), outermode, innermode,
8971 133659 : XEXP (op, 0), XEXP (op, 1));
8972 :
8973 : /* Distribute non-paradoxical subregs through logic ops in cases where
8974 : one term disappears.
8975 :
8976 : (subreg:M1 (and:M2 X C1)) -> (subreg:M1 X)
8977 : (subreg:M1 (ior:M2 X C1)) -> (subreg:M1 C1)
8978 : (subreg:M1 (xor:M2 X C1)) -> (subreg:M1 (not:M2 X))
8979 :
8980 : if M2 is no smaller than M1 and (subreg:M1 C1) is all-ones.
8981 :
8982 : (subreg:M1 (and:M2 X C2)) -> (subreg:M1 C2)
8983 : (subreg:M1 (ior/xor:M2 X C2)) -> (subreg:M1 X)
8984 :
8985 : if M2 is no smaller than M1 and (subreg:M1 C2) is zero. */
8986 42931661 : if (known_ge (innersize, outersize)
8987 29646320 : && GET_MODE_CLASS (outermode) == GET_MODE_CLASS (innermode)
8988 27296142 : && (GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR)
8989 44641495 : && CONSTANT_P (XEXP (op, 1)))
8990 : {
8991 891800 : rtx op1_subreg = distribute_subreg (XEXP (op, 1));
8992 891800 : if (op1_subreg == CONSTM1_RTX (outermode))
8993 : {
8994 121801 : if (GET_CODE (op) == IOR)
8995 : return op1_subreg;
8996 121567 : rtx op0 = XEXP (op, 0);
8997 121567 : if (GET_CODE (op) == XOR)
8998 889 : op0 = simplify_gen_unary (NOT, innermode, op0, innermode);
8999 121567 : return simplify_gen_subreg (outermode, op0, innermode, byte);
9000 : }
9001 :
9002 769999 : if (op1_subreg == CONST0_RTX (outermode))
9003 12322 : return (GET_CODE (op) == AND
9004 12322 : ? op1_subreg
9005 7273 : : distribute_subreg (XEXP (op, 0)));
9006 : }
9007 :
9008 : return NULL_RTX;
9009 : }
9010 :
9011 : /* Make a SUBREG operation or equivalent if it folds. */
9012 :
9013 : rtx
9014 45895368 : simplify_context::simplify_gen_subreg (machine_mode outermode, rtx op,
9015 : machine_mode innermode,
9016 : poly_uint64 byte)
9017 : {
9018 45895368 : rtx newx;
9019 :
9020 45895368 : newx = simplify_subreg (outermode, op, innermode, byte);
9021 45895368 : if (newx)
9022 : return newx;
9023 :
9024 21867230 : if (GET_CODE (op) == SUBREG
9025 21867230 : || GET_CODE (op) == CONCAT
9026 21833419 : || CONST_SCALAR_INT_P (op)
9027 21833393 : || CONST_DOUBLE_AS_FLOAT_P (op)
9028 21833393 : || CONST_FIXED_P (op)
9029 21833393 : || GET_CODE (op) == CONST_VECTOR)
9030 : return NULL_RTX;
9031 :
9032 21833383 : if (validate_subreg (outermode, innermode, op, byte))
9033 21800706 : return gen_rtx_SUBREG (outermode, op, byte);
9034 :
9035 : return NULL_RTX;
9036 : }
9037 :
9038 : /* Generates a subreg to get the least significant part of EXPR (in mode
9039 : INNER_MODE) to OUTER_MODE. */
9040 :
9041 : rtx
9042 34040889 : simplify_context::lowpart_subreg (machine_mode outer_mode, rtx expr,
9043 : machine_mode inner_mode)
9044 : {
9045 34040889 : return simplify_gen_subreg (outer_mode, expr, inner_mode,
9046 34040889 : subreg_lowpart_offset (outer_mode, inner_mode));
9047 : }
9048 :
9049 : /* Generate RTX to select element at INDEX out of vector OP. */
9050 :
9051 : rtx
9052 676477 : simplify_context::simplify_gen_vec_select (rtx op, unsigned int index)
9053 : {
9054 676477 : gcc_assert (VECTOR_MODE_P (GET_MODE (op)));
9055 :
9056 676477 : scalar_mode imode = GET_MODE_INNER (GET_MODE (op));
9057 :
9058 1352954 : if (known_eq (index * GET_MODE_SIZE (imode),
9059 : subreg_lowpart_offset (imode, GET_MODE (op))))
9060 : {
9061 676327 : rtx res = lowpart_subreg (imode, op, GET_MODE (op));
9062 676327 : if (res)
9063 : return res;
9064 : }
9065 :
9066 671 : rtx tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, GEN_INT (index)));
9067 671 : return gen_rtx_VEC_SELECT (imode, op, tmp);
9068 : }
9069 :
9070 :
9071 : /* Simplify X, an rtx expression.
9072 :
9073 : Return the simplified expression or NULL if no simplifications
9074 : were possible.
9075 :
9076 : This is the preferred entry point into the simplification routines;
9077 : however, we still allow passes to call the more specific routines.
9078 :
9079 : Right now GCC has three (yes, three) major bodies of RTL simplification
9080 : code that need to be unified.
9081 :
9082 : 1. fold_rtx in cse.cc. This code uses various CSE specific
9083 : information to aid in RTL simplification.
9084 :
9085 : 2. simplify_rtx in combine.cc. Similar to fold_rtx, except that
9086 : it uses combine specific information to aid in RTL
9087 : simplification.
9088 :
9089 : 3. The routines in this file.
9090 :
9091 :
9092 : Long term we want to only have one body of simplification code; to
9093 : get to that state I recommend the following steps:
9094 :
9095 : 1. Pour over fold_rtx & simplify_rtx and move any simplifications
9096 : which are not pass dependent state into these routines.
9097 :
9098 : 2. As code is moved by #1, change fold_rtx & simplify_rtx to
9099 : use this routine whenever possible.
9100 :
9101 : 3. Allow for pass dependent state to be provided to these
9102 : routines and add simplifications based on the pass dependent
9103 : state. Remove code from cse.cc & combine.cc that becomes
9104 : redundant/dead.
9105 :
9106 : It will take time, but ultimately the compiler will be easier to
9107 : maintain and improve. It's totally silly that when we add a
9108 : simplification that it needs to be added to 4 places (3 for RTL
9109 : simplification and 1 for tree simplification. */
9110 :
9111 : rtx
9112 47586759 : simplify_rtx (const_rtx x)
9113 : {
9114 47586759 : const enum rtx_code code = GET_CODE (x);
9115 47586759 : const machine_mode mode = GET_MODE (x);
9116 :
9117 47586759 : switch (GET_RTX_CLASS (code))
9118 : {
9119 781379 : case RTX_UNARY:
9120 1562758 : return simplify_unary_operation (code, mode,
9121 781379 : XEXP (x, 0), GET_MODE (XEXP (x, 0)));
9122 27277835 : case RTX_COMM_ARITH:
9123 27277835 : if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
9124 434263 : return simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
9125 :
9126 : /* Fall through. */
9127 :
9128 33413801 : case RTX_BIN_ARITH:
9129 33413801 : return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
9130 :
9131 82907 : case RTX_TERNARY:
9132 82907 : case RTX_BITFIELD_OPS:
9133 82907 : return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
9134 82907 : XEXP (x, 0), XEXP (x, 1),
9135 82907 : XEXP (x, 2));
9136 :
9137 206325 : case RTX_COMPARE:
9138 206325 : case RTX_COMM_COMPARE:
9139 206325 : return simplify_relational_operation (code, mode,
9140 206325 : ((GET_MODE (XEXP (x, 0))
9141 : != VOIDmode)
9142 : ? GET_MODE (XEXP (x, 0))
9143 332 : : GET_MODE (XEXP (x, 1))),
9144 206325 : XEXP (x, 0),
9145 412650 : XEXP (x, 1));
9146 :
9147 235964 : case RTX_EXTRA:
9148 235964 : if (code == SUBREG)
9149 2536 : return simplify_subreg (mode, SUBREG_REG (x),
9150 2536 : GET_MODE (SUBREG_REG (x)),
9151 2536 : SUBREG_BYTE (x));
9152 : break;
9153 :
9154 6658236 : case RTX_OBJ:
9155 6658236 : if (code == LO_SUM)
9156 : {
9157 : /* Convert (lo_sum (high FOO) FOO) to FOO. */
9158 0 : if (GET_CODE (XEXP (x, 0)) == HIGH
9159 0 : && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
9160 0 : return XEXP (x, 1);
9161 : }
9162 : break;
9163 :
9164 : default:
9165 : break;
9166 : }
9167 : return NULL;
9168 : }
9169 :
9170 : #if CHECKING_P
9171 :
9172 : namespace selftest {
9173 :
9174 : /* Make a unique pseudo REG of mode MODE for use by selftests. */
9175 :
9176 : static rtx
9177 2672 : make_test_reg (machine_mode mode)
9178 : {
9179 2672 : static int test_reg_num = LAST_VIRTUAL_REGISTER + 1;
9180 :
9181 2672 : return gen_rtx_REG (mode, test_reg_num++);
9182 : }
9183 :
9184 : static void
9185 40 : test_scalar_int_ops (machine_mode mode)
9186 : {
9187 40 : rtx op0 = make_test_reg (mode);
9188 40 : rtx op1 = make_test_reg (mode);
9189 40 : rtx six = GEN_INT (6);
9190 :
9191 40 : rtx neg_op0 = simplify_gen_unary (NEG, mode, op0, mode);
9192 40 : rtx not_op0 = simplify_gen_unary (NOT, mode, op0, mode);
9193 40 : rtx bswap_op0 = simplify_gen_unary (BSWAP, mode, op0, mode);
9194 :
9195 40 : rtx and_op0_op1 = simplify_gen_binary (AND, mode, op0, op1);
9196 40 : rtx ior_op0_op1 = simplify_gen_binary (IOR, mode, op0, op1);
9197 40 : rtx xor_op0_op1 = simplify_gen_binary (XOR, mode, op0, op1);
9198 :
9199 40 : rtx and_op0_6 = simplify_gen_binary (AND, mode, op0, six);
9200 40 : rtx and_op1_6 = simplify_gen_binary (AND, mode, op1, six);
9201 :
9202 : /* Test some binary identities. */
9203 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, op0, const0_rtx));
9204 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, const0_rtx, op0));
9205 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MINUS, mode, op0, const0_rtx));
9206 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, op0, const1_rtx));
9207 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, const1_rtx, op0));
9208 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (DIV, mode, op0, const1_rtx));
9209 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, constm1_rtx));
9210 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, constm1_rtx, op0));
9211 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, const0_rtx));
9212 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, const0_rtx, op0));
9213 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, op0, const0_rtx));
9214 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, const0_rtx, op0));
9215 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFT, mode, op0, const0_rtx));
9216 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATE, mode, op0, const0_rtx));
9217 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFTRT, mode, op0, const0_rtx));
9218 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (LSHIFTRT, mode, op0, const0_rtx));
9219 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATERT, mode, op0, const0_rtx));
9220 :
9221 : /* Test some self-inverse operations. */
9222 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (NEG, mode, neg_op0, mode));
9223 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (NOT, mode, not_op0, mode));
9224 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (BSWAP, mode, bswap_op0, mode));
9225 :
9226 : /* Test some reflexive operations. */
9227 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, op0));
9228 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, op0));
9229 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (SMIN, mode, op0, op0));
9230 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (SMAX, mode, op0, op0));
9231 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (UMIN, mode, op0, op0));
9232 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (UMAX, mode, op0, op0));
9233 :
9234 40 : ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (MINUS, mode, op0, op0));
9235 40 : ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (XOR, mode, op0, op0));
9236 :
9237 : /* Test simplify_distributive_operation. */
9238 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, xor_op0_op1, six),
9239 : simplify_gen_binary (XOR, mode, and_op0_6, and_op1_6));
9240 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, ior_op0_op1, six),
9241 : simplify_gen_binary (IOR, mode, and_op0_6, and_op1_6));
9242 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, and_op0_op1, six),
9243 : simplify_gen_binary (AND, mode, and_op0_6, and_op1_6));
9244 :
9245 : /* Test useless extensions are eliminated. */
9246 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (TRUNCATE, mode, op0, mode));
9247 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (ZERO_EXTEND, mode, op0, mode));
9248 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (SIGN_EXTEND, mode, op0, mode));
9249 40 : ASSERT_RTX_EQ (op0, lowpart_subreg (mode, op0, mode));
9250 40 : }
9251 :
9252 : /* Verify some simplifications of integer extension/truncation.
9253 : Machine mode BMODE is the guaranteed wider than SMODE. */
9254 :
9255 : static void
9256 24 : test_scalar_int_ext_ops (machine_mode bmode, machine_mode smode)
9257 : {
9258 24 : rtx sreg = make_test_reg (smode);
9259 :
9260 : /* Check truncation of extension. */
9261 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9262 : simplify_gen_unary (ZERO_EXTEND, bmode,
9263 : sreg, smode),
9264 : bmode),
9265 : sreg);
9266 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9267 : simplify_gen_unary (SIGN_EXTEND, bmode,
9268 : sreg, smode),
9269 : bmode),
9270 : sreg);
9271 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9272 : lowpart_subreg (bmode, sreg, smode),
9273 : bmode),
9274 : sreg);
9275 :
9276 : /* Test extensions, followed by logic ops, followed by truncations. */
9277 24 : rtx bsubreg = lowpart_subreg (bmode, sreg, smode);
9278 24 : rtx smask = gen_int_mode (GET_MODE_MASK (smode), bmode);
9279 24 : rtx inv_smask = gen_int_mode (~GET_MODE_MASK (smode), bmode);
9280 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9281 : simplify_gen_binary (AND, bmode,
9282 : bsubreg, smask),
9283 : bmode),
9284 : sreg);
9285 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9286 : simplify_gen_binary (AND, bmode,
9287 : bsubreg, inv_smask),
9288 : bmode),
9289 : const0_rtx);
9290 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9291 : simplify_gen_binary (IOR, bmode,
9292 : bsubreg, smask),
9293 : bmode),
9294 : constm1_rtx);
9295 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9296 : simplify_gen_binary (IOR, bmode,
9297 : bsubreg, inv_smask),
9298 : bmode),
9299 : sreg);
9300 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9301 : simplify_gen_binary (XOR, bmode,
9302 : bsubreg, smask),
9303 : bmode),
9304 : lowpart_subreg (smode,
9305 : gen_rtx_NOT (bmode, bsubreg),
9306 : bmode));
9307 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9308 : simplify_gen_binary (XOR, bmode,
9309 : bsubreg, inv_smask),
9310 : bmode),
9311 : sreg);
9312 :
9313 24 : if (known_le (GET_MODE_PRECISION (bmode), BITS_PER_WORD))
9314 : {
9315 24 : rtx breg1 = make_test_reg (bmode);
9316 24 : rtx breg2 = make_test_reg (bmode);
9317 24 : rtx ssubreg1 = lowpart_subreg (smode, breg1, bmode);
9318 24 : rtx ssubreg2 = lowpart_subreg (smode, breg2, bmode);
9319 24 : rtx not_1 = simplify_gen_unary (NOT, smode, ssubreg1, smode);
9320 24 : rtx and_12 = simplify_gen_binary (AND, smode, ssubreg1, ssubreg2);
9321 24 : rtx ior_12 = simplify_gen_binary (IOR, smode, ssubreg1, ssubreg2);
9322 24 : rtx xor_12 = simplify_gen_binary (XOR, smode, ssubreg1, ssubreg2);
9323 24 : rtx and_n12 = simplify_gen_binary (AND, smode, not_1, ssubreg2);
9324 24 : rtx ior_n12 = simplify_gen_binary (IOR, smode, not_1, ssubreg2);
9325 24 : rtx xor_12_c = simplify_gen_binary (XOR, smode, xor_12, const1_rtx);
9326 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, not_1, smode),
9327 : gen_rtx_NOT (bmode, breg1));
9328 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, and_12, smode),
9329 : gen_rtx_AND (bmode, breg1, breg2));
9330 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, ior_12, smode),
9331 : gen_rtx_IOR (bmode, breg1, breg2));
9332 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, xor_12, smode),
9333 : gen_rtx_XOR (bmode, breg1, breg2));
9334 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, and_n12, smode),
9335 : gen_rtx_AND (bmode, gen_rtx_NOT (bmode, breg1), breg2));
9336 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, ior_n12, smode),
9337 : gen_rtx_IOR (bmode, gen_rtx_NOT (bmode, breg1), breg2));
9338 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, xor_12_c, smode),
9339 : gen_rtx_XOR (bmode,
9340 : gen_rtx_XOR (bmode, breg1, breg2),
9341 : const1_rtx));
9342 : }
9343 24 : }
9344 :
9345 : /* Verify more simplifications of integer extension/truncation.
9346 : BMODE is wider than MMODE which is wider than SMODE. */
9347 :
9348 : static void
9349 16 : test_scalar_int_ext_ops2 (machine_mode bmode, machine_mode mmode,
9350 : machine_mode smode)
9351 : {
9352 16 : rtx breg = make_test_reg (bmode);
9353 16 : rtx mreg = make_test_reg (mmode);
9354 16 : rtx sreg = make_test_reg (smode);
9355 :
9356 : /* Check truncate of truncate. */
9357 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9358 : simplify_gen_unary (TRUNCATE, mmode,
9359 : breg, bmode),
9360 : mmode),
9361 : simplify_gen_unary (TRUNCATE, smode, breg, bmode));
9362 :
9363 : /* Check extension of extension. */
9364 16 : ASSERT_RTX_EQ (simplify_gen_unary (ZERO_EXTEND, bmode,
9365 : simplify_gen_unary (ZERO_EXTEND, mmode,
9366 : sreg, smode),
9367 : mmode),
9368 : simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
9369 16 : ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
9370 : simplify_gen_unary (SIGN_EXTEND, mmode,
9371 : sreg, smode),
9372 : mmode),
9373 : simplify_gen_unary (SIGN_EXTEND, bmode, sreg, smode));
9374 16 : ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
9375 : simplify_gen_unary (ZERO_EXTEND, mmode,
9376 : sreg, smode),
9377 : mmode),
9378 : simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
9379 :
9380 : /* Check truncation of extension. */
9381 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9382 : simplify_gen_unary (ZERO_EXTEND, bmode,
9383 : mreg, mmode),
9384 : bmode),
9385 : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
9386 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9387 : simplify_gen_unary (SIGN_EXTEND, bmode,
9388 : mreg, mmode),
9389 : bmode),
9390 : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
9391 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9392 : lowpart_subreg (bmode, mreg, mmode),
9393 : bmode),
9394 : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
9395 16 : }
9396 :
9397 : /* Test comparisons of comparisons, with the inner comparisons being
9398 : between values of mode MODE2 and producing results of mode MODE1,
9399 : and with the outer comparisons producing results of mode MODE0. */
9400 :
9401 : static void
9402 4 : test_comparisons (machine_mode mode0, machine_mode mode1, machine_mode mode2)
9403 : {
9404 4 : rtx reg0 = make_test_reg (mode2);
9405 4 : rtx reg1 = make_test_reg (mode2);
9406 :
9407 4 : static const rtx_code codes[] = {
9408 : EQ, NE, LT, LTU, LE, LEU, GE, GEU, GT, GTU
9409 : };
9410 4 : constexpr auto num_codes = ARRAY_SIZE (codes);
9411 4 : rtx cmps[num_codes];
9412 4 : rtx vals[] = { constm1_rtx, const0_rtx, const1_rtx };
9413 :
9414 44 : for (unsigned int i = 0; i < num_codes; ++i)
9415 40 : cmps[i] = gen_rtx_fmt_ee (codes[i], mode1, reg0, reg1);
9416 :
9417 44 : for (auto code : codes)
9418 440 : for (unsigned int i0 = 0; i0 < num_codes; ++i0)
9419 4400 : for (unsigned int i1 = 0; i1 < num_codes; ++i1)
9420 : {
9421 4000 : rtx cmp_res = simplify_relational_operation (code, mode0, mode1,
9422 : cmps[i0], cmps[i1]);
9423 4000 : if (i0 >= 2 && i1 >= 2 && (i0 ^ i1) & 1)
9424 1280 : ASSERT_TRUE (cmp_res == NULL_RTX);
9425 : else
9426 : {
9427 2720 : ASSERT_TRUE (cmp_res != NULL_RTX
9428 : && (CONSTANT_P (cmp_res)
9429 : || (COMPARISON_P (cmp_res)
9430 : && GET_MODE (cmp_res) == mode0
9431 : && REG_P (XEXP (cmp_res, 0))
9432 : && REG_P (XEXP (cmp_res, 1)))));
9433 10880 : for (rtx reg0_val : vals)
9434 32640 : for (rtx reg1_val : vals)
9435 : {
9436 24480 : rtx val0 = simplify_const_relational_operation
9437 24480 : (codes[i0], mode1, reg0_val, reg1_val);
9438 24480 : rtx val1 = simplify_const_relational_operation
9439 24480 : (codes[i1], mode1, reg0_val, reg1_val);
9440 24480 : rtx val = simplify_const_relational_operation
9441 24480 : (code, mode0, val0, val1);
9442 24480 : rtx folded = cmp_res;
9443 24480 : if (COMPARISON_P (cmp_res))
9444 16704 : folded = simplify_const_relational_operation
9445 16704 : (GET_CODE (cmp_res), mode0,
9446 16704 : XEXP (cmp_res, 0) == reg0 ? reg0_val : reg1_val,
9447 16704 : XEXP (cmp_res, 1) == reg0 ? reg0_val : reg1_val);
9448 24480 : ASSERT_RTX_EQ (val, folded);
9449 : }
9450 : }
9451 : }
9452 4 : }
9453 :
9454 :
9455 : /* Verify some simplifications involving scalar expressions. */
9456 :
9457 : static void
9458 4 : test_scalar_ops ()
9459 : {
9460 500 : for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
9461 : {
9462 496 : machine_mode mode = (machine_mode) i;
9463 496 : if (SCALAR_INT_MODE_P (mode) && mode != BImode)
9464 40 : test_scalar_int_ops (mode);
9465 : }
9466 :
9467 4 : test_scalar_int_ext_ops (HImode, QImode);
9468 4 : test_scalar_int_ext_ops (SImode, QImode);
9469 4 : test_scalar_int_ext_ops (SImode, HImode);
9470 4 : test_scalar_int_ext_ops (DImode, QImode);
9471 4 : test_scalar_int_ext_ops (DImode, HImode);
9472 4 : test_scalar_int_ext_ops (DImode, SImode);
9473 :
9474 4 : test_scalar_int_ext_ops2 (SImode, HImode, QImode);
9475 4 : test_scalar_int_ext_ops2 (DImode, HImode, QImode);
9476 4 : test_scalar_int_ext_ops2 (DImode, SImode, QImode);
9477 4 : test_scalar_int_ext_ops2 (DImode, SImode, HImode);
9478 :
9479 4 : test_comparisons (QImode, HImode, SImode);
9480 4 : }
9481 :
9482 : /* Test vector simplifications involving VEC_DUPLICATE in which the
9483 : operands and result have vector mode MODE. SCALAR_REG is a pseudo
9484 : register that holds one element of MODE. */
9485 :
9486 : static void
9487 224 : test_vector_ops_duplicate (machine_mode mode, rtx scalar_reg)
9488 : {
9489 224 : scalar_mode inner_mode = GET_MODE_INNER (mode);
9490 224 : rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
9491 448 : poly_uint64 nunits = GET_MODE_NUNITS (mode);
9492 224 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
9493 : {
9494 : /* Test some simple unary cases with VEC_DUPLICATE arguments. */
9495 124 : rtx not_scalar_reg = gen_rtx_NOT (inner_mode, scalar_reg);
9496 124 : rtx duplicate_not = gen_rtx_VEC_DUPLICATE (mode, not_scalar_reg);
9497 124 : ASSERT_RTX_EQ (duplicate,
9498 : simplify_unary_operation (NOT, mode,
9499 : duplicate_not, mode));
9500 :
9501 124 : rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
9502 124 : rtx duplicate_neg = gen_rtx_VEC_DUPLICATE (mode, neg_scalar_reg);
9503 124 : ASSERT_RTX_EQ (duplicate,
9504 : simplify_unary_operation (NEG, mode,
9505 : duplicate_neg, mode));
9506 :
9507 : /* Test some simple binary cases with VEC_DUPLICATE arguments. */
9508 124 : ASSERT_RTX_EQ (duplicate,
9509 : simplify_binary_operation (PLUS, mode, duplicate,
9510 : CONST0_RTX (mode)));
9511 :
9512 124 : ASSERT_RTX_EQ (duplicate,
9513 : simplify_binary_operation (MINUS, mode, duplicate,
9514 : CONST0_RTX (mode)));
9515 :
9516 124 : ASSERT_RTX_PTR_EQ (CONST0_RTX (mode),
9517 : simplify_binary_operation (MINUS, mode, duplicate,
9518 : duplicate));
9519 : }
9520 :
9521 : /* Test a scalar VEC_SELECT of a VEC_DUPLICATE. */
9522 224 : rtx zero_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const0_rtx));
9523 224 : ASSERT_RTX_PTR_EQ (scalar_reg,
9524 : simplify_binary_operation (VEC_SELECT, inner_mode,
9525 : duplicate, zero_par));
9526 :
9527 224 : unsigned HOST_WIDE_INT const_nunits;
9528 224 : if (nunits.is_constant (&const_nunits))
9529 : {
9530 : /* And again with the final element. */
9531 224 : rtx last_index = gen_int_mode (const_nunits - 1, word_mode);
9532 224 : rtx last_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, last_index));
9533 224 : ASSERT_RTX_PTR_EQ (scalar_reg,
9534 : simplify_binary_operation (VEC_SELECT, inner_mode,
9535 : duplicate, last_par));
9536 :
9537 : /* Test a scalar subreg of a VEC_MERGE of a VEC_DUPLICATE. */
9538 : /* Skip this test for vectors of booleans, because offset is in bytes,
9539 : while vec_merge indices are in elements (usually bits). */
9540 224 : if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
9541 : {
9542 224 : rtx vector_reg = make_test_reg (mode);
9543 3732 : for (unsigned HOST_WIDE_INT i = 0; i < const_nunits; i++)
9544 : {
9545 3288 : if (i >= HOST_BITS_PER_WIDE_INT)
9546 : break;
9547 3284 : rtx mask = GEN_INT ((HOST_WIDE_INT_1U << i) | (i + 1));
9548 3284 : rtx vm = gen_rtx_VEC_MERGE (mode, duplicate, vector_reg, mask);
9549 6568 : poly_uint64 offset = i * GET_MODE_SIZE (inner_mode);
9550 :
9551 3284 : ASSERT_RTX_EQ (scalar_reg,
9552 : simplify_gen_subreg (inner_mode, vm,
9553 : mode, offset));
9554 : }
9555 : }
9556 : }
9557 :
9558 : /* Test a scalar subreg of a VEC_DUPLICATE. */
9559 224 : poly_uint64 offset = subreg_lowpart_offset (inner_mode, mode);
9560 224 : ASSERT_RTX_EQ (scalar_reg,
9561 : simplify_gen_subreg (inner_mode, duplicate,
9562 : mode, offset));
9563 :
9564 224 : machine_mode narrower_mode;
9565 224 : if (maybe_ne (nunits, 2U)
9566 184 : && multiple_p (nunits, 2)
9567 396 : && mode_for_vector (inner_mode, 2).exists (&narrower_mode)
9568 396 : && VECTOR_MODE_P (narrower_mode))
9569 : {
9570 : /* Test VEC_DUPLICATE of a vector. */
9571 172 : rtx_vector_builder nbuilder (narrower_mode, 2, 1);
9572 172 : nbuilder.quick_push (const0_rtx);
9573 172 : nbuilder.quick_push (const1_rtx);
9574 172 : rtx_vector_builder builder (mode, 2, 1);
9575 172 : builder.quick_push (const0_rtx);
9576 172 : builder.quick_push (const1_rtx);
9577 172 : ASSERT_RTX_EQ (builder.build (),
9578 : simplify_unary_operation (VEC_DUPLICATE, mode,
9579 : nbuilder.build (),
9580 : narrower_mode));
9581 :
9582 : /* Test VEC_SELECT of a vector. */
9583 172 : rtx vec_par
9584 172 : = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, const1_rtx, const0_rtx));
9585 172 : rtx narrower_duplicate
9586 172 : = gen_rtx_VEC_DUPLICATE (narrower_mode, scalar_reg);
9587 172 : ASSERT_RTX_EQ (narrower_duplicate,
9588 : simplify_binary_operation (VEC_SELECT, narrower_mode,
9589 : duplicate, vec_par));
9590 :
9591 : /* Test a vector subreg of a VEC_DUPLICATE. */
9592 172 : poly_uint64 offset = subreg_lowpart_offset (narrower_mode, mode);
9593 172 : ASSERT_RTX_EQ (narrower_duplicate,
9594 : simplify_gen_subreg (narrower_mode, duplicate,
9595 : mode, offset));
9596 172 : }
9597 224 : }
9598 :
9599 : /* Test vector simplifications involving VEC_SERIES in which the
9600 : operands and result have vector mode MODE. SCALAR_REG is a pseudo
9601 : register that holds one element of MODE. */
9602 :
9603 : static void
9604 92 : test_vector_ops_series (machine_mode mode, rtx scalar_reg)
9605 : {
9606 : /* Test unary cases with VEC_SERIES arguments. */
9607 92 : scalar_mode inner_mode = GET_MODE_INNER (mode);
9608 92 : rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
9609 92 : rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
9610 92 : rtx series_0_r = gen_rtx_VEC_SERIES (mode, const0_rtx, scalar_reg);
9611 92 : rtx series_0_nr = gen_rtx_VEC_SERIES (mode, const0_rtx, neg_scalar_reg);
9612 92 : rtx series_nr_1 = gen_rtx_VEC_SERIES (mode, neg_scalar_reg, const1_rtx);
9613 92 : rtx series_r_m1 = gen_rtx_VEC_SERIES (mode, scalar_reg, constm1_rtx);
9614 92 : rtx series_r_r = gen_rtx_VEC_SERIES (mode, scalar_reg, scalar_reg);
9615 92 : rtx series_nr_nr = gen_rtx_VEC_SERIES (mode, neg_scalar_reg,
9616 : neg_scalar_reg);
9617 92 : ASSERT_RTX_EQ (series_0_r,
9618 : simplify_unary_operation (NEG, mode, series_0_nr, mode));
9619 92 : ASSERT_RTX_EQ (series_r_m1,
9620 : simplify_unary_operation (NEG, mode, series_nr_1, mode));
9621 92 : ASSERT_RTX_EQ (series_r_r,
9622 : simplify_unary_operation (NEG, mode, series_nr_nr, mode));
9623 :
9624 : /* Test that a VEC_SERIES with a zero step is simplified away. */
9625 92 : ASSERT_RTX_EQ (duplicate,
9626 : simplify_binary_operation (VEC_SERIES, mode,
9627 : scalar_reg, const0_rtx));
9628 :
9629 : /* Test PLUS and MINUS with VEC_SERIES. */
9630 92 : rtx series_0_1 = gen_const_vec_series (mode, const0_rtx, const1_rtx);
9631 92 : rtx series_0_m1 = gen_const_vec_series (mode, const0_rtx, constm1_rtx);
9632 92 : rtx series_r_1 = gen_rtx_VEC_SERIES (mode, scalar_reg, const1_rtx);
9633 92 : ASSERT_RTX_EQ (series_r_r,
9634 : simplify_binary_operation (PLUS, mode, series_0_r,
9635 : duplicate));
9636 92 : ASSERT_RTX_EQ (series_r_1,
9637 : simplify_binary_operation (PLUS, mode, duplicate,
9638 : series_0_1));
9639 92 : ASSERT_RTX_EQ (series_r_m1,
9640 : simplify_binary_operation (PLUS, mode, duplicate,
9641 : series_0_m1));
9642 92 : ASSERT_RTX_EQ (series_0_r,
9643 : simplify_binary_operation (MINUS, mode, series_r_r,
9644 : duplicate));
9645 92 : ASSERT_RTX_EQ (series_r_m1,
9646 : simplify_binary_operation (MINUS, mode, duplicate,
9647 : series_0_1));
9648 92 : ASSERT_RTX_EQ (series_r_1,
9649 : simplify_binary_operation (MINUS, mode, duplicate,
9650 : series_0_m1));
9651 92 : ASSERT_RTX_EQ (series_0_m1,
9652 : simplify_binary_operation (VEC_SERIES, mode, const0_rtx,
9653 : constm1_rtx));
9654 :
9655 : /* Test NEG on constant vector series. */
9656 92 : ASSERT_RTX_EQ (series_0_m1,
9657 : simplify_unary_operation (NEG, mode, series_0_1, mode));
9658 92 : ASSERT_RTX_EQ (series_0_1,
9659 : simplify_unary_operation (NEG, mode, series_0_m1, mode));
9660 :
9661 : /* Test PLUS and MINUS on constant vector series. */
9662 92 : rtx scalar2 = gen_int_mode (2, inner_mode);
9663 92 : rtx scalar3 = gen_int_mode (3, inner_mode);
9664 92 : rtx series_1_1 = gen_const_vec_series (mode, const1_rtx, const1_rtx);
9665 92 : rtx series_0_2 = gen_const_vec_series (mode, const0_rtx, scalar2);
9666 92 : rtx series_1_3 = gen_const_vec_series (mode, const1_rtx, scalar3);
9667 92 : ASSERT_RTX_EQ (series_1_1,
9668 : simplify_binary_operation (PLUS, mode, series_0_1,
9669 : CONST1_RTX (mode)));
9670 92 : ASSERT_RTX_EQ (series_0_m1,
9671 : simplify_binary_operation (PLUS, mode, CONST0_RTX (mode),
9672 : series_0_m1));
9673 92 : ASSERT_RTX_EQ (series_1_3,
9674 : simplify_binary_operation (PLUS, mode, series_1_1,
9675 : series_0_2));
9676 92 : ASSERT_RTX_EQ (series_0_1,
9677 : simplify_binary_operation (MINUS, mode, series_1_1,
9678 : CONST1_RTX (mode)));
9679 92 : ASSERT_RTX_EQ (series_1_1,
9680 : simplify_binary_operation (MINUS, mode, CONST1_RTX (mode),
9681 : series_0_m1));
9682 92 : ASSERT_RTX_EQ (series_1_1,
9683 : simplify_binary_operation (MINUS, mode, series_1_3,
9684 : series_0_2));
9685 :
9686 : /* Test MULT between constant vectors. */
9687 92 : rtx vec2 = gen_const_vec_duplicate (mode, scalar2);
9688 92 : rtx vec3 = gen_const_vec_duplicate (mode, scalar3);
9689 92 : rtx scalar9 = gen_int_mode (9, inner_mode);
9690 92 : rtx series_3_9 = gen_const_vec_series (mode, scalar3, scalar9);
9691 92 : ASSERT_RTX_EQ (series_0_2,
9692 : simplify_binary_operation (MULT, mode, series_0_1, vec2));
9693 92 : ASSERT_RTX_EQ (series_3_9,
9694 : simplify_binary_operation (MULT, mode, vec3, series_1_3));
9695 92 : if (!GET_MODE_NUNITS (mode).is_constant ())
9696 : ASSERT_FALSE (simplify_binary_operation (MULT, mode, series_0_1,
9697 : series_0_1));
9698 :
9699 : /* Test ASHIFT between constant vectors. */
9700 92 : ASSERT_RTX_EQ (series_0_2,
9701 : simplify_binary_operation (ASHIFT, mode, series_0_1,
9702 : CONST1_RTX (mode)));
9703 92 : if (!GET_MODE_NUNITS (mode).is_constant ())
9704 : ASSERT_FALSE (simplify_binary_operation (ASHIFT, mode, CONST1_RTX (mode),
9705 : series_0_1));
9706 92 : }
9707 :
9708 : static rtx
9709 3136 : simplify_merge_mask (rtx x, rtx mask, int op)
9710 : {
9711 0 : return simplify_context ().simplify_merge_mask (x, mask, op);
9712 : }
9713 :
9714 : /* Verify simplify_merge_mask works correctly. */
9715 :
9716 : static void
9717 224 : test_vec_merge (machine_mode mode)
9718 : {
9719 224 : rtx op0 = make_test_reg (mode);
9720 224 : rtx op1 = make_test_reg (mode);
9721 224 : rtx op2 = make_test_reg (mode);
9722 224 : rtx op3 = make_test_reg (mode);
9723 224 : rtx op4 = make_test_reg (mode);
9724 224 : rtx op5 = make_test_reg (mode);
9725 224 : rtx mask1 = make_test_reg (SImode);
9726 224 : rtx mask2 = make_test_reg (SImode);
9727 224 : rtx vm1 = gen_rtx_VEC_MERGE (mode, op0, op1, mask1);
9728 224 : rtx vm2 = gen_rtx_VEC_MERGE (mode, op2, op3, mask1);
9729 224 : rtx vm3 = gen_rtx_VEC_MERGE (mode, op4, op5, mask1);
9730 :
9731 : /* Simple vec_merge. */
9732 224 : ASSERT_EQ (op0, simplify_merge_mask (vm1, mask1, 0));
9733 224 : ASSERT_EQ (op1, simplify_merge_mask (vm1, mask1, 1));
9734 224 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 0));
9735 224 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 1));
9736 :
9737 : /* Nested vec_merge.
9738 : It's tempting to make this simplify right down to opN, but we don't
9739 : because all the simplify_* functions assume that the operands have
9740 : already been simplified. */
9741 224 : rtx nvm = gen_rtx_VEC_MERGE (mode, vm1, vm2, mask1);
9742 224 : ASSERT_EQ (vm1, simplify_merge_mask (nvm, mask1, 0));
9743 224 : ASSERT_EQ (vm2, simplify_merge_mask (nvm, mask1, 1));
9744 :
9745 : /* Intermediate unary op. */
9746 224 : rtx unop = gen_rtx_NOT (mode, vm1);
9747 224 : ASSERT_RTX_EQ (gen_rtx_NOT (mode, op0),
9748 : simplify_merge_mask (unop, mask1, 0));
9749 224 : ASSERT_RTX_EQ (gen_rtx_NOT (mode, op1),
9750 : simplify_merge_mask (unop, mask1, 1));
9751 :
9752 : /* Intermediate binary op. */
9753 224 : rtx binop = gen_rtx_PLUS (mode, vm1, vm2);
9754 224 : ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op0, op2),
9755 : simplify_merge_mask (binop, mask1, 0));
9756 224 : ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op1, op3),
9757 : simplify_merge_mask (binop, mask1, 1));
9758 :
9759 : /* Intermediate ternary op. */
9760 224 : rtx tenop = gen_rtx_FMA (mode, vm1, vm2, vm3);
9761 224 : ASSERT_RTX_EQ (gen_rtx_FMA (mode, op0, op2, op4),
9762 : simplify_merge_mask (tenop, mask1, 0));
9763 224 : ASSERT_RTX_EQ (gen_rtx_FMA (mode, op1, op3, op5),
9764 : simplify_merge_mask (tenop, mask1, 1));
9765 :
9766 : /* Side effects. */
9767 224 : rtx badop0 = gen_rtx_PRE_INC (mode, op0);
9768 224 : rtx badvm = gen_rtx_VEC_MERGE (mode, badop0, op1, mask1);
9769 224 : ASSERT_EQ (badop0, simplify_merge_mask (badvm, mask1, 0));
9770 224 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (badvm, mask1, 1));
9771 :
9772 : /* Called indirectly. */
9773 224 : ASSERT_RTX_EQ (gen_rtx_VEC_MERGE (mode, op0, op3, mask1),
9774 : simplify_rtx (nvm));
9775 224 : }
9776 :
9777 : /* Test that vector rotate formation works at RTL level. Try various
9778 : combinations of (REG << C) [|,^,+] (REG >> (<bitwidth> - C)). */
9779 :
9780 : static void
9781 92 : test_vector_rotate (rtx reg)
9782 : {
9783 92 : machine_mode mode = GET_MODE (reg);
9784 92 : unsigned bitwidth = GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT;
9785 92 : rtx plus_rtx = gen_rtx_PLUS (mode, reg, reg);
9786 92 : rtx lshftrt_amnt = GEN_INT (bitwidth - 1);
9787 92 : lshftrt_amnt = gen_const_vec_duplicate (mode, lshftrt_amnt);
9788 92 : rtx lshiftrt_rtx = gen_rtx_LSHIFTRT (mode, reg, lshftrt_amnt);
9789 92 : rtx rotate_rtx = gen_rtx_ROTATE (mode, reg, CONST1_RTX (mode));
9790 : /* Test explicitly the case where ASHIFT (x, 1) is a PLUS (x, x). */
9791 92 : ASSERT_RTX_EQ (rotate_rtx,
9792 : simplify_rtx (gen_rtx_IOR (mode, plus_rtx, lshiftrt_rtx)));
9793 92 : ASSERT_RTX_EQ (rotate_rtx,
9794 : simplify_rtx (gen_rtx_XOR (mode, plus_rtx, lshiftrt_rtx)));
9795 92 : ASSERT_RTX_EQ (rotate_rtx,
9796 : simplify_rtx (gen_rtx_PLUS (mode, plus_rtx, lshiftrt_rtx)));
9797 :
9798 : /* Don't go through every possible rotate amount to save execution time.
9799 : Multiple of BITS_PER_UNIT amounts could conceivably be simplified to
9800 : other bswap operations sometimes. Go through just the odd amounts. */
9801 1380 : for (unsigned i = 3; i < bitwidth - 2; i += 2)
9802 : {
9803 1288 : rtx rot_amnt = gen_const_vec_duplicate (mode, GEN_INT (i));
9804 1288 : rtx ashift_rtx = gen_rtx_ASHIFT (mode, reg, rot_amnt);
9805 1288 : lshftrt_amnt = gen_const_vec_duplicate (mode, GEN_INT (bitwidth - i));
9806 1288 : lshiftrt_rtx = gen_rtx_LSHIFTRT (mode, reg, lshftrt_amnt);
9807 1288 : rotate_rtx = gen_rtx_ROTATE (mode, reg, rot_amnt);
9808 1288 : ASSERT_RTX_EQ (rotate_rtx,
9809 : simplify_rtx (gen_rtx_IOR (mode, ashift_rtx, lshiftrt_rtx)));
9810 1288 : ASSERT_RTX_EQ (rotate_rtx,
9811 : simplify_rtx (gen_rtx_XOR (mode, ashift_rtx, lshiftrt_rtx)));
9812 1288 : ASSERT_RTX_EQ (rotate_rtx,
9813 : simplify_rtx (gen_rtx_PLUS (mode, ashift_rtx, lshiftrt_rtx)));
9814 : }
9815 92 : }
9816 :
9817 : /* Test subregs of integer vector constant X, trying elements in
9818 : the range [ELT_BIAS, ELT_BIAS + constant_lower_bound (NELTS)),
9819 : where NELTS is the number of elements in X. Subregs involving
9820 : elements [ELT_BIAS, ELT_BIAS + FIRST_VALID) are expected to fail. */
9821 :
9822 : static void
9823 276 : test_vector_subregs_modes (rtx x, poly_uint64 elt_bias = 0,
9824 : unsigned int first_valid = 0)
9825 : {
9826 276 : machine_mode inner_mode = GET_MODE (x);
9827 276 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9828 :
9829 34500 : for (unsigned int modei = 0; modei < NUM_MACHINE_MODES; ++modei)
9830 : {
9831 34224 : machine_mode outer_mode = (machine_mode) modei;
9832 34224 : if (!VECTOR_MODE_P (outer_mode))
9833 18768 : continue;
9834 :
9835 15456 : unsigned int outer_nunits;
9836 15456 : if (GET_MODE_INNER (outer_mode) == int_mode
9837 1932 : && GET_MODE_NUNITS (outer_mode).is_constant (&outer_nunits)
9838 20412 : && multiple_p (GET_MODE_NUNITS (inner_mode), outer_nunits))
9839 : {
9840 : /* Test subregs in which the outer mode is a smaller,
9841 : constant-sized vector of the same element type. */
9842 1092 : unsigned int limit
9843 1092 : = constant_lower_bound (GET_MODE_NUNITS (inner_mode));
9844 8028 : for (unsigned int elt = 0; elt < limit; elt += outer_nunits)
9845 : {
9846 6936 : rtx expected = NULL_RTX;
9847 6936 : if (elt >= first_valid)
9848 : {
9849 6936 : rtx_vector_builder builder (outer_mode, outer_nunits, 1);
9850 46704 : for (unsigned int i = 0; i < outer_nunits; ++i)
9851 32832 : builder.quick_push (CONST_VECTOR_ELT (x, elt + i));
9852 6936 : expected = builder.build ();
9853 6936 : }
9854 13872 : poly_uint64 byte = (elt_bias + elt) * GET_MODE_SIZE (int_mode);
9855 6936 : ASSERT_RTX_EQ (expected,
9856 : simplify_subreg (outer_mode, x,
9857 : inner_mode, byte));
9858 : }
9859 : }
9860 28728 : else if (known_eq (GET_MODE_SIZE (outer_mode),
9861 : GET_MODE_SIZE (inner_mode))
9862 2040 : && known_eq (elt_bias, 0U)
9863 2040 : && (GET_MODE_CLASS (outer_mode) != MODE_VECTOR_BOOL
9864 0 : || known_eq (GET_MODE_BITSIZE (outer_mode),
9865 : GET_MODE_NUNITS (outer_mode)))
9866 2040 : && (!FLOAT_MODE_P (outer_mode)
9867 15876 : || (FLOAT_MODE_FORMAT (outer_mode)->ieee_bits
9868 1104 : == GET_MODE_UNIT_PRECISION (outer_mode)))
9869 14364 : && (GET_MODE_SIZE (inner_mode).is_constant ()
9870 : || !CONST_VECTOR_STEPPED_P (x)))
9871 : {
9872 : /* Try converting to OUTER_MODE and back. */
9873 1800 : rtx outer_x = simplify_subreg (outer_mode, x, inner_mode, 0);
9874 1800 : ASSERT_TRUE (outer_x != NULL_RTX);
9875 1800 : ASSERT_RTX_EQ (x, simplify_subreg (inner_mode, outer_x,
9876 : outer_mode, 0));
9877 : }
9878 : }
9879 :
9880 276 : if (BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
9881 : {
9882 : /* Test each byte in the element range. */
9883 276 : unsigned int limit
9884 276 : = constant_lower_bound (GET_MODE_SIZE (inner_mode));
9885 14604 : for (unsigned int i = 0; i < limit; ++i)
9886 : {
9887 14328 : unsigned int elt = i / GET_MODE_SIZE (int_mode);
9888 14328 : rtx expected = NULL_RTX;
9889 14328 : if (elt >= first_valid)
9890 : {
9891 14328 : unsigned int byte_shift = i % GET_MODE_SIZE (int_mode);
9892 14328 : if (BYTES_BIG_ENDIAN)
9893 : byte_shift = GET_MODE_SIZE (int_mode) - byte_shift - 1;
9894 14328 : rtx_mode_t vec_elt (CONST_VECTOR_ELT (x, elt), int_mode);
9895 14328 : wide_int shifted_elt
9896 14328 : = wi::lrshift (vec_elt, byte_shift * BITS_PER_UNIT);
9897 14328 : expected = immed_wide_int_const (shifted_elt, QImode);
9898 14328 : }
9899 28656 : poly_uint64 byte = elt_bias * GET_MODE_SIZE (int_mode) + i;
9900 14328 : ASSERT_RTX_EQ (expected,
9901 : simplify_subreg (QImode, x, inner_mode, byte));
9902 : }
9903 : }
9904 276 : }
9905 :
9906 : /* Test constant subregs of integer vector mode INNER_MODE, using 1
9907 : element per pattern. */
9908 :
9909 : static void
9910 92 : test_vector_subregs_repeating (machine_mode inner_mode)
9911 : {
9912 184 : poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
9913 92 : unsigned int min_nunits = constant_lower_bound (nunits);
9914 92 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9915 92 : unsigned int count = gcd (min_nunits, 8);
9916 :
9917 92 : rtx_vector_builder builder (inner_mode, count, 1);
9918 776 : for (unsigned int i = 0; i < count; ++i)
9919 592 : builder.quick_push (gen_int_mode (8 - i, int_mode));
9920 92 : rtx x = builder.build ();
9921 :
9922 92 : test_vector_subregs_modes (x);
9923 92 : if (!nunits.is_constant ())
9924 : test_vector_subregs_modes (x, nunits - min_nunits);
9925 92 : }
9926 :
9927 : /* Test constant subregs of integer vector mode INNER_MODE, using 2
9928 : elements per pattern. */
9929 :
9930 : static void
9931 92 : test_vector_subregs_fore_back (machine_mode inner_mode)
9932 : {
9933 184 : poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
9934 92 : unsigned int min_nunits = constant_lower_bound (nunits);
9935 92 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9936 92 : unsigned int count = gcd (min_nunits, 4);
9937 :
9938 92 : rtx_vector_builder builder (inner_mode, count, 2);
9939 536 : for (unsigned int i = 0; i < count; ++i)
9940 352 : builder.quick_push (gen_int_mode (i, int_mode));
9941 444 : for (unsigned int i = 0; i < count; ++i)
9942 352 : builder.quick_push (gen_int_mode (-1 - (int) i, int_mode));
9943 92 : rtx x = builder.build ();
9944 :
9945 92 : test_vector_subregs_modes (x);
9946 92 : if (!nunits.is_constant ())
9947 : test_vector_subregs_modes (x, nunits - min_nunits, count);
9948 92 : }
9949 :
9950 : /* Test constant subregs of integer vector mode INNER_MODE, using 3
9951 : elements per pattern. */
9952 :
9953 : static void
9954 92 : test_vector_subregs_stepped (machine_mode inner_mode)
9955 : {
9956 : /* Build { 0, 1, 2, 3, ... }. */
9957 92 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9958 92 : rtx_vector_builder builder (inner_mode, 1, 3);
9959 460 : for (unsigned int i = 0; i < 3; ++i)
9960 276 : builder.quick_push (gen_int_mode (i, int_mode));
9961 92 : rtx x = builder.build ();
9962 :
9963 92 : test_vector_subregs_modes (x);
9964 92 : }
9965 :
9966 : /* Test constant subregs of integer vector mode INNER_MODE. */
9967 :
9968 : static void
9969 92 : test_vector_subregs (machine_mode inner_mode)
9970 : {
9971 92 : test_vector_subregs_repeating (inner_mode);
9972 92 : test_vector_subregs_fore_back (inner_mode);
9973 92 : test_vector_subregs_stepped (inner_mode);
9974 92 : }
9975 :
9976 : /* Verify some simplifications involving vectors. */
9977 :
9978 : static void
9979 4 : test_vector_ops ()
9980 : {
9981 500 : for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
9982 : {
9983 496 : machine_mode mode = (machine_mode) i;
9984 496 : if (VECTOR_MODE_P (mode))
9985 : {
9986 448 : rtx scalar_reg = make_test_reg (GET_MODE_INNER (mode));
9987 224 : test_vector_ops_duplicate (mode, scalar_reg);
9988 224 : rtx vector_reg = make_test_reg (mode);
9989 224 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
9990 348 : && maybe_gt (GET_MODE_NUNITS (mode), 2))
9991 : {
9992 92 : test_vector_ops_series (mode, scalar_reg);
9993 92 : test_vector_subregs (mode);
9994 92 : test_vector_rotate (vector_reg);
9995 : }
9996 224 : test_vec_merge (mode);
9997 : }
9998 : }
9999 4 : }
10000 :
10001 : template<unsigned int N>
10002 : struct simplify_const_poly_int_tests
10003 : {
10004 : static void run ();
10005 : };
10006 :
10007 : template<>
10008 : struct simplify_const_poly_int_tests<1>
10009 : {
10010 : static void run () {}
10011 : };
10012 :
10013 : /* Test various CONST_POLY_INT properties. */
10014 :
10015 : template<unsigned int N>
10016 : void
10017 : simplify_const_poly_int_tests<N>::run ()
10018 : {
10019 : using poly_int64 = poly_int<N, HOST_WIDE_INT>;
10020 : rtx x1 = gen_int_mode (poly_int64 (1, 1), QImode);
10021 : rtx x2 = gen_int_mode (poly_int64 (-80, 127), QImode);
10022 : rtx x3 = gen_int_mode (poly_int64 (-79, -128), QImode);
10023 : rtx x4 = gen_int_mode (poly_int64 (5, 4), QImode);
10024 : rtx x5 = gen_int_mode (poly_int64 (30, 24), QImode);
10025 : rtx x6 = gen_int_mode (poly_int64 (20, 16), QImode);
10026 : rtx x7 = gen_int_mode (poly_int64 (7, 4), QImode);
10027 : rtx x8 = gen_int_mode (poly_int64 (30, 24), HImode);
10028 : rtx x9 = gen_int_mode (poly_int64 (-30, -24), HImode);
10029 : rtx x10 = gen_int_mode (poly_int64 (-31, -24), HImode);
10030 : rtx two = GEN_INT (2);
10031 : rtx six = GEN_INT (6);
10032 : poly_uint64 offset = subreg_lowpart_offset (QImode, HImode);
10033 :
10034 : /* These tests only try limited operation combinations. Fuller arithmetic
10035 : testing is done directly on poly_ints. */
10036 : ASSERT_EQ (simplify_unary_operation (NEG, HImode, x8, HImode), x9);
10037 : ASSERT_EQ (simplify_unary_operation (NOT, HImode, x8, HImode), x10);
10038 : ASSERT_EQ (simplify_unary_operation (TRUNCATE, QImode, x8, HImode), x5);
10039 : ASSERT_EQ (simplify_binary_operation (PLUS, QImode, x1, x2), x3);
10040 : ASSERT_EQ (simplify_binary_operation (MINUS, QImode, x3, x1), x2);
10041 : ASSERT_EQ (simplify_binary_operation (MULT, QImode, x4, six), x5);
10042 : ASSERT_EQ (simplify_binary_operation (MULT, QImode, six, x4), x5);
10043 : ASSERT_EQ (simplify_binary_operation (ASHIFT, QImode, x4, two), x6);
10044 : ASSERT_EQ (simplify_binary_operation (IOR, QImode, x4, two), x7);
10045 : ASSERT_EQ (simplify_subreg (HImode, x5, QImode, 0), x8);
10046 : ASSERT_EQ (simplify_subreg (QImode, x8, HImode, offset), x5);
10047 : }
10048 :
10049 : /* Run all of the selftests within this file. */
10050 :
10051 : void
10052 4 : simplify_rtx_cc_tests ()
10053 : {
10054 4 : test_scalar_ops ();
10055 4 : test_vector_ops ();
10056 4 : simplify_const_poly_int_tests<NUM_POLY_INT_COEFFS>::run ();
10057 4 : }
10058 :
10059 : } // namespace selftest
10060 :
10061 : #endif /* CHECKING_P */
|