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 9061482 : neg_poly_int_rtx (machine_mode mode, const_rtx i)
56 : {
57 9061482 : 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 6235609 : mode_signbit_p (machine_mode mode, const_rtx x)
65 : {
66 6235609 : unsigned HOST_WIDE_INT val;
67 6235609 : unsigned int width;
68 6235609 : scalar_int_mode int_mode;
69 :
70 6235609 : if (!is_int_mode (mode, &int_mode))
71 : return false;
72 :
73 6235601 : width = GET_MODE_PRECISION (int_mode);
74 6235601 : if (width == 0)
75 : return false;
76 :
77 6235601 : if (width <= HOST_BITS_PER_WIDE_INT
78 6234066 : && CONST_INT_P (x))
79 6079801 : val = INTVAL (x);
80 : #if TARGET_SUPPORTS_WIDE_INT
81 155800 : 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 6079801 : if (width < HOST_BITS_PER_WIDE_INT)
109 5507471 : val &= (HOST_WIDE_INT_1U << width) - 1;
110 6080224 : 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 3692628 : val_signbit_p (machine_mode mode, unsigned HOST_WIDE_INT val)
119 : {
120 3692628 : unsigned int width;
121 3692628 : scalar_int_mode int_mode;
122 :
123 3692628 : if (!is_int_mode (mode, &int_mode))
124 : return false;
125 :
126 3692592 : width = GET_MODE_PRECISION (int_mode);
127 3692592 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
128 : return false;
129 :
130 3687770 : val &= GET_MODE_MASK (int_mode);
131 3687770 : 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 2642140 : val_signbit_known_set_p (machine_mode mode, unsigned HOST_WIDE_INT val)
138 : {
139 2642140 : unsigned int width;
140 :
141 2642140 : scalar_int_mode int_mode;
142 2642140 : if (!is_int_mode (mode, &int_mode))
143 : return false;
144 :
145 2600539 : width = GET_MODE_PRECISION (int_mode);
146 2600539 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
147 : return false;
148 :
149 2600539 : val &= HOST_WIDE_INT_1U << (width - 1);
150 2600539 : 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 7673110 : val_signbit_known_clear_p (machine_mode mode, unsigned HOST_WIDE_INT val)
157 : {
158 7673110 : unsigned int width;
159 :
160 7673110 : scalar_int_mode int_mode;
161 7673110 : if (!is_int_mode (mode, &int_mode))
162 : return false;
163 :
164 7311273 : width = GET_MODE_PRECISION (int_mode);
165 7311273 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
166 : return false;
167 :
168 7200525 : val &= HOST_WIDE_INT_1U << (width - 1);
169 7200525 : 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 120478054 : simplify_context::simplify_gen_binary (rtx_code code, machine_mode mode,
177 : rtx op0, rtx op1)
178 : {
179 120478054 : rtx tem;
180 :
181 : /* If this simplifies, do it. */
182 120478054 : tem = simplify_binary_operation (code, mode, op0, op1);
183 120478054 : if (tem)
184 : return tem;
185 :
186 : /* Put complex operands first and constants second if commutative. */
187 76518054 : if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
188 76518054 : && swap_commutative_operands_p (op0, op1))
189 : std::swap (op0, op1);
190 :
191 76518054 : 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 2758812938 : avoid_constant_pool_reference (rtx x)
198 : {
199 2758812938 : rtx c, tmp, addr;
200 2758812938 : machine_mode cmode;
201 2758812938 : poly_int64 offset = 0;
202 :
203 2758812938 : switch (GET_CODE (x))
204 : {
205 264788702 : case MEM:
206 264788702 : break;
207 :
208 909705 : case FLOAT_EXTEND:
209 : /* Handle float extensions of constant pool references. */
210 909705 : tmp = XEXP (x, 0);
211 909705 : c = avoid_constant_pool_reference (tmp);
212 909705 : if (c != tmp && CONST_DOUBLE_AS_FLOAT_P (c))
213 123873 : return const_double_from_real_value (*CONST_DOUBLE_REAL_VALUE (c),
214 123873 : GET_MODE (x));
215 : return x;
216 :
217 : default:
218 : return x;
219 : }
220 :
221 264788702 : if (GET_MODE (x) == BLKmode)
222 : return x;
223 :
224 260705751 : addr = XEXP (x, 0);
225 :
226 : /* Call target hook to avoid the effects of -fpic etc.... */
227 260705751 : addr = targetm.delegitimize_address (addr);
228 :
229 : /* Split the address into a base and integer offset. */
230 260705751 : addr = strip_offset (addr, &offset);
231 :
232 260705751 : 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 260705751 : if (GET_CODE (addr) == SYMBOL_REF
238 260705751 : && CONSTANT_POOL_ADDRESS_P (addr))
239 : {
240 5375853 : c = get_pool_constant (addr);
241 5375853 : 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 5375853 : if (known_eq (offset, 0) && cmode == GET_MODE (x))
247 : return c;
248 29874 : else if (known_in_range_p (offset, 0, GET_MODE_SIZE (cmode)))
249 : {
250 14937 : rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset);
251 14937 : if (tem && CONSTANT_P (tem))
252 : return tem;
253 : }
254 : }
255 :
256 : return x;
257 : }
258 :
259 : /* Simplify a MEM based on its attributes. This is the default
260 : delegitimize_address target hook, and it's recommended that every
261 : overrider call it. */
262 :
263 : rtx
264 3542864350 : 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 3542864350 : if (MEM_P (x)
269 63295971 : && MEM_EXPR (x)
270 3582173620 : && MEM_OFFSET_KNOWN_P (x))
271 : {
272 36331558 : tree decl = MEM_EXPR (x);
273 36331558 : machine_mode mode = GET_MODE (x);
274 36331558 : poly_int64 offset = 0;
275 :
276 36331558 : switch (TREE_CODE (decl))
277 : {
278 : default:
279 : decl = NULL;
280 : break;
281 :
282 : case VAR_DECL:
283 : break;
284 :
285 10400547 : case ARRAY_REF:
286 10400547 : case ARRAY_RANGE_REF:
287 10400547 : case COMPONENT_REF:
288 10400547 : case BIT_FIELD_REF:
289 10400547 : case REALPART_EXPR:
290 10400547 : case IMAGPART_EXPR:
291 10400547 : case VIEW_CONVERT_EXPR:
292 10400547 : {
293 10400547 : poly_int64 bitsize, bitpos, bytepos, toffset_val = 0;
294 10400547 : tree toffset;
295 10400547 : int unsignedp, reversep, volatilep = 0;
296 :
297 10400547 : decl
298 10400547 : = get_inner_reference (decl, &bitsize, &bitpos, &toffset, &mode,
299 : &unsignedp, &reversep, &volatilep);
300 20801094 : if (maybe_ne (bitsize, GET_MODE_BITSIZE (mode))
301 10684743 : || !multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
302 20357144 : || (toffset && !poly_int_tree_p (toffset, &toffset_val)))
303 : decl = NULL;
304 : else
305 9672401 : offset += bytepos + toffset_val;
306 10400547 : break;
307 : }
308 : }
309 :
310 728146 : if (decl
311 21423676 : && mode == GET_MODE (x)
312 21143746 : && VAR_P (decl)
313 13697785 : && (TREE_STATIC (decl)
314 12456014 : || DECL_THREAD_LOCAL_P (decl))
315 1279244 : && DECL_RTL_SET_P (decl)
316 10951178 : && MEM_P (DECL_RTL (decl)))
317 : {
318 1278777 : rtx newx;
319 :
320 1278777 : offset += MEM_OFFSET (x);
321 :
322 1278777 : newx = DECL_RTL (decl);
323 :
324 1278777 : if (MEM_P (newx))
325 : {
326 1278777 : rtx n = XEXP (newx, 0), o = XEXP (x, 0);
327 1278777 : 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 1278777 : n = strip_offset (n, &n_offset);
336 1278777 : o = strip_offset (o, &o_offset);
337 2529507 : if (!(known_eq (o_offset, n_offset + offset)
338 1250730 : && rtx_equal_p (o, n)))
339 214389 : 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 3542864350 : 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 6781348 : simplify_context::simplify_gen_unary (rtx_code code, machine_mode mode, rtx op,
355 : machine_mode op_mode)
356 : {
357 6781348 : rtx tem;
358 :
359 : /* If this simplifies, use it. */
360 6781348 : if ((tem = simplify_unary_operation (code, mode, op, op_mode)) != 0)
361 : return tem;
362 :
363 2428190 : return gen_rtx_fmt_e (code, mode, op);
364 : }
365 :
366 : /* Likewise for ternary operations. */
367 :
368 : rtx
369 2237538 : 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 2237538 : rtx tem;
374 :
375 : /* If this simplifies, use it. */
376 2237538 : if ((tem = simplify_ternary_operation (code, mode, op0_mode,
377 : op0, op1, op2)) != 0)
378 : return tem;
379 :
380 1989255 : 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 21615144 : simplify_context::simplify_gen_relational (rtx_code code, machine_mode mode,
388 : machine_mode cmp_mode,
389 : rtx op0, rtx op1)
390 : {
391 21615144 : rtx tem;
392 :
393 21615144 : if ((tem = simplify_relational_operation (code, mode, cmp_mode,
394 : op0, op1)) != 0)
395 : return tem;
396 :
397 19454822 : 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 496001084 : simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
407 : rtx (*fn) (rtx, const_rtx, void *), void *data)
408 : {
409 496001084 : enum rtx_code code = GET_CODE (x);
410 496001084 : machine_mode mode = GET_MODE (x);
411 496001084 : machine_mode op_mode;
412 496001084 : const char *fmt;
413 496001084 : rtx op0, op1, op2, newx, op;
414 496001084 : rtvec vec, newvec;
415 496001084 : int i, j;
416 :
417 496001084 : if (UNLIKELY (fn != NULL))
418 : {
419 433804157 : newx = fn (x, old_rtx, data);
420 433804157 : if (newx)
421 : return newx;
422 : }
423 62196927 : else if (rtx_equal_p (x, old_rtx))
424 5173720 : return copy_rtx ((rtx) data);
425 :
426 390323463 : switch (GET_RTX_CLASS (code))
427 : {
428 2000314 : case RTX_UNARY:
429 2000314 : op0 = XEXP (x, 0);
430 2000314 : op_mode = GET_MODE (op0);
431 2000314 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
432 2000314 : if (op0 == XEXP (x, 0))
433 : return x;
434 639019 : return simplify_gen_unary (code, mode, op0, op_mode);
435 :
436 75720685 : case RTX_BIN_ARITH:
437 75720685 : case RTX_COMM_ARITH:
438 75720685 : op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
439 75720685 : op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
440 75720685 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
441 : return x;
442 23401284 : return simplify_gen_binary (code, mode, op0, op1);
443 :
444 9697612 : case RTX_COMPARE:
445 9697612 : case RTX_COMM_COMPARE:
446 9697612 : op0 = XEXP (x, 0);
447 9697612 : op1 = XEXP (x, 1);
448 9697612 : op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
449 9697612 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
450 9697612 : op1 = simplify_replace_fn_rtx (op1, old_rtx, fn, data);
451 9697612 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
452 : return x;
453 2320347 : return simplify_gen_relational (code, mode, op_mode, op0, op1);
454 :
455 5821315 : case RTX_TERNARY:
456 5821315 : case RTX_BITFIELD_OPS:
457 5821315 : op0 = XEXP (x, 0);
458 5821315 : op_mode = GET_MODE (op0);
459 5821315 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
460 5821315 : op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
461 5821315 : op2 = simplify_replace_fn_rtx (XEXP (x, 2), old_rtx, fn, data);
462 5821315 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2))
463 : return x;
464 1673433 : if (op_mode == VOIDmode)
465 1651772 : op_mode = GET_MODE (op0);
466 1673433 : return simplify_gen_ternary (code, mode, op_mode, op0, op1, op2);
467 :
468 87998596 : case RTX_EXTRA:
469 87998596 : if (code == SUBREG)
470 : {
471 631322 : op0 = simplify_replace_fn_rtx (SUBREG_REG (x), old_rtx, fn, data);
472 631322 : if (op0 == SUBREG_REG (x))
473 : return x;
474 128426 : op0 = simplify_gen_subreg (GET_MODE (x), op0,
475 64213 : GET_MODE (SUBREG_REG (x)),
476 64213 : SUBREG_BYTE (x));
477 64213 : return op0 ? op0 : x;
478 : }
479 : break;
480 :
481 62520497 : case RTX_OBJ:
482 62520497 : if (code == MEM)
483 : {
484 10801666 : op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
485 10801666 : if (op0 == XEXP (x, 0))
486 : return x;
487 161446 : return replace_equiv_address_nv (x, op0);
488 : }
489 51718831 : 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 285650549 : newx = x;
515 285650549 : fmt = GET_RTX_FORMAT (code);
516 617256015 : for (i = 0; fmt[i]; i++)
517 331605466 : switch (fmt[i])
518 : {
519 3201331 : case 'E':
520 3201331 : vec = XVEC (x, i);
521 3201331 : newvec = XVEC (newx, i);
522 13371971 : for (j = 0; j < GET_NUM_ELEM (vec); j++)
523 : {
524 10170640 : op = simplify_replace_fn_rtx (RTVEC_ELT (vec, j),
525 : old_rtx, fn, data);
526 10170640 : if (op != RTVEC_ELT (vec, j))
527 : {
528 351590 : if (newvec == vec)
529 : {
530 338899 : newvec = shallow_copy_rtvec (vec);
531 338899 : if (x == newx)
532 338899 : newx = shallow_copy_rtx (x);
533 338899 : XVEC (newx, i) = newvec;
534 : }
535 351590 : RTVEC_ELT (newvec, j) = op;
536 : }
537 : }
538 : break;
539 :
540 79496482 : case 'e':
541 79496482 : if (XEXP (x, i))
542 : {
543 79496431 : op = simplify_replace_fn_rtx (XEXP (x, i), old_rtx, fn, data);
544 79496431 : if (op != XEXP (x, i))
545 : {
546 4546895 : if (x == newx)
547 4543702 : newx = shallow_copy_rtx (x);
548 4546895 : 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 12737941 : simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx)
561 : {
562 12737941 : 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 22467727 : simplify_context::simplify_truncation (machine_mode mode, rtx op,
614 : machine_mode op_mode)
615 : {
616 22467727 : unsigned int precision = GET_MODE_UNIT_PRECISION (mode);
617 22467727 : unsigned int op_precision = GET_MODE_UNIT_PRECISION (op_mode);
618 22467727 : scalar_int_mode int_mode, int_op_mode, subreg_mode;
619 :
620 22467727 : gcc_assert (precision <= op_precision);
621 :
622 : /* Optimize truncations of zero and sign extended values. */
623 22467727 : if (GET_CODE (op) == ZERO_EXTEND
624 22467727 : || 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 279114 : machine_mode origmode = GET_MODE (XEXP (op, 0));
633 279114 : if (mode == origmode)
634 : return XEXP (op, 0);
635 25056 : else if (precision <= GET_MODE_UNIT_PRECISION (origmode))
636 9728 : return simplify_gen_unary (TRUNCATE, mode,
637 9728 : XEXP (op, 0), origmode);
638 : else
639 2800 : return simplify_gen_unary (GET_CODE (op), mode,
640 2800 : 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 22188613 : if (1
647 : && (!WORD_REGISTER_OPERATIONS || precision >= BITS_PER_WORD)
648 : && (GET_CODE (op) == PLUS
649 : || GET_CODE (op) == MINUS
650 22188613 : || GET_CODE (op) == MULT))
651 : {
652 1320351 : rtx op0 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0), op_mode);
653 1320351 : if (op0)
654 : {
655 1320351 : rtx op1 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 1), op_mode);
656 1320351 : if (op1)
657 1320351 : 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 20868262 : if ((GET_CODE (op) == LSHIFTRT
665 20868262 : || 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 1922027 : && 2 * precision <= op_precision
671 1922027 : && CONST_INT_P (XEXP (op, 1))
672 1822896 : && 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 20868238 : if ((GET_CODE (op) == LSHIFTRT
682 : || GET_CODE (op) == ASHIFTRT)
683 1922003 : && CONST_INT_P (XEXP (op, 1))
684 1822872 : && GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
685 730 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
686 730 : && UINTVAL (XEXP (op, 1)) < precision)
687 720 : return simplify_gen_binary (LSHIFTRT, mode,
688 720 : 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 20867518 : if (GET_CODE (op) == ASHIFT
694 789501 : && CONST_INT_P (XEXP (op, 1))
695 729283 : && (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
696 729283 : || GET_CODE (XEXP (op, 0)) == SIGN_EXTEND)
697 768 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
698 755 : && UINTVAL (XEXP (op, 1)) < precision)
699 710 : return simplify_gen_binary (ASHIFT, mode,
700 710 : 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 20866808 : if (GET_CODE (op) == AND
706 772074 : && (GET_CODE (XEXP (op, 0)) == LSHIFTRT
707 772074 : || GET_CODE (XEXP (op, 0)) == ASHIFTRT)
708 42071 : && CONST_INT_P (XEXP (XEXP (op, 0), 1))
709 41956 : && CONST_INT_P (XEXP (op, 1)))
710 : {
711 41956 : rtx op0 = (XEXP (XEXP (op, 0), 0));
712 41956 : rtx shift_op = XEXP (XEXP (op, 0), 1);
713 41956 : rtx mask_op = XEXP (op, 1);
714 41956 : unsigned HOST_WIDE_INT shift = UINTVAL (shift_op);
715 41956 : unsigned HOST_WIDE_INT mask = UINTVAL (mask_op);
716 :
717 41956 : if (shift < precision
718 : /* If doing this transform works for an X with all bits set,
719 : it works for any X. */
720 26631 : && ((GET_MODE_MASK (mode) >> shift) & mask)
721 26631 : == ((GET_MODE_MASK (op_mode) >> shift) & mask)
722 3258 : && (op0 = simplify_gen_unary (TRUNCATE, mode, op0, op_mode))
723 45214 : && (op0 = simplify_gen_binary (LSHIFTRT, mode, op0, shift_op)))
724 : {
725 3258 : mask_op = GEN_INT (trunc_int_for_mode (mask, mode));
726 3258 : return simplify_gen_binary (AND, mode, op0, mask_op);
727 : }
728 : }
729 :
730 : /* Turn (truncate:M1 (*_extract:M2 (reg:M2) (len) (pos))) into
731 : (*_extract:M1 (truncate:M1 (reg:M2)) (len) (pos')) if possible without
732 : changing len. */
733 20863550 : if ((GET_CODE (op) == ZERO_EXTRACT || GET_CODE (op) == SIGN_EXTRACT)
734 428246 : && REG_P (XEXP (op, 0))
735 310356 : && GET_MODE (XEXP (op, 0)) == GET_MODE (op)
736 309325 : && CONST_INT_P (XEXP (op, 1))
737 309325 : && CONST_INT_P (XEXP (op, 2)))
738 : {
739 277916 : rtx op0 = XEXP (op, 0);
740 277916 : unsigned HOST_WIDE_INT len = UINTVAL (XEXP (op, 1));
741 277916 : unsigned HOST_WIDE_INT pos = UINTVAL (XEXP (op, 2));
742 277916 : if (BITS_BIG_ENDIAN && pos >= op_precision - precision)
743 : {
744 : op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
745 : if (op0)
746 : {
747 : pos -= op_precision - precision;
748 : return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
749 : XEXP (op, 1), GEN_INT (pos));
750 : }
751 : }
752 277916 : else if (!BITS_BIG_ENDIAN && precision >= len + pos)
753 : {
754 7897 : op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
755 7897 : if (op0)
756 7897 : return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
757 7897 : XEXP (op, 1), XEXP (op, 2));
758 : }
759 : }
760 :
761 : /* Recognize a word extraction from a multi-word subreg. */
762 20855653 : if ((GET_CODE (op) == LSHIFTRT
763 20855653 : || GET_CODE (op) == ASHIFTRT)
764 1921283 : && SCALAR_INT_MODE_P (mode)
765 1918124 : && SCALAR_INT_MODE_P (op_mode)
766 2054461 : && precision >= BITS_PER_WORD
767 60630 : && 2 * precision <= op_precision
768 60630 : && CONST_INT_P (XEXP (op, 1))
769 51729 : && (INTVAL (XEXP (op, 1)) & (precision - 1)) == 0
770 1832 : && UINTVAL (XEXP (op, 1)) < op_precision)
771 : {
772 1832 : poly_int64 byte = subreg_lowpart_offset (mode, op_mode);
773 1832 : int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
774 1832 : return simplify_gen_subreg (mode, XEXP (op, 0), op_mode,
775 : (WORDS_BIG_ENDIAN
776 1832 : ? byte - shifted_bytes
777 1832 : : 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 20853821 : if ((GET_CODE (op) == LSHIFTRT
784 : || GET_CODE (op) == ASHIFTRT)
785 1916292 : && is_a <scalar_int_mode> (mode, &int_mode)
786 22768899 : && is_a <scalar_int_mode> (op_mode, &int_op_mode)
787 1916292 : && MEM_P (XEXP (op, 0))
788 11667 : && CONST_INT_P (XEXP (op, 1))
789 21510 : && INTVAL (XEXP (op, 1)) % GET_MODE_BITSIZE (int_mode) == 0
790 1257 : && INTVAL (XEXP (op, 1)) > 0
791 2514 : && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (int_op_mode)
792 1257 : && ! mode_dependent_address_p (XEXP (XEXP (op, 0), 0),
793 1257 : MEM_ADDR_SPACE (XEXP (op, 0)))
794 1257 : && ! MEM_VOLATILE_P (XEXP (op, 0))
795 20853821 : && (GET_MODE_SIZE (int_mode) >= UNITS_PER_WORD
796 : || WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN))
797 : {
798 1214 : poly_int64 byte = subreg_lowpart_offset (int_mode, int_op_mode);
799 1214 : int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
800 1214 : 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 20852607 : if ((GET_CODE (op) == ABS
809 20852607 : || GET_CODE (op) == NEG)
810 21438 : && (GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
811 21438 : || 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 20852606 : if (GET_CODE (op) == SUBREG
818 20853137 : && is_a <scalar_int_mode> (mode, &int_mode)
819 29105 : && SCALAR_INT_MODE_P (op_mode)
820 29105 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &subreg_mode)
821 20881217 : && subreg_lowpart_p (op))
822 : {
823 : /* (truncate:A (subreg:B (truncate:C X) 0)) is (truncate:A X). */
824 28608 : 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 28608 : if (is_a <scalar_int_mode> (op_mode, &int_op_mode))
841 : {
842 28608 : unsigned int int_op_prec = GET_MODE_PRECISION (int_op_mode);
843 28608 : unsigned int subreg_prec = GET_MODE_PRECISION (subreg_mode);
844 28608 : if (int_op_prec > subreg_prec)
845 : {
846 1497 : if (int_mode == subreg_mode)
847 : return SUBREG_REG (op);
848 61 : if (GET_MODE_PRECISION (int_mode) < subreg_prec)
849 27 : return simplify_gen_unary (TRUNCATE, int_mode,
850 27 : SUBREG_REG (op), subreg_mode);
851 : }
852 : /* Simplification of (truncate:A (subreg:B X:C 0)) where
853 : A is narrower than B and B is narrower than C. */
854 27111 : else if (int_op_prec < subreg_prec
855 27111 : && GET_MODE_PRECISION (int_mode) < int_op_prec)
856 27111 : return simplify_gen_unary (TRUNCATE, int_mode,
857 27111 : SUBREG_REG (op), subreg_mode);
858 : }
859 : }
860 :
861 : /* (truncate:A (truncate:B X)) is (truncate:A X). */
862 20824032 : 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 20824032 : if (GET_CODE (op) == IOR
869 35732 : && SCALAR_INT_MODE_P (mode)
870 35732 : && SCALAR_INT_MODE_P (op_mode)
871 35732 : && CONST_INT_P (XEXP (op, 1))
872 20832887 : && 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 28789330 : simplify_context::simplify_unary_operation (rtx_code code, machine_mode mode,
883 : rtx op, machine_mode op_mode)
884 : {
885 28789330 : rtx trueop, tem;
886 :
887 28789330 : trueop = avoid_constant_pool_reference (op);
888 :
889 28789330 : tem = simplify_const_unary_operation (code, mode, trueop, op_mode);
890 28789330 : if (tem)
891 : return tem;
892 :
893 23433557 : return simplify_unary_operation_1 (code, mode, op);
894 : }
895 :
896 : /* Return true if FLOAT or UNSIGNED_FLOAT operation OP is known
897 : to be exact. */
898 :
899 : static bool
900 2684 : exact_int_to_float_conversion_p (const_rtx op)
901 : {
902 2684 : machine_mode op0_mode = GET_MODE (XEXP (op, 0));
903 : /* Constants can reach here with -frounding-math, if they do then
904 : the conversion isn't exact. */
905 2684 : if (op0_mode == VOIDmode)
906 : return false;
907 5366 : int out_bits = significand_size (GET_MODE_INNER (GET_MODE (op)));
908 2683 : int in_prec = GET_MODE_UNIT_PRECISION (op0_mode);
909 2683 : int in_bits = in_prec;
910 2683 : if (HWI_COMPUTABLE_MODE_P (op0_mode))
911 : {
912 2593 : unsigned HOST_WIDE_INT nonzero = nonzero_bits (XEXP (op, 0), op0_mode);
913 2593 : if (GET_CODE (op) == FLOAT)
914 2472 : 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 2593 : in_bits -= wi::ctz (wi::uhwi (nonzero, in_prec));
920 : }
921 2683 : return in_bits <= out_bits;
922 : }
923 :
924 : /* Perform some simplifications we can do even if the operands
925 : aren't constant. */
926 : rtx
927 23433557 : simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
928 : rtx op)
929 : {
930 23433557 : enum rtx_code reversed;
931 23433557 : rtx temp, elt, base, step;
932 23433557 : scalar_int_mode inner, int_mode, op_mode, op0_mode;
933 :
934 23433557 : switch (code)
935 : {
936 2348507 : case NOT:
937 : /* (not (not X)) == X. */
938 2348507 : if (GET_CODE (op) == NOT)
939 3157 : 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 2345350 : if (COMPARISON_P (op)
944 16941 : && ((SCALAR_INT_MODE_P (mode) && STORE_FLAG_VALUE == -1)
945 : #ifdef VECTOR_STORE_FLAG_VALUE
946 16941 : || (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
947 : && VECTOR_STORE_FLAG_VALUE (mode) == constm1_rtx)
948 : #endif
949 11704 : || mode == BImode)
950 2350587 : && ((reversed = reversed_comparison_code (op, NULL)) != UNKNOWN))
951 5068 : return simplify_gen_relational (reversed, mode, VOIDmode,
952 5068 : 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 2340282 : if (GET_CODE (op) == NEG
957 70199 : && 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 2340288 : && ((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 2340276 : if (GET_CODE (op) == PLUS
975 287988 : && XEXP (op, 1) == constm1_rtx)
976 4573 : 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 2335703 : if (GET_CODE (op) == NEG && CONSTM1_RTX (mode))
982 70190 : return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
983 70190 : CONSTM1_RTX (mode));
984 :
985 : /* (not (xor X C)) for C constant is (xor X D) with D = ~C. */
986 2265513 : if (GET_CODE (op) == XOR
987 18867 : && CONST_INT_P (XEXP (op, 1))
988 2269595 : && (temp = simplify_unary_operation (NOT, mode,
989 : XEXP (op, 1), mode)) != 0)
990 4082 : 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 2261431 : if (GET_CODE (op) == PLUS
994 283415 : && CONST_INT_P (XEXP (op, 1))
995 165766 : && mode_signbit_p (mode, XEXP (op, 1))
996 2265245 : && (temp = simplify_unary_operation (NOT, mode,
997 : XEXP (op, 1), mode)) != 0)
998 3814 : 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 2257617 : if (GET_CODE (op) == ASHIFT
1007 31768 : && XEXP (op, 0) == const1_rtx)
1008 : {
1009 1166 : temp = simplify_gen_unary (NOT, mode, const1_rtx, mode);
1010 1166 : 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 2256451 : 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 2256451 : if (partial_subreg_p (op)
1026 596823 : && subreg_lowpart_p (op)
1027 596515 : && GET_CODE (SUBREG_REG (op)) == ASHIFT
1028 613681 : && XEXP (SUBREG_REG (op), 0) == const1_rtx)
1029 : {
1030 163 : machine_mode inner_mode = GET_MODE (SUBREG_REG (op));
1031 163 : rtx x;
1032 :
1033 163 : x = gen_rtx_ROTATE (inner_mode,
1034 : simplify_gen_unary (NOT, inner_mode, const1_rtx,
1035 : inner_mode),
1036 : XEXP (SUBREG_REG (op), 1));
1037 163 : temp = rtl_hooks.gen_lowpart_no_emit (mode, x);
1038 163 : if (temp)
1039 : return temp;
1040 : }
1041 :
1042 : /* Apply De Morgan's laws to reduce number of patterns for machines
1043 : with negating logical insns (and-not, nand, etc.). If result has
1044 : only one NOT, put it first, since that is how the patterns are
1045 : coded. */
1046 2256288 : if (GET_CODE (op) == IOR || GET_CODE (op) == AND)
1047 : {
1048 13776 : rtx in1 = XEXP (op, 0), in2 = XEXP (op, 1);
1049 13776 : machine_mode op_mode;
1050 :
1051 13776 : op_mode = GET_MODE (in1);
1052 13776 : in1 = simplify_gen_unary (NOT, op_mode, in1, op_mode);
1053 :
1054 13776 : op_mode = GET_MODE (in2);
1055 13776 : if (op_mode == VOIDmode)
1056 5200 : op_mode = mode;
1057 13776 : in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode);
1058 :
1059 13776 : if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT)
1060 : std::swap (in1, in2);
1061 :
1062 27552 : 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 2242512 : 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 1802445 : case NEG:
1075 : /* (neg (neg X)) == X. */
1076 1802445 : if (GET_CODE (op) == NEG)
1077 6424 : 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 1796021 : if (GET_CODE (op) == IF_THEN_ELSE)
1083 : {
1084 3092 : rtx cond = XEXP (op, 0);
1085 3092 : rtx true_rtx = XEXP (op, 1);
1086 3092 : rtx false_rtx = XEXP (op, 2);
1087 :
1088 3092 : if ((GET_CODE (true_rtx) == NEG
1089 0 : && rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
1090 3092 : || (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 1796021 : if (GET_CODE (op) == PLUS
1107 138811 : && XEXP (op, 1) == const1_rtx)
1108 53464 : return simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1109 :
1110 : /* Similarly, (neg (not X)) is (plus X 1). */
1111 1742557 : if (GET_CODE (op) == NOT)
1112 372 : return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
1113 372 : 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 1742185 : if (GET_CODE (op) == MINUS
1121 24841 : && !HONOR_SIGNED_ZEROS (mode)
1122 1765614 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1123 23429 : return simplify_gen_binary (MINUS, mode, XEXP (op, 1), XEXP (op, 0));
1124 :
1125 1718756 : if (GET_CODE (op) == PLUS
1126 85347 : && !HONOR_SIGNED_ZEROS (mode)
1127 1803679 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1128 : {
1129 : /* (neg (plus A C)) is simplified to (minus -C A). */
1130 84923 : if (CONST_SCALAR_INT_P (XEXP (op, 1))
1131 5547 : || CONST_DOUBLE_AS_FLOAT_P (XEXP (op, 1)))
1132 : {
1133 79376 : temp = simplify_unary_operation (NEG, mode, XEXP (op, 1), mode);
1134 79376 : if (temp)
1135 79376 : 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 5547 : temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
1140 5547 : 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 1633833 : if (GET_CODE (op) == MULT
1146 1633833 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1147 : {
1148 26997 : temp = simplify_gen_unary (NEG, mode, XEXP (op, 1), mode);
1149 26997 : 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 1606836 : if (GET_CODE (op) == ASHIFT)
1156 : {
1157 53710 : temp = simplify_unary_operation (NEG, mode, XEXP (op, 0), mode);
1158 53710 : if (temp)
1159 12329 : 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 1594507 : if (GET_CODE (op) == ASHIFTRT
1165 28133 : && CONST_INT_P (XEXP (op, 1))
1166 1650677 : && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1167 691 : return simplify_gen_binary (LSHIFTRT, mode,
1168 691 : 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 1593816 : if (GET_CODE (op) == LSHIFTRT
1173 8920 : && CONST_INT_P (XEXP (op, 1))
1174 1611488 : && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1175 3438 : return simplify_gen_binary (ASHIFTRT, mode,
1176 3438 : 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 1590378 : if (GET_CODE (op) == XOR
1180 11437 : && XEXP (op, 1) == const1_rtx
1181 1590489 : && nonzero_bits (XEXP (op, 0), mode) == 1)
1182 32 : return plus_constant (mode, XEXP (op, 0), -1);
1183 :
1184 : /* (neg (lt x 0)) is (ashiftrt X C) if STORE_FLAG_VALUE is 1. */
1185 : /* (neg (lt x 0)) is (lshiftrt X C) if STORE_FLAG_VALUE is -1. */
1186 1590346 : if (GET_CODE (op) == LT
1187 3107 : && XEXP (op, 1) == const0_rtx
1188 1592623 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op, 0)), &inner))
1189 : {
1190 439 : int_mode = as_a <scalar_int_mode> (mode);
1191 439 : int isize = GET_MODE_PRECISION (inner);
1192 439 : if (STORE_FLAG_VALUE == 1)
1193 : {
1194 439 : temp = simplify_gen_binary (ASHIFTRT, inner, XEXP (op, 0),
1195 : gen_int_shift_amount (inner,
1196 439 : isize - 1));
1197 439 : if (int_mode == inner)
1198 : return temp;
1199 202 : if (GET_MODE_PRECISION (int_mode) > isize)
1200 129 : return simplify_gen_unary (SIGN_EXTEND, int_mode, temp, inner);
1201 73 : return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1202 : }
1203 : else if (STORE_FLAG_VALUE == -1)
1204 : {
1205 : temp = simplify_gen_binary (LSHIFTRT, inner, XEXP (op, 0),
1206 : gen_int_shift_amount (inner,
1207 : isize - 1));
1208 : if (int_mode == inner)
1209 : return temp;
1210 : if (GET_MODE_PRECISION (int_mode) > isize)
1211 : return simplify_gen_unary (ZERO_EXTEND, int_mode, temp, inner);
1212 : return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1213 : }
1214 : }
1215 :
1216 1589907 : 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 1952457 : case TRUNCATE:
1234 : /* Don't optimize (lshiftrt (mult ...)) as it would interfere
1235 : with the umulXi3_highpart patterns. */
1236 1952457 : if (GET_CODE (op) == LSHIFTRT
1237 19680 : && GET_CODE (XEXP (op, 0)) == MULT)
1238 : break;
1239 :
1240 1945095 : 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 1945083 : if (GET_MODE (op) != VOIDmode)
1255 : {
1256 1945083 : temp = simplify_truncation (mode, op, GET_MODE (op));
1257 1945083 : 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 1824441 : if (known_eq (GET_MODE_NUNITS (mode), 1)
1264 1824441 : && (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op))
1265 0 : || truncated_to_mode (mode, op)))
1266 : {
1267 1811707 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1268 1811707 : 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 12930 : if (HWI_COMPUTABLE_MODE_P (mode)
1277 196 : && COMPARISON_P (op)
1278 0 : && (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0
1279 12930 : && 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 12930 : if (GET_CODE (op) == MEM
1289 319 : && !VECTOR_MODE_P (mode)
1290 194 : && !MEM_VOLATILE_P (op)
1291 13118 : && !mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op)))
1292 : {
1293 188 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1294 188 : if (temp)
1295 : return temp;
1296 : }
1297 :
1298 : /* Check for useless truncation. */
1299 12930 : if (GET_MODE (op) == mode)
1300 : return op;
1301 : break;
1302 :
1303 172390 : case FLOAT_TRUNCATE:
1304 : /* Check for useless truncation. */
1305 172390 : if (GET_MODE (op) == mode)
1306 : return op;
1307 :
1308 172390 : if (DECIMAL_FLOAT_MODE_P (mode))
1309 : break;
1310 :
1311 : /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF. */
1312 172236 : 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 172234 : if ((GET_CODE (op) == FLOAT_TRUNCATE
1326 145 : && flag_unsafe_math_optimizations)
1327 172230 : || 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 172227 : if ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1336 172227 : && (flag_unsafe_math_optimizations
1337 1410 : || exact_int_to_float_conversion_p (op)))
1338 1409 : return simplify_gen_unary (GET_CODE (op), mode,
1339 : XEXP (op, 0),
1340 1409 : GET_MODE (XEXP (op, 0)));
1341 :
1342 : /* (float_truncate:SF (OP:DF (float_extend:DF foo:sf))) is
1343 : (OP:SF foo:SF) if OP is NEG or ABS. */
1344 170818 : if ((GET_CODE (op) == ABS
1345 170818 : || GET_CODE (op) == NEG)
1346 209 : && 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 170790 : if (GET_CODE (op) == SUBREG
1354 307 : && subreg_lowpart_p (op)
1355 171094 : && GET_CODE (SUBREG_REG (op)) == FLOAT_TRUNCATE)
1356 : return SUBREG_REG (op);
1357 : break;
1358 :
1359 590968 : case FLOAT_EXTEND:
1360 : /* Check for useless extension. */
1361 590968 : if (GET_MODE (op) == mode)
1362 : return op;
1363 :
1364 590968 : 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 590865 : if (GET_CODE (op) == FLOAT_EXTEND
1373 590865 : || ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1374 1274 : && exact_int_to_float_conversion_p (op)))
1375 563 : return simplify_gen_unary (GET_CODE (op), mode,
1376 : XEXP (op, 0),
1377 563 : GET_MODE (XEXP (op, 0)));
1378 :
1379 : break;
1380 :
1381 334879 : case ABS:
1382 : /* (abs (neg <foo>)) -> (abs <foo>) */
1383 334879 : if (GET_CODE (op) == NEG)
1384 31 : return simplify_gen_unary (ABS, mode, XEXP (op, 0),
1385 31 : 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 334848 : if (GET_MODE (op) == VOIDmode)
1390 : break;
1391 :
1392 : /* If operand is something known to be positive, ignore the ABS. */
1393 334848 : 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 334630 : 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 334630 : && 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 334630 : if (is_a <scalar_int_mode> (mode, &int_mode)
1424 56405 : && (num_sign_bit_copies (op, int_mode)
1425 56405 : == GET_MODE_PRECISION (int_mode)))
1426 74 : return gen_rtx_NEG (int_mode, op);
1427 :
1428 : break;
1429 :
1430 0 : case FFS:
1431 : /* (ffs (*_extend <X>)) = (*_extend (ffs <X>)). */
1432 0 : if (GET_CODE (op) == SIGN_EXTEND
1433 0 : || GET_CODE (op) == ZERO_EXTEND)
1434 : {
1435 0 : temp = simplify_gen_unary (FFS, GET_MODE (XEXP (op, 0)),
1436 0 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1437 0 : return simplify_gen_unary (GET_CODE (op), mode, temp,
1438 0 : GET_MODE (temp));
1439 : }
1440 : break;
1441 :
1442 3441 : case POPCOUNT:
1443 3441 : switch (GET_CODE (op))
1444 : {
1445 0 : case BSWAP:
1446 0 : case BITREVERSE:
1447 : /* (popcount (bswap <X>)) = (popcount <X>). */
1448 0 : return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1449 0 : GET_MODE (XEXP (op, 0)));
1450 :
1451 44 : case ZERO_EXTEND:
1452 : /* (popcount (zero_extend <X>)) = (zero_extend (popcount <X>)). */
1453 88 : temp = simplify_gen_unary (POPCOUNT, GET_MODE (XEXP (op, 0)),
1454 44 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1455 44 : return simplify_gen_unary (ZERO_EXTEND, mode, temp,
1456 44 : GET_MODE (temp));
1457 :
1458 0 : case ROTATE:
1459 0 : case ROTATERT:
1460 : /* Rotations don't affect popcount. */
1461 0 : if (!side_effects_p (XEXP (op, 1)))
1462 0 : return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1463 0 : GET_MODE (XEXP (op, 0)));
1464 : break;
1465 :
1466 : default:
1467 : break;
1468 : }
1469 : break;
1470 :
1471 0 : case PARITY:
1472 0 : switch (GET_CODE (op))
1473 : {
1474 0 : case NOT:
1475 0 : case BSWAP:
1476 0 : case BITREVERSE:
1477 0 : return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1478 0 : GET_MODE (XEXP (op, 0)));
1479 :
1480 0 : case ZERO_EXTEND:
1481 0 : case SIGN_EXTEND:
1482 0 : temp = simplify_gen_unary (PARITY, GET_MODE (XEXP (op, 0)),
1483 0 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1484 0 : return simplify_gen_unary (GET_CODE (op), mode, temp,
1485 0 : GET_MODE (temp));
1486 :
1487 0 : case ROTATE:
1488 0 : case ROTATERT:
1489 : /* Rotations don't affect parity. */
1490 0 : if (!side_effects_p (XEXP (op, 1)))
1491 0 : return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1492 0 : GET_MODE (XEXP (op, 0)));
1493 : break;
1494 :
1495 : case PARITY:
1496 : /* (parity (parity x)) -> parity (x). */
1497 : return op;
1498 :
1499 : default:
1500 : break;
1501 : }
1502 : break;
1503 :
1504 31749 : case BSWAP:
1505 : /* (bswap (bswap x)) -> x. */
1506 31749 : if (GET_CODE (op) == BSWAP)
1507 184 : return XEXP (op, 0);
1508 : break;
1509 :
1510 0 : case BITREVERSE:
1511 : /* (bitreverse (bitreverse x)) -> x. */
1512 0 : if (GET_CODE (op) == BITREVERSE)
1513 0 : return XEXP (op, 0);
1514 : break;
1515 :
1516 906817 : case FLOAT:
1517 : /* (float (sign_extend <X>)) = (float <X>). */
1518 906817 : if (GET_CODE (op) == SIGN_EXTEND)
1519 9576 : return simplify_gen_unary (FLOAT, mode, XEXP (op, 0),
1520 9576 : GET_MODE (XEXP (op, 0)));
1521 : break;
1522 :
1523 3064257 : case SIGN_EXTEND:
1524 : /* Check for useless extension. */
1525 3064257 : if (GET_MODE (op) == mode)
1526 : return op;
1527 :
1528 : /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
1529 : becomes just the MINUS if its mode is MODE. This allows
1530 : folding switch statements on machines using casesi (such as
1531 : the VAX). */
1532 3064217 : if (GET_CODE (op) == TRUNCATE
1533 62 : && GET_MODE (XEXP (op, 0)) == mode
1534 62 : && GET_CODE (XEXP (op, 0)) == MINUS
1535 0 : && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
1536 0 : && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
1537 : return XEXP (op, 0);
1538 :
1539 : /* Extending a widening multiplication should be canonicalized to
1540 : a wider widening multiplication. */
1541 3064217 : if (GET_CODE (op) == MULT)
1542 : {
1543 68173 : rtx lhs = XEXP (op, 0);
1544 68173 : rtx rhs = XEXP (op, 1);
1545 68173 : enum rtx_code lcode = GET_CODE (lhs);
1546 68173 : enum rtx_code rcode = GET_CODE (rhs);
1547 :
1548 : /* Widening multiplies usually extend both operands, but sometimes
1549 : they use a shift to extract a portion of a register. */
1550 68173 : if ((lcode == SIGN_EXTEND
1551 68023 : || (lcode == ASHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1552 969 : && (rcode == SIGN_EXTEND
1553 925 : || (rcode == ASHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1554 : {
1555 165 : machine_mode lmode = GET_MODE (lhs);
1556 165 : machine_mode rmode = GET_MODE (rhs);
1557 165 : int bits;
1558 :
1559 165 : if (lcode == ASHIFTRT)
1560 : /* Number of bits not shifted off the end. */
1561 125 : bits = (GET_MODE_UNIT_PRECISION (lmode)
1562 125 : - INTVAL (XEXP (lhs, 1)));
1563 : else /* lcode == SIGN_EXTEND */
1564 : /* Size of inner mode. */
1565 80 : bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1566 :
1567 165 : if (rcode == ASHIFTRT)
1568 121 : bits += (GET_MODE_UNIT_PRECISION (rmode)
1569 121 : - INTVAL (XEXP (rhs, 1)));
1570 : else /* rcode == SIGN_EXTEND */
1571 88 : bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1572 :
1573 : /* We can only widen multiplies if the result is mathematiclly
1574 : equivalent. I.e. if overflow was impossible. */
1575 330 : if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1576 108 : return simplify_gen_binary
1577 108 : (MULT, mode,
1578 : simplify_gen_unary (SIGN_EXTEND, mode, lhs, lmode),
1579 108 : simplify_gen_unary (SIGN_EXTEND, mode, rhs, rmode));
1580 : }
1581 : }
1582 :
1583 : /* Check for a sign extension of a subreg of a promoted
1584 : variable, where the promotion is sign-extended, and the
1585 : target mode is the same as the variable's promotion. */
1586 3064109 : if (GET_CODE (op) == SUBREG
1587 215829 : && SUBREG_PROMOTED_VAR_P (op)
1588 3070185 : && SUBREG_PROMOTED_SIGNED_P (op))
1589 : {
1590 0 : rtx subreg = SUBREG_REG (op);
1591 0 : machine_mode subreg_mode = GET_MODE (subreg);
1592 0 : if (!paradoxical_subreg_p (mode, subreg_mode))
1593 : {
1594 0 : temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
1595 0 : if (temp)
1596 : {
1597 : /* Preserve SUBREG_PROMOTED_VAR_P. */
1598 0 : if (partial_subreg_p (temp))
1599 : {
1600 0 : SUBREG_PROMOTED_VAR_P (temp) = 1;
1601 0 : SUBREG_PROMOTED_SET (temp, SRP_SIGNED);
1602 : }
1603 0 : return temp;
1604 : }
1605 : }
1606 : else
1607 : /* Sign-extending a sign-extended subreg. */
1608 0 : return simplify_gen_unary (SIGN_EXTEND, mode,
1609 0 : subreg, subreg_mode);
1610 : }
1611 :
1612 : /* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
1613 : (sign_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1614 3064109 : if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND)
1615 : {
1616 20118 : gcc_assert (GET_MODE_UNIT_PRECISION (mode)
1617 : > GET_MODE_UNIT_PRECISION (GET_MODE (op)));
1618 6706 : return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0),
1619 6706 : GET_MODE (XEXP (op, 0)));
1620 : }
1621 :
1622 : /* (sign_extend:M (ashiftrt:N (ashift <X> (const_int I)) (const_int I)))
1623 : is (sign_extend:M (subreg:O <X>)) if there is mode with
1624 : GET_MODE_BITSIZE (N) - I bits.
1625 : (sign_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1626 : is similarly (zero_extend:M (subreg:O <X>)). */
1627 3057403 : if ((GET_CODE (op) == ASHIFTRT || GET_CODE (op) == LSHIFTRT)
1628 89217 : && GET_CODE (XEXP (op, 0)) == ASHIFT
1629 3059924 : && is_a <scalar_int_mode> (mode, &int_mode)
1630 5174 : && CONST_INT_P (XEXP (op, 1))
1631 5174 : && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1632 3062453 : && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1633 5050 : GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1634 : {
1635 5050 : scalar_int_mode tmode;
1636 5050 : gcc_assert (GET_MODE_PRECISION (int_mode)
1637 : > GET_MODE_PRECISION (op_mode));
1638 5050 : if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1639 7447 : - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1640 : {
1641 2653 : rtx inner =
1642 2653 : rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1643 2653 : if (inner)
1644 2653 : return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
1645 : ? SIGN_EXTEND : ZERO_EXTEND,
1646 2653 : int_mode, inner, tmode);
1647 : }
1648 : }
1649 :
1650 : /* (sign_extend:M (lshiftrt:N <X> (const_int I))) is better as
1651 : (zero_extend:M (lshiftrt:N <X> (const_int I))) if I is not 0. */
1652 3054750 : if (GET_CODE (op) == LSHIFTRT
1653 183 : && CONST_INT_P (XEXP (op, 1))
1654 183 : && XEXP (op, 1) != const0_rtx)
1655 183 : return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1656 :
1657 : /* (sign_extend:M (truncate:N (lshiftrt:O <X> (const_int I)))) where
1658 : I is GET_MODE_PRECISION(O) - GET_MODE_PRECISION(N), simplifies to
1659 : (ashiftrt:M <X> (const_int I)) if modes M and O are the same, and
1660 : (truncate:M (ashiftrt:O <X> (const_int I))) if M is narrower than
1661 : O, and (sign_extend:M (ashiftrt:O <X> (const_int I))) if M is
1662 : wider than O. */
1663 3054567 : if (GET_CODE (op) == TRUNCATE
1664 62 : && GET_CODE (XEXP (op, 0)) == LSHIFTRT
1665 0 : && CONST_INT_P (XEXP (XEXP (op, 0), 1)))
1666 : {
1667 0 : scalar_int_mode m_mode, n_mode, o_mode;
1668 0 : rtx old_shift = XEXP (op, 0);
1669 0 : if (is_a <scalar_int_mode> (mode, &m_mode)
1670 0 : && is_a <scalar_int_mode> (GET_MODE (op), &n_mode)
1671 0 : && is_a <scalar_int_mode> (GET_MODE (old_shift), &o_mode)
1672 0 : && GET_MODE_PRECISION (o_mode) - GET_MODE_PRECISION (n_mode)
1673 0 : == INTVAL (XEXP (old_shift, 1)))
1674 : {
1675 0 : rtx new_shift = simplify_gen_binary (ASHIFTRT,
1676 : GET_MODE (old_shift),
1677 : XEXP (old_shift, 0),
1678 : XEXP (old_shift, 1));
1679 0 : if (GET_MODE_PRECISION (m_mode) > GET_MODE_PRECISION (o_mode))
1680 0 : return simplify_gen_unary (SIGN_EXTEND, mode, new_shift,
1681 0 : GET_MODE (new_shift));
1682 0 : if (mode != GET_MODE (new_shift))
1683 0 : return simplify_gen_unary (TRUNCATE, mode, new_shift,
1684 0 : GET_MODE (new_shift));
1685 : return new_shift;
1686 : }
1687 : }
1688 :
1689 : /* We can canonicalize SIGN_EXTEND (op) as ZERO_EXTEND (op) when
1690 : we know the sign bit of OP must be clear. */
1691 3054567 : if (val_signbit_known_clear_p (GET_MODE (op),
1692 3054567 : nonzero_bits (op, GET_MODE (op))))
1693 39689 : return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1694 :
1695 : /* (sign_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1696 3014878 : if (GET_CODE (op) == SUBREG
1697 215555 : && subreg_lowpart_p (op)
1698 215443 : && GET_MODE (SUBREG_REG (op)) == mode
1699 3199075 : && is_a <scalar_int_mode> (mode, &int_mode)
1700 190975 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1701 190975 : && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
1702 189170 : && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
1703 3204048 : && (nonzero_bits (SUBREG_REG (op), mode)
1704 189170 : & ~(GET_MODE_MASK (op_mode) >> 1)) == 0)
1705 6778 : return SUBREG_REG (op);
1706 :
1707 : #if defined(POINTERS_EXTEND_UNSIGNED)
1708 : /* As we do not know which address space the pointer is referring to,
1709 : we can do this only if the target does not support different pointer
1710 : or address modes depending on the address space. */
1711 3008100 : if (target_default_pointer_address_modes_p ()
1712 : && ! POINTERS_EXTEND_UNSIGNED
1713 : && mode == Pmode && GET_MODE (op) == ptr_mode
1714 : && (CONSTANT_P (op)
1715 : || (GET_CODE (op) == SUBREG
1716 : && REG_P (SUBREG_REG (op))
1717 : && REG_POINTER (SUBREG_REG (op))
1718 : && GET_MODE (SUBREG_REG (op)) == Pmode))
1719 : && !targetm.have_ptr_extend ())
1720 : {
1721 : temp
1722 : = convert_memory_address_addr_space_1 (Pmode, op,
1723 : ADDR_SPACE_GENERIC, false,
1724 : true);
1725 : if (temp)
1726 : return temp;
1727 : }
1728 : #endif
1729 : break;
1730 :
1731 11321862 : case ZERO_EXTEND:
1732 : /* Check for useless extension. */
1733 11321862 : if (GET_MODE (op) == mode)
1734 : return op;
1735 :
1736 : /* (zero_extend:SI (and:QI X (const))) -> (and:SI (lowpart:SI X) const)
1737 : where const does not sign bit set. */
1738 11321820 : if (GET_CODE (op) == AND
1739 116680 : && CONST_INT_P (XEXP (op, 1))
1740 90133 : && INTVAL (XEXP (op, 1)) > 0)
1741 : {
1742 83109 : rtx tem = rtl_hooks.gen_lowpart_no_emit (mode, XEXP (op, 0));
1743 83109 : if (tem)
1744 66914 : return simplify_gen_binary (AND, mode, tem, XEXP (op, 1));
1745 : }
1746 :
1747 : /* Check for a zero extension of a subreg of a promoted
1748 : variable, where the promotion is zero-extended, and the
1749 : target mode is the same as the variable's promotion. */
1750 11254906 : if (GET_CODE (op) == SUBREG
1751 1542682 : && SUBREG_PROMOTED_VAR_P (op)
1752 11255383 : && SUBREG_PROMOTED_UNSIGNED_P (op))
1753 : {
1754 477 : rtx subreg = SUBREG_REG (op);
1755 477 : machine_mode subreg_mode = GET_MODE (subreg);
1756 477 : if (!paradoxical_subreg_p (mode, subreg_mode))
1757 : {
1758 291 : temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
1759 291 : if (temp)
1760 : {
1761 : /* Preserve SUBREG_PROMOTED_VAR_P. */
1762 291 : if (partial_subreg_p (temp))
1763 : {
1764 129 : SUBREG_PROMOTED_VAR_P (temp) = 1;
1765 129 : SUBREG_PROMOTED_SET (temp, SRP_UNSIGNED);
1766 : }
1767 291 : return temp;
1768 : }
1769 : }
1770 : else
1771 : /* Zero-extending a zero-extended subreg. */
1772 186 : return simplify_gen_unary (ZERO_EXTEND, mode,
1773 186 : subreg, subreg_mode);
1774 : }
1775 :
1776 : /* Extending a widening multiplication should be canonicalized to
1777 : a wider widening multiplication. */
1778 11254429 : if (GET_CODE (op) == MULT)
1779 : {
1780 175348 : rtx lhs = XEXP (op, 0);
1781 175348 : rtx rhs = XEXP (op, 1);
1782 175348 : enum rtx_code lcode = GET_CODE (lhs);
1783 175348 : enum rtx_code rcode = GET_CODE (rhs);
1784 :
1785 : /* Widening multiplies usually extend both operands, but sometimes
1786 : they use a shift to extract a portion of a register. */
1787 175348 : if ((lcode == ZERO_EXTEND
1788 174576 : || (lcode == LSHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1789 1078 : && (rcode == ZERO_EXTEND
1790 966 : || (rcode == LSHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1791 : {
1792 124 : machine_mode lmode = GET_MODE (lhs);
1793 124 : machine_mode rmode = GET_MODE (rhs);
1794 124 : int bits;
1795 :
1796 124 : if (lcode == LSHIFTRT)
1797 : /* Number of bits not shifted off the end. */
1798 12 : bits = (GET_MODE_UNIT_PRECISION (lmode)
1799 12 : - INTVAL (XEXP (lhs, 1)));
1800 : else /* lcode == ZERO_EXTEND */
1801 : /* Size of inner mode. */
1802 224 : bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1803 :
1804 124 : if (rcode == LSHIFTRT)
1805 12 : bits += (GET_MODE_UNIT_PRECISION (rmode)
1806 12 : - INTVAL (XEXP (rhs, 1)));
1807 : else /* rcode == ZERO_EXTEND */
1808 224 : bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1809 :
1810 : /* We can only widen multiplies if the result is mathematiclly
1811 : equivalent. I.e. if overflow was impossible. */
1812 248 : if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1813 112 : return simplify_gen_binary
1814 112 : (MULT, mode,
1815 : simplify_gen_unary (ZERO_EXTEND, mode, lhs, lmode),
1816 112 : simplify_gen_unary (ZERO_EXTEND, mode, rhs, rmode));
1817 : }
1818 : }
1819 :
1820 : /* (zero_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1821 11254317 : if (GET_CODE (op) == ZERO_EXTEND)
1822 21653 : return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0),
1823 21653 : GET_MODE (XEXP (op, 0)));
1824 :
1825 : /* (zero_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1826 : is (zero_extend:M (subreg:O <X>)) if there is mode with
1827 : GET_MODE_PRECISION (N) - I bits. */
1828 11232664 : if (GET_CODE (op) == LSHIFTRT
1829 71023 : && GET_CODE (XEXP (op, 0)) == ASHIFT
1830 11232687 : && is_a <scalar_int_mode> (mode, &int_mode)
1831 23 : && CONST_INT_P (XEXP (op, 1))
1832 18 : && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1833 11232664 : && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1834 0 : GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1835 : {
1836 0 : scalar_int_mode tmode;
1837 0 : if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1838 0 : - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1839 : {
1840 0 : rtx inner =
1841 0 : rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1842 0 : if (inner)
1843 0 : return simplify_gen_unary (ZERO_EXTEND, int_mode,
1844 0 : inner, tmode);
1845 : }
1846 : }
1847 :
1848 : /* (zero_extend:M (subreg:N <X:O>)) is <X:O> (for M == O) or
1849 : (zero_extend:M <X:O>), if X doesn't have any non-zero bits outside
1850 : of mode N. E.g.
1851 : (zero_extend:SI (subreg:QI (and:SI (reg:SI) (const_int 63)) 0)) is
1852 : (and:SI (reg:SI) (const_int 63)). */
1853 11232664 : if (partial_subreg_p (op)
1854 12700651 : && is_a <scalar_int_mode> (mode, &int_mode)
1855 1490032 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &op0_mode)
1856 1489519 : && GET_MODE_PRECISION (op0_mode) <= HOST_BITS_PER_WIDE_INT
1857 1170359 : && GET_MODE_PRECISION (int_mode) >= GET_MODE_PRECISION (op0_mode)
1858 1147838 : && subreg_lowpart_p (op)
1859 2357648 : && (nonzero_bits (SUBREG_REG (op), op0_mode)
1860 815443 : & ~GET_MODE_MASK (GET_MODE (op))) == 0)
1861 : {
1862 22045 : if (GET_MODE_PRECISION (int_mode) == GET_MODE_PRECISION (op0_mode))
1863 14736 : return SUBREG_REG (op);
1864 7309 : return simplify_gen_unary (ZERO_EXTEND, int_mode, SUBREG_REG (op),
1865 7309 : op0_mode);
1866 : }
1867 :
1868 : /* (zero_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1869 11210619 : if (GET_CODE (op) == SUBREG
1870 1520160 : && subreg_lowpart_p (op)
1871 931269 : && GET_MODE (SUBREG_REG (op)) == mode
1872 12006693 : && is_a <scalar_int_mode> (mode, &int_mode)
1873 796074 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1874 796074 : && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
1875 734198 : && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
1876 11944817 : && (nonzero_bits (SUBREG_REG (op), mode)
1877 734198 : & ~GET_MODE_MASK (op_mode)) == 0)
1878 0 : return SUBREG_REG (op);
1879 :
1880 : /* Trying to optimize:
1881 : (zero_extend:M (subreg:N (not:M (X:M)))) ->
1882 : (xor:M (zero_extend:M (subreg:N (X:M)), mask))
1883 : where the mask is GET_MODE_MASK (N).
1884 : For the cases when X:M doesn't have any non-zero bits
1885 : outside of mode N, (zero_extend:M (subreg:N (X:M))
1886 : will be simplified to just (X:M)
1887 : and whole optimization will be -> (xor:M (X:M, mask)). */
1888 11210619 : if (partial_subreg_p (op)
1889 1467987 : && GET_CODE (XEXP (op, 0)) == NOT
1890 1484 : && GET_MODE (XEXP (op, 0)) == mode
1891 1466 : && subreg_lowpart_p (op)
1892 11211033 : && HWI_COMPUTABLE_MODE_P (mode)
1893 418 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1894 1520578 : && (nonzero_bits (XEXP (XEXP (op, 0), 0), mode)
1895 418 : & ~GET_MODE_MASK (op_mode)) == 0)
1896 : {
1897 4 : unsigned HOST_WIDE_INT mask = GET_MODE_MASK (op_mode);
1898 8 : return simplify_gen_binary (XOR, mode,
1899 4 : XEXP (XEXP (op, 0), 0),
1900 4 : gen_int_mode (mask, mode));
1901 : }
1902 :
1903 : #if defined(POINTERS_EXTEND_UNSIGNED)
1904 : /* As we do not know which address space the pointer is referring to,
1905 : we can do this only if the target does not support different pointer
1906 : or address modes depending on the address space. */
1907 11210615 : if (target_default_pointer_address_modes_p ()
1908 : && POINTERS_EXTEND_UNSIGNED > 0
1909 12611952 : && mode == Pmode && GET_MODE (op) == ptr_mode
1910 673 : && (CONSTANT_P (op)
1911 652 : || (GET_CODE (op) == SUBREG
1912 0 : && REG_P (SUBREG_REG (op))
1913 0 : && REG_POINTER (SUBREG_REG (op))
1914 0 : && GET_MODE (SUBREG_REG (op)) == Pmode))
1915 11210636 : && !targetm.have_ptr_extend ())
1916 : {
1917 21 : temp
1918 21 : = convert_memory_address_addr_space_1 (Pmode, op,
1919 : ADDR_SPACE_GENERIC, false,
1920 : true);
1921 21 : if (temp)
1922 : return temp;
1923 : }
1924 : #endif
1925 : break;
1926 :
1927 529057 : case VEC_DUPLICATE:
1928 529057 : if (GET_CODE (op) == VEC_DUPLICATE)
1929 2 : return simplify_gen_unary (VEC_DUPLICATE, mode, XEXP (op, 0),
1930 2 : GET_MODE (XEXP (op, 0)));
1931 : break;
1932 :
1933 : default:
1934 : break;
1935 : }
1936 :
1937 19435597 : if (VECTOR_MODE_P (mode)
1938 1567423 : && vec_duplicate_p (op, &elt)
1939 21008908 : && code != VEC_DUPLICATE)
1940 : {
1941 5888 : if (code == SIGN_EXTEND || code == ZERO_EXTEND)
1942 : /* Enforce a canonical order of VEC_DUPLICATE wrt other unary
1943 : operations by promoting VEC_DUPLICATE to the root of the expression
1944 : (as far as possible). */
1945 4832 : temp = simplify_gen_unary (code, GET_MODE_INNER (mode),
1946 9664 : elt, GET_MODE_INNER (GET_MODE (op)));
1947 : else
1948 : /* Try applying the operator to ELT and see if that simplifies.
1949 : We can duplicate the result if so.
1950 :
1951 : The reason we traditionally haven't used simplify_gen_unary
1952 : for these codes is that it didn't necessarily seem to be a
1953 : win to convert things like:
1954 :
1955 : (neg:V (vec_duplicate:V (reg:S R)))
1956 :
1957 : to:
1958 :
1959 : (vec_duplicate:V (neg:S (reg:S R)))
1960 :
1961 : The first might be done entirely in vector registers while the
1962 : second might need a move between register files.
1963 :
1964 : However, there also cases where promoting the vec_duplicate is
1965 : more efficient, and there is definite value in having a canonical
1966 : form when matching instruction patterns. We should consider
1967 : extending the simplify_gen_unary code above to more cases. */
1968 1056 : temp = simplify_unary_operation (code, GET_MODE_INNER (mode),
1969 2112 : elt, GET_MODE_INNER (GET_MODE (op)));
1970 5888 : if (temp)
1971 5412 : return gen_vec_duplicate (mode, temp);
1972 : }
1973 :
1974 : return 0;
1975 : }
1976 :
1977 : /* Try to compute the value of a unary operation CODE whose output mode is to
1978 : be MODE with input operand OP whose mode was originally OP_MODE.
1979 : Return zero if the value cannot be computed. */
1980 : rtx
1981 28790290 : simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
1982 : rtx op, machine_mode op_mode)
1983 : {
1984 28790290 : scalar_int_mode result_mode;
1985 :
1986 28790290 : if (code == VEC_DUPLICATE)
1987 : {
1988 1667661 : gcc_assert (VECTOR_MODE_P (mode));
1989 1667661 : if (GET_MODE (op) != VOIDmode)
1990 : {
1991 568738 : if (!VECTOR_MODE_P (GET_MODE (op)))
1992 1124198 : gcc_assert (GET_MODE_INNER (mode) == GET_MODE (op));
1993 : else
1994 19917 : gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER
1995 : (GET_MODE (op)));
1996 : }
1997 1667661 : if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op))
1998 1137849 : return gen_const_vec_duplicate (mode, op);
1999 529812 : if (GET_CODE (op) == CONST_VECTOR
2000 529812 : && (CONST_VECTOR_DUPLICATE_P (op)
2001 : || CONST_VECTOR_NUNITS (op).is_constant ()))
2002 : {
2003 755 : unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op)
2004 755 : ? CONST_VECTOR_NPATTERNS (op)
2005 1509 : : CONST_VECTOR_NUNITS (op).to_constant ());
2006 2265 : gcc_assert (multiple_p (GET_MODE_NUNITS (mode), npatterns));
2007 755 : rtx_vector_builder builder (mode, npatterns, 1);
2008 3130 : for (unsigned i = 0; i < npatterns; i++)
2009 2375 : builder.quick_push (CONST_VECTOR_ELT (op, i));
2010 755 : return builder.build ();
2011 755 : }
2012 : }
2013 :
2014 26360902 : if (VECTOR_MODE_P (mode)
2015 1615192 : && GET_CODE (op) == CONST_VECTOR
2016 27753746 : && known_eq (GET_MODE_NUNITS (mode), CONST_VECTOR_NUNITS (op)))
2017 : {
2018 34020 : gcc_assert (GET_MODE (op) == op_mode);
2019 :
2020 34020 : rtx_vector_builder builder;
2021 34020 : if (!builder.new_unary_operation (mode, op, false))
2022 : return 0;
2023 :
2024 34020 : unsigned int count = builder.encoded_nelts ();
2025 152574 : for (unsigned int i = 0; i < count; i++)
2026 : {
2027 238146 : rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
2028 : CONST_VECTOR_ELT (op, i),
2029 238146 : GET_MODE_INNER (op_mode));
2030 119073 : if (!x || !valid_for_const_vector_p (mode, x))
2031 519 : return 0;
2032 118554 : builder.quick_push (x);
2033 : }
2034 33501 : return builder.build ();
2035 34020 : }
2036 :
2037 : /* The order of these tests is critical so that, for example, we don't
2038 : check the wrong mode (input vs. output) for a conversion operation,
2039 : such as FIX. At some point, this should be simplified. */
2040 :
2041 27617666 : if (code == FLOAT && CONST_SCALAR_INT_P (op))
2042 : {
2043 7805 : REAL_VALUE_TYPE d;
2044 :
2045 7805 : if (op_mode == VOIDmode)
2046 : {
2047 : /* CONST_INT have VOIDmode as the mode. We assume that all
2048 : the bits of the constant are significant, though, this is
2049 : a dangerous assumption as many times CONST_INTs are
2050 : created and used with garbage in the bits outside of the
2051 : precision of the implied mode of the const_int. */
2052 64 : op_mode = MAX_MODE_INT;
2053 : }
2054 :
2055 7805 : real_from_integer (&d, mode, rtx_mode_t (op, op_mode), SIGNED);
2056 :
2057 : /* Avoid the folding if flag_signaling_nans is on and
2058 : operand is a signaling NaN. */
2059 7805 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2060 : return 0;
2061 :
2062 7805 : d = real_value_truncate (mode, d);
2063 :
2064 : /* Avoid the folding if flag_rounding_math is on and the
2065 : conversion is not exact. */
2066 7805 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2067 : {
2068 1011 : bool fail = false;
2069 1011 : wide_int w = real_to_integer (&d, &fail,
2070 : GET_MODE_PRECISION
2071 1011 : (as_a <scalar_int_mode> (op_mode)));
2072 2022 : if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
2073 905 : return 0;
2074 1011 : }
2075 :
2076 6900 : return const_double_from_real_value (d, mode);
2077 : }
2078 27609861 : else if (code == UNSIGNED_FLOAT && CONST_SCALAR_INT_P (op))
2079 : {
2080 2139 : REAL_VALUE_TYPE d;
2081 :
2082 2139 : if (op_mode == VOIDmode)
2083 : {
2084 : /* CONST_INT have VOIDmode as the mode. We assume that all
2085 : the bits of the constant are significant, though, this is
2086 : a dangerous assumption as many times CONST_INTs are
2087 : created and used with garbage in the bits outside of the
2088 : precision of the implied mode of the const_int. */
2089 8 : op_mode = MAX_MODE_INT;
2090 : }
2091 :
2092 2139 : real_from_integer (&d, mode, rtx_mode_t (op, op_mode), UNSIGNED);
2093 :
2094 : /* Avoid the folding if flag_signaling_nans is on and
2095 : operand is a signaling NaN. */
2096 2139 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2097 : return 0;
2098 :
2099 2139 : d = real_value_truncate (mode, d);
2100 :
2101 : /* Avoid the folding if flag_rounding_math is on and the
2102 : conversion is not exact. */
2103 2139 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2104 : {
2105 16 : bool fail = false;
2106 16 : wide_int w = real_to_integer (&d, &fail,
2107 : GET_MODE_PRECISION
2108 16 : (as_a <scalar_int_mode> (op_mode)));
2109 28 : if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
2110 16 : return 0;
2111 16 : }
2112 :
2113 2123 : return const_double_from_real_value (d, mode);
2114 : }
2115 :
2116 27607722 : if (CONST_SCALAR_INT_P (op) && is_a <scalar_int_mode> (mode, &result_mode))
2117 : {
2118 3766367 : unsigned int width = GET_MODE_PRECISION (result_mode);
2119 3766367 : if (width > MAX_BITSIZE_MODE_ANY_INT)
2120 : return 0;
2121 :
2122 3766367 : wide_int result;
2123 3766367 : scalar_int_mode imode = (op_mode == VOIDmode
2124 3766367 : ? result_mode
2125 3766150 : : as_a <scalar_int_mode> (op_mode));
2126 3766367 : rtx_mode_t op0 = rtx_mode_t (op, imode);
2127 3766367 : int int_value;
2128 :
2129 : #if TARGET_SUPPORTS_WIDE_INT == 0
2130 : /* This assert keeps the simplification from producing a result
2131 : that cannot be represented in a CONST_DOUBLE but a lot of
2132 : upstream callers expect that this function never fails to
2133 : simplify something and so you if you added this to the test
2134 : above the code would die later anyway. If this assert
2135 : happens, you just need to make the port support wide int. */
2136 : gcc_assert (width <= HOST_BITS_PER_DOUBLE_INT);
2137 : #endif
2138 :
2139 3766367 : switch (code)
2140 : {
2141 170771 : case NOT:
2142 170771 : result = wi::bit_not (op0);
2143 170771 : break;
2144 :
2145 1855097 : case NEG:
2146 1855097 : result = wi::neg (op0);
2147 1855097 : break;
2148 :
2149 7062 : case ABS:
2150 7062 : result = wi::abs (op0);
2151 7062 : break;
2152 :
2153 0 : case FFS:
2154 0 : result = wi::shwi (wi::ffs (op0), result_mode);
2155 0 : break;
2156 :
2157 168 : case CLZ:
2158 168 : if (wi::ne_p (op0, 0))
2159 38 : int_value = wi::clz (op0);
2160 260 : else if (! CLZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2161 : return NULL_RTX;
2162 38 : result = wi::shwi (int_value, result_mode);
2163 38 : break;
2164 :
2165 0 : case CLRSB:
2166 0 : result = wi::shwi (wi::clrsb (op0), result_mode);
2167 0 : break;
2168 :
2169 0 : case CTZ:
2170 0 : if (wi::ne_p (op0, 0))
2171 0 : int_value = wi::ctz (op0);
2172 0 : else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2173 : return NULL_RTX;
2174 0 : result = wi::shwi (int_value, result_mode);
2175 0 : break;
2176 :
2177 160 : case POPCOUNT:
2178 160 : result = wi::shwi (wi::popcount (op0), result_mode);
2179 160 : break;
2180 :
2181 0 : case PARITY:
2182 0 : result = wi::shwi (wi::parity (op0), result_mode);
2183 0 : break;
2184 :
2185 1757 : case BSWAP:
2186 1757 : result = wi::bswap (op0);
2187 1757 : break;
2188 :
2189 0 : case BITREVERSE:
2190 0 : result = wi::bitreverse (op0);
2191 0 : break;
2192 :
2193 1552893 : case TRUNCATE:
2194 1552893 : case ZERO_EXTEND:
2195 1552893 : result = wide_int::from (op0, width, UNSIGNED);
2196 1552893 : break;
2197 :
2198 14342 : case US_TRUNCATE:
2199 14342 : case SS_TRUNCATE:
2200 14342 : {
2201 14342 : signop sgn = code == US_TRUNCATE ? UNSIGNED : SIGNED;
2202 14342 : wide_int nmax
2203 14342 : = wide_int::from (wi::max_value (width, sgn),
2204 28684 : GET_MODE_PRECISION (imode), sgn);
2205 14342 : wide_int nmin
2206 14342 : = wide_int::from (wi::min_value (width, sgn),
2207 28684 : GET_MODE_PRECISION (imode), sgn);
2208 14342 : result = wi::min (wi::max (op0, nmin, sgn), nmax, sgn);
2209 14342 : result = wide_int::from (result, width, sgn);
2210 14342 : break;
2211 14342 : }
2212 164117 : case SIGN_EXTEND:
2213 164117 : result = wide_int::from (op0, width, SIGNED);
2214 164117 : break;
2215 :
2216 0 : case SS_NEG:
2217 0 : if (wi::only_sign_bit_p (op0))
2218 0 : result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
2219 : else
2220 0 : result = wi::neg (op0);
2221 : break;
2222 :
2223 0 : case SS_ABS:
2224 0 : if (wi::only_sign_bit_p (op0))
2225 0 : result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
2226 : else
2227 0 : result = wi::abs (op0);
2228 : break;
2229 :
2230 : case SQRT:
2231 : default:
2232 : return 0;
2233 : }
2234 :
2235 3766237 : return immed_wide_int_const (result, result_mode);
2236 3766367 : }
2237 :
2238 23841355 : else if (CONST_DOUBLE_AS_FLOAT_P (op)
2239 412131 : && SCALAR_FLOAT_MODE_P (mode)
2240 410096 : && SCALAR_FLOAT_MODE_P (GET_MODE (op)))
2241 : {
2242 410096 : REAL_VALUE_TYPE d = *CONST_DOUBLE_REAL_VALUE (op);
2243 410096 : switch (code)
2244 : {
2245 : case SQRT:
2246 : return 0;
2247 544 : case ABS:
2248 544 : d = real_value_abs (&d);
2249 544 : break;
2250 15751 : case NEG:
2251 15751 : d = real_value_negate (&d);
2252 15751 : break;
2253 2284 : case FLOAT_TRUNCATE:
2254 : /* Don't perform the operation if flag_signaling_nans is on
2255 : and the operand is a signaling NaN. */
2256 2284 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2257 : return NULL_RTX;
2258 : /* Or if flag_rounding_math is on and the truncation is not
2259 : exact. */
2260 2284 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2261 2284 : && !exact_real_truncate (mode, &d))
2262 231 : return NULL_RTX;
2263 2053 : d = real_value_truncate (mode, d);
2264 2053 : break;
2265 385041 : case FLOAT_EXTEND:
2266 : /* Don't perform the operation if flag_signaling_nans is on
2267 : and the operand is a signaling NaN. */
2268 385041 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2269 : return NULL_RTX;
2270 : /* All this does is change the mode, unless changing
2271 : mode class. */
2272 385039 : if (GET_MODE_CLASS (mode) != GET_MODE_CLASS (GET_MODE (op)))
2273 0 : real_convert (&d, mode, &d);
2274 : break;
2275 0 : case FIX:
2276 : /* Don't perform the operation if flag_signaling_nans is on
2277 : and the operand is a signaling NaN. */
2278 0 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2279 : return NULL_RTX;
2280 0 : real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
2281 0 : break;
2282 5871 : case NOT:
2283 5871 : {
2284 5871 : long tmp[4];
2285 5871 : int i;
2286 :
2287 5871 : real_to_target (tmp, &d, GET_MODE (op));
2288 29355 : for (i = 0; i < 4; i++)
2289 23484 : tmp[i] = ~tmp[i];
2290 5871 : real_from_target (&d, tmp, mode);
2291 5871 : break;
2292 : }
2293 0 : default:
2294 0 : gcc_unreachable ();
2295 : }
2296 409258 : return const_double_from_real_value (d, mode);
2297 : }
2298 2035 : else if (CONST_DOUBLE_AS_FLOAT_P (op)
2299 2035 : && SCALAR_FLOAT_MODE_P (GET_MODE (op))
2300 23433294 : && is_int_mode (mode, &result_mode))
2301 : {
2302 2035 : unsigned int width = GET_MODE_PRECISION (result_mode);
2303 2035 : if (width > MAX_BITSIZE_MODE_ANY_INT)
2304 : return 0;
2305 :
2306 : /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
2307 : operators are intentionally left unspecified (to ease implementation
2308 : by target backends), for consistency, this routine implements the
2309 : same semantics for constant folding as used by the middle-end. */
2310 :
2311 : /* This was formerly used only for non-IEEE float.
2312 : eggert@twinsun.com says it is safe for IEEE also. */
2313 2035 : REAL_VALUE_TYPE t;
2314 2035 : const REAL_VALUE_TYPE *x = CONST_DOUBLE_REAL_VALUE (op);
2315 2035 : wide_int wmax, wmin;
2316 : /* This is part of the abi to real_to_integer, but we check
2317 : things before making this call. */
2318 2035 : bool fail;
2319 :
2320 2035 : switch (code)
2321 : {
2322 2027 : case FIX:
2323 : /* According to IEEE standard, for conversions from floating point to
2324 : integer. When a NaN or infinite operand cannot be represented in
2325 : the destination format and this cannot otherwise be indicated, the
2326 : invalid operation exception shall be signaled. When a numeric
2327 : operand would convert to an integer outside the range of the
2328 : destination format, the invalid operation exception shall be
2329 : signaled if this situation cannot otherwise be indicated. */
2330 2027 : if (REAL_VALUE_ISNAN (*x))
2331 955 : return flag_trapping_math ? NULL_RTX : const0_rtx;
2332 :
2333 1072 : if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
2334 : return NULL_RTX;
2335 :
2336 : /* Test against the signed upper bound. */
2337 112 : wmax = wi::max_value (width, SIGNED);
2338 112 : real_from_integer (&t, VOIDmode, wmax, SIGNED);
2339 112 : if (real_less (&t, x))
2340 3 : return (flag_trapping_math
2341 3 : ? NULL_RTX : immed_wide_int_const (wmax, mode));
2342 :
2343 : /* Test against the signed lower bound. */
2344 109 : wmin = wi::min_value (width, SIGNED);
2345 109 : real_from_integer (&t, VOIDmode, wmin, SIGNED);
2346 109 : if (real_less (x, &t))
2347 8 : return immed_wide_int_const (wmin, mode);
2348 :
2349 101 : return immed_wide_int_const (real_to_integer (x, &fail, width),
2350 : mode);
2351 :
2352 8 : case UNSIGNED_FIX:
2353 8 : if (REAL_VALUE_ISNAN (*x) || REAL_VALUE_NEGATIVE (*x))
2354 6 : return flag_trapping_math ? NULL_RTX : const0_rtx;
2355 :
2356 2 : if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
2357 : return NULL_RTX;
2358 :
2359 : /* Test against the unsigned upper bound. */
2360 0 : wmax = wi::max_value (width, UNSIGNED);
2361 0 : real_from_integer (&t, VOIDmode, wmax, UNSIGNED);
2362 0 : if (real_less (&t, x))
2363 0 : return (flag_trapping_math
2364 0 : ? NULL_RTX : immed_wide_int_const (wmax, mode));
2365 :
2366 0 : return immed_wide_int_const (real_to_integer (x, &fail, width),
2367 : mode);
2368 :
2369 0 : default:
2370 0 : gcc_unreachable ();
2371 : }
2372 2035 : }
2373 :
2374 : /* Handle polynomial integers. */
2375 : else if (CONST_POLY_INT_P (op))
2376 : {
2377 : poly_wide_int result;
2378 : switch (code)
2379 : {
2380 : case NEG:
2381 : result = -const_poly_int_value (op);
2382 : break;
2383 :
2384 : case NOT:
2385 : result = ~const_poly_int_value (op);
2386 : break;
2387 :
2388 : default:
2389 : return NULL_RTX;
2390 : }
2391 : return immed_wide_int_const (result, mode);
2392 : }
2393 :
2394 : return NULL_RTX;
2395 : }
2396 :
2397 : /* Subroutine of simplify_binary_operation to simplify a binary operation
2398 : CODE that can commute with byte swapping, with result mode MODE and
2399 : operating on OP0 and OP1. CODE is currently one of AND, IOR or XOR.
2400 : Return zero if no simplification or canonicalization is possible. */
2401 :
2402 : rtx
2403 37160820 : simplify_context::simplify_byte_swapping_operation (rtx_code code,
2404 : machine_mode mode,
2405 : rtx op0, rtx op1)
2406 : {
2407 37160820 : rtx tem;
2408 :
2409 : /* (op (bswap x) C1)) -> (bswap (op x C2)) with C2 swapped. */
2410 37160820 : if (GET_CODE (op0) == BSWAP && CONST_SCALAR_INT_P (op1))
2411 : {
2412 254 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0),
2413 : simplify_gen_unary (BSWAP, mode, op1, mode));
2414 254 : return simplify_gen_unary (BSWAP, mode, tem, mode);
2415 : }
2416 :
2417 : /* (op (bswap x) (bswap y)) -> (bswap (op x y)). */
2418 37160566 : if (GET_CODE (op0) == BSWAP && GET_CODE (op1) == BSWAP)
2419 : {
2420 0 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0), XEXP (op1, 0));
2421 0 : return simplify_gen_unary (BSWAP, mode, tem, mode);
2422 : }
2423 :
2424 : return NULL_RTX;
2425 : }
2426 :
2427 : /* Subroutine of simplify_binary_operation to simplify a commutative,
2428 : associative binary operation CODE with result mode MODE, operating
2429 : on OP0 and OP1. CODE is currently one of PLUS, MULT, AND, IOR, XOR,
2430 : SMIN, SMAX, UMIN or UMAX. Return zero if no simplification or
2431 : canonicalization is possible. */
2432 :
2433 : rtx
2434 47729490 : simplify_context::simplify_associative_operation (rtx_code code,
2435 : machine_mode mode,
2436 : rtx op0, rtx op1)
2437 : {
2438 47729490 : rtx tem;
2439 :
2440 : /* Normally expressions simplified by simplify-rtx.cc are combined
2441 : at most from a few machine instructions and therefore the
2442 : expressions should be fairly small. During var-tracking
2443 : we can see arbitrarily large expressions though and reassociating
2444 : those can be quadratic, so punt after encountering max_assoc_count
2445 : simplify_associative_operation calls during outermost simplify_*
2446 : call. */
2447 47729490 : if (++assoc_count >= max_assoc_count)
2448 : return NULL_RTX;
2449 :
2450 : /* Linearize the operator to the left. */
2451 47725060 : if (GET_CODE (op1) == code)
2452 : {
2453 : /* "(a op b) op (c op d)" becomes "((a op b) op c) op d)". */
2454 18376 : if (GET_CODE (op0) == code)
2455 : {
2456 4960 : tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
2457 4960 : return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
2458 : }
2459 :
2460 : /* "a op (b op c)" becomes "(b op c) op a". */
2461 13416 : if (! swap_commutative_operands_p (op1, op0))
2462 13416 : return simplify_gen_binary (code, mode, op1, op0);
2463 :
2464 : std::swap (op0, op1);
2465 : }
2466 :
2467 47706684 : if (GET_CODE (op0) == code)
2468 : {
2469 : /* Canonicalize "(x op c) op y" as "(x op y) op c". */
2470 1311129 : if (swap_commutative_operands_p (XEXP (op0, 1), op1))
2471 : {
2472 264135 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
2473 264135 : return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2474 : }
2475 :
2476 : /* Attempt to simplify "(a op b) op c" as "a op (b op c)". */
2477 1046994 : tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
2478 1046994 : if (tem != 0)
2479 77523 : return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
2480 :
2481 : /* Attempt to simplify "(a op b) op c" as "(a op c) op b". */
2482 969471 : tem = simplify_binary_operation (code, mode, XEXP (op0, 0), op1);
2483 969471 : if (tem != 0)
2484 32429 : return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2485 : }
2486 :
2487 : return 0;
2488 : }
2489 :
2490 : /* If COMPARISON can be treated as an unsigned comparison, return a mask
2491 : that represents it (8 if it includes <, 4 if it includes > and 2
2492 : if it includes ==). Return 0 otherwise. */
2493 : static int
2494 18898 : unsigned_comparison_to_mask (rtx_code comparison)
2495 : {
2496 0 : switch (comparison)
2497 : {
2498 : case LTU:
2499 : return 8;
2500 : case GTU:
2501 : return 4;
2502 : case EQ:
2503 : return 2;
2504 :
2505 : case LEU:
2506 : return 10;
2507 : case GEU:
2508 : return 6;
2509 :
2510 : case NE:
2511 : return 12;
2512 :
2513 : default:
2514 : return 0;
2515 : }
2516 : }
2517 :
2518 : /* Reverse the mapping in unsigned_comparison_to_mask, going from masks
2519 : to comparisons. */
2520 : static rtx_code
2521 6612 : mask_to_unsigned_comparison (int mask)
2522 : {
2523 6612 : switch (mask)
2524 : {
2525 : case 8:
2526 : return LTU;
2527 160 : case 4:
2528 160 : return GTU;
2529 2515 : case 2:
2530 2515 : return EQ;
2531 :
2532 160 : case 10:
2533 160 : return LEU;
2534 160 : case 6:
2535 160 : return GEU;
2536 :
2537 3457 : case 12:
2538 3457 : return NE;
2539 :
2540 0 : default:
2541 0 : gcc_unreachable ();
2542 : }
2543 : }
2544 :
2545 : /* Return a mask describing the COMPARISON. */
2546 : static int
2547 2666 : comparison_to_mask (enum rtx_code comparison)
2548 : {
2549 2666 : switch (comparison)
2550 : {
2551 : case LT:
2552 : return 8;
2553 472 : case GT:
2554 472 : return 4;
2555 419 : case EQ:
2556 419 : return 2;
2557 19 : case UNORDERED:
2558 19 : return 1;
2559 :
2560 0 : case LTGT:
2561 0 : return 12;
2562 441 : case LE:
2563 441 : return 10;
2564 441 : case GE:
2565 441 : return 6;
2566 0 : case UNLT:
2567 0 : return 9;
2568 0 : case UNGT:
2569 0 : return 5;
2570 0 : case UNEQ:
2571 0 : return 3;
2572 :
2573 0 : case ORDERED:
2574 0 : return 14;
2575 400 : case NE:
2576 400 : return 13;
2577 0 : case UNLE:
2578 0 : return 11;
2579 0 : case UNGE:
2580 0 : return 7;
2581 :
2582 0 : default:
2583 0 : gcc_unreachable ();
2584 : }
2585 : }
2586 :
2587 : /* Return a comparison corresponding to the MASK. */
2588 : static enum rtx_code
2589 1014 : mask_to_comparison (int mask)
2590 : {
2591 1014 : switch (mask)
2592 : {
2593 : case 8:
2594 : return LT;
2595 : case 4:
2596 : return GT;
2597 : case 2:
2598 : return EQ;
2599 : case 1:
2600 : return UNORDERED;
2601 :
2602 : case 12:
2603 : return LTGT;
2604 : case 10:
2605 : return LE;
2606 : case 6:
2607 : return GE;
2608 : case 9:
2609 : return UNLT;
2610 : case 5:
2611 : return UNGT;
2612 : case 3:
2613 : return UNEQ;
2614 :
2615 : case 14:
2616 : return ORDERED;
2617 : case 13:
2618 : return NE;
2619 : case 11:
2620 : return UNLE;
2621 : case 7:
2622 : return UNGE;
2623 :
2624 0 : default:
2625 0 : gcc_unreachable ();
2626 : }
2627 : }
2628 :
2629 : /* Canonicalize RES, a scalar const0_rtx/const_true_rtx to the right
2630 : false/true value of comparison with MODE where comparison operands
2631 : have CMP_MODE. */
2632 :
2633 : static rtx
2634 776840 : relational_result (machine_mode mode, machine_mode cmp_mode, rtx res)
2635 : {
2636 776840 : if (SCALAR_FLOAT_MODE_P (mode))
2637 : {
2638 197 : if (res == const0_rtx)
2639 193 : return CONST0_RTX (mode);
2640 : #ifdef FLOAT_STORE_FLAG_VALUE
2641 : REAL_VALUE_TYPE val = FLOAT_STORE_FLAG_VALUE (mode);
2642 : return const_double_from_real_value (val, mode);
2643 : #else
2644 : return NULL_RTX;
2645 : #endif
2646 : }
2647 776643 : if (VECTOR_MODE_P (mode))
2648 : {
2649 397 : if (res == const0_rtx)
2650 75 : return CONST0_RTX (mode);
2651 : #ifdef VECTOR_STORE_FLAG_VALUE
2652 322 : rtx val = VECTOR_STORE_FLAG_VALUE (mode);
2653 312 : if (val == NULL_RTX)
2654 : return NULL_RTX;
2655 312 : if (val == const1_rtx)
2656 0 : return CONST1_RTX (mode);
2657 :
2658 312 : return gen_const_vec_duplicate (mode, val);
2659 : #else
2660 : return NULL_RTX;
2661 : #endif
2662 : }
2663 : /* For vector comparison with scalar int result, it is unknown
2664 : if the target means here a comparison into an integral bitmask,
2665 : or comparison where all comparisons true mean const_true_rtx
2666 : whole result, or where any comparisons true mean const_true_rtx
2667 : whole result. For const0_rtx all the cases are the same. */
2668 776246 : if (VECTOR_MODE_P (cmp_mode)
2669 0 : && SCALAR_INT_MODE_P (mode)
2670 0 : && res == const_true_rtx)
2671 0 : return NULL_RTX;
2672 :
2673 : return res;
2674 : }
2675 :
2676 : /* Simplify a logical operation CODE with result mode MODE, operating on OP0
2677 : and OP1, in the case where both are relational operations. Assume that
2678 : OP0 is inverted if INVERT0_P is true.
2679 :
2680 : Return 0 if no such simplification is possible. */
2681 : rtx
2682 13453163 : simplify_context::simplify_logical_relational_operation (rtx_code code,
2683 : machine_mode mode,
2684 : rtx op0, rtx op1,
2685 : bool invert0_p)
2686 : {
2687 13453163 : if (!(COMPARISON_P (op0) && COMPARISON_P (op1)))
2688 : return 0;
2689 :
2690 21702 : if (!(rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2691 9877 : && rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))))
2692 2376 : return 0;
2693 :
2694 9449 : if (side_effects_p (op0))
2695 : return 0;
2696 :
2697 9449 : enum rtx_code code0 = GET_CODE (op0);
2698 9449 : enum rtx_code code1 = GET_CODE (op1);
2699 9449 : machine_mode cmp_mode = GET_MODE (XEXP (op0, 0));
2700 9449 : if (cmp_mode == VOIDmode)
2701 0 : cmp_mode = GET_MODE (XEXP (op0, 1));
2702 :
2703 : /* Assume at first that the comparisons are on integers, and that the
2704 : operands are therefore ordered. */
2705 9449 : int all = 14;
2706 9449 : int mask0 = unsigned_comparison_to_mask (code0);
2707 9449 : int mask1 = unsigned_comparison_to_mask (code1);
2708 18898 : bool unsigned_p = (IN_RANGE (mask0 & 12, 4, 8)
2709 9449 : || IN_RANGE (mask1 & 12, 4, 8));
2710 1333 : if (unsigned_p)
2711 : {
2712 : /* We only reach here when comparing integers. Reject mixtures of signed
2713 : and unsigned comparisons. */
2714 8116 : if (mask0 == 0 || mask1 == 0)
2715 : return 0;
2716 : }
2717 : else
2718 : {
2719 : /* See whether the operands might be unordered. Assume that all
2720 : results are possible for CC modes, and punt later if we don't get an
2721 : always-true or always-false answer. */
2722 1333 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC || HONOR_NANS (cmp_mode))
2723 : all = 15;
2724 1333 : mask0 = comparison_to_mask (code0) & all;
2725 1333 : mask1 = comparison_to_mask (code1) & all;
2726 : }
2727 :
2728 8169 : if (invert0_p)
2729 4583 : mask0 = mask0 ^ all;
2730 :
2731 8169 : int mask;
2732 8169 : if (code == AND)
2733 960 : mask = mask0 & mask1;
2734 7209 : else if (code == IOR)
2735 948 : mask = mask0 | mask1;
2736 6261 : else if (code == XOR)
2737 6261 : mask = mask0 ^ mask1;
2738 : else
2739 : return 0;
2740 :
2741 8169 : if (mask == all)
2742 232 : return relational_result (mode, GET_MODE (op0), const_true_rtx);
2743 :
2744 7937 : if (mask == 0)
2745 232 : return relational_result (mode, GET_MODE (op0), const0_rtx);
2746 :
2747 7705 : if (unsigned_p)
2748 6612 : code = mask_to_unsigned_comparison (mask);
2749 : else
2750 : {
2751 1093 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
2752 : return 0;
2753 :
2754 1014 : code = mask_to_comparison (mask);
2755 : /* LTGT and NE are arithmetically equivalent for ordered operands,
2756 : with NE being the canonical choice. */
2757 1014 : if (code == LTGT && all == 14)
2758 184 : code = NE;
2759 : }
2760 :
2761 7626 : op0 = XEXP (op1, 0);
2762 7626 : op1 = XEXP (op1, 1);
2763 :
2764 7626 : return simplify_gen_relational (code, mode, VOIDmode, op0, op1);
2765 : }
2766 :
2767 : /* We are going to IOR together OP0/OP1. If there is a common term in OP0/OP1
2768 : then we may be able to simplify the expression. We're primarily trying to
2769 : simplify down to IOR/XOR expression right now, but there may be other
2770 : simplifications we can do in the future.
2771 :
2772 : Return the simplified expression or NULL_RTX if no simplification was
2773 : possible. */
2774 : rtx
2775 27429173 : simplify_context::simplify_ior_with_common_term (machine_mode mode, rtx op0, rtx op1)
2776 : {
2777 : /* (ior X (plus/xor X C)) can be simplified into (ior X C) when
2778 : X and C have no bits in common. */
2779 27429173 : if ((GET_CODE (op1) == PLUS || GET_CODE (op1) == XOR)
2780 230921 : && rtx_equal_p (op0, XEXP (op1, 0))
2781 8325 : && ((nonzero_bits (op0, GET_MODE (op0))
2782 8325 : & nonzero_bits (XEXP (op1, 1), GET_MODE (op1))) == 0)
2783 27429173 : && !side_effects_p (op1))
2784 0 : return simplify_gen_binary (IOR, mode, op0, XEXP (op1, 1));
2785 :
2786 : /* (ior (and A C1) (and (not A) C2)) can be converted
2787 : into (and (xor A C2) (C1 + C2)) when there are no bits
2788 : in common between C1 and C2. */
2789 27429173 : if (GET_CODE (op0) == AND
2790 4010790 : && GET_CODE (op1) == AND
2791 396177 : && GET_CODE (XEXP (op1, 0)) == NOT
2792 20992 : && rtx_equal_p (XEXP (op0, 0), XEXP (XEXP (op1, 0), 0))
2793 3386 : && CONST_INT_P (XEXP (op0, 1))
2794 91 : && CONST_INT_P (XEXP (op1, 1))
2795 27429264 : && (INTVAL (XEXP (op0, 1)) & INTVAL (XEXP (op1, 1))) == 0)
2796 : {
2797 91 : rtx c = GEN_INT (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1)));
2798 :
2799 91 : rtx tem = simplify_gen_binary (XOR, mode, XEXP (op0, 0), XEXP (op1, 1));
2800 91 : if (tem)
2801 : {
2802 91 : tem = simplify_gen_binary (AND, mode, tem, c);
2803 :
2804 91 : if (tem)
2805 : return tem;
2806 : }
2807 : }
2808 :
2809 : /* Another variant seen on some target particularly those with
2810 : sub-word operations.
2811 :
2812 : (ior (and A C1) (plus (and A C2) C2)) can be simplified into
2813 : (and (xor (A C2) (C1 + C2).
2814 :
2815 : Where C2 is the sign bit for A's mode. So 0x80 for QI,
2816 : 0x8000 for HI, etc. In this case we know there is no carry
2817 : from the PLUS into relevant bits of the output. */
2818 27429082 : if (GET_CODE (op0) == AND
2819 4010699 : && GET_CODE (op1) == PLUS
2820 5840 : && GET_CODE (XEXP (op1, 0)) == AND
2821 300 : && rtx_equal_p (XEXP (op0, 0), XEXP (XEXP (op1, 0), 0))
2822 276 : && CONST_INT_P (XEXP (op0, 1))
2823 276 : && CONST_INT_P (XEXP (op1, 1))
2824 276 : && CONST_INT_P (XEXP (XEXP (op1, 0), 1))
2825 276 : && INTVAL (XEXP (op1, 1)) == INTVAL (XEXP (XEXP (op1, 0), 1))
2826 72 : && GET_MODE_BITSIZE (GET_MODE (op1)).is_constant ()
2827 144 : && ((INTVAL (XEXP (op1, 1)) & GET_MODE_MASK (GET_MODE (op1)))
2828 144 : == HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (GET_MODE (op1)).to_constant () - 1))
2829 27429082 : && (INTVAL (XEXP (op0, 1)) & INTVAL (XEXP (op1, 1))) == 0)
2830 : {
2831 0 : rtx c = GEN_INT (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1)));
2832 :
2833 0 : rtx tem = simplify_gen_binary (XOR, mode, XEXP (op0, 0), XEXP (op1, 1));
2834 0 : if (tem)
2835 : {
2836 0 : tem = simplify_gen_binary (AND, mode, tem, c);
2837 0 : if (tem)
2838 : return tem;
2839 : }
2840 : }
2841 : return NULL_RTX;
2842 : }
2843 :
2844 :
2845 : /* Simplify a binary operation CODE with result mode MODE, operating on OP0
2846 : and OP1. Return 0 if no simplification is possible.
2847 :
2848 : Don't use this for relational operations such as EQ or LT.
2849 : Use simplify_relational_operation instead. */
2850 : rtx
2851 485561472 : simplify_context::simplify_binary_operation (rtx_code code, machine_mode mode,
2852 : rtx op0, rtx op1)
2853 : {
2854 485561472 : rtx trueop0, trueop1;
2855 485561472 : rtx tem;
2856 :
2857 : /* Relational operations don't work here. We must know the mode
2858 : of the operands in order to do the comparison correctly.
2859 : Assuming a full word can give incorrect results.
2860 : Consider comparing 128 with -128 in QImode. */
2861 485561472 : gcc_assert (GET_RTX_CLASS (code) != RTX_COMPARE);
2862 485561472 : gcc_assert (GET_RTX_CLASS (code) != RTX_COMM_COMPARE);
2863 :
2864 : /* Make sure the constant is second. */
2865 485561472 : if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
2866 485561472 : && swap_commutative_operands_p (op0, op1))
2867 : std::swap (op0, op1);
2868 :
2869 485561472 : trueop0 = avoid_constant_pool_reference (op0);
2870 485561472 : trueop1 = avoid_constant_pool_reference (op1);
2871 :
2872 485561472 : tem = simplify_const_binary_operation (code, mode, trueop0, trueop1);
2873 485561472 : if (tem)
2874 : return tem;
2875 455504172 : tem = simplify_binary_operation_1 (code, mode, op0, op1, trueop0, trueop1);
2876 :
2877 455504172 : if (tem)
2878 : return tem;
2879 :
2880 : /* If the above steps did not result in a simplification and op0 or op1
2881 : were constant pool references, use the referenced constants directly. */
2882 391503086 : if (trueop0 != op0 || trueop1 != op1)
2883 581779 : return simplify_gen_binary (code, mode, trueop0, trueop1);
2884 :
2885 : return NULL_RTX;
2886 : }
2887 :
2888 : /* Subroutine of simplify_binary_operation_1 that looks for cases in
2889 : which OP0 and OP1 are both vector series or vector duplicates
2890 : (which are really just series with a step of 0). If so, try to
2891 : form a new series by applying CODE to the bases and to the steps.
2892 : Return null if no simplification is possible.
2893 :
2894 : MODE is the mode of the operation and is known to be a vector
2895 : integer mode. */
2896 :
2897 : rtx
2898 2513918 : simplify_context::simplify_binary_operation_series (rtx_code code,
2899 : machine_mode mode,
2900 : rtx op0, rtx op1)
2901 : {
2902 2513918 : rtx base0, step0;
2903 2513918 : if (vec_duplicate_p (op0, &base0))
2904 73073 : step0 = const0_rtx;
2905 2440845 : else if (!vec_series_p (op0, &base0, &step0))
2906 : return NULL_RTX;
2907 :
2908 73793 : rtx base1, step1;
2909 73793 : if (vec_duplicate_p (op1, &base1))
2910 422 : step1 = const0_rtx;
2911 73371 : else if (!vec_series_p (op1, &base1, &step1))
2912 : return NULL_RTX;
2913 :
2914 : /* Only create a new series if we can simplify both parts. In other
2915 : cases this isn't really a simplification, and it's not necessarily
2916 : a win to replace a vector operation with a scalar operation. */
2917 5663 : scalar_mode inner_mode = GET_MODE_INNER (mode);
2918 5663 : rtx new_base = simplify_binary_operation (code, inner_mode, base0, base1);
2919 5663 : if (!new_base)
2920 : return NULL_RTX;
2921 :
2922 4709 : rtx new_step = simplify_binary_operation (code, inner_mode, step0, step1);
2923 4709 : if (!new_step)
2924 : return NULL_RTX;
2925 :
2926 4709 : return gen_vec_series (mode, new_base, new_step);
2927 : }
2928 :
2929 : /* Subroutine of simplify_binary_operation_1. Un-distribute a binary
2930 : operation CODE with result mode MODE, operating on OP0 and OP1.
2931 : e.g. simplify (xor (and A C) (and (B C)) to (and (xor (A B) C).
2932 : Returns NULL_RTX if no simplification is possible. */
2933 :
2934 : rtx
2935 1333373 : simplify_context::simplify_distributive_operation (rtx_code code,
2936 : machine_mode mode,
2937 : rtx op0, rtx op1)
2938 : {
2939 1333373 : enum rtx_code op = GET_CODE (op0);
2940 1333373 : gcc_assert (GET_CODE (op1) == op);
2941 :
2942 1333373 : if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))
2943 1333373 : && ! side_effects_p (XEXP (op0, 1)))
2944 338550 : return simplify_gen_binary (op, mode,
2945 : simplify_gen_binary (code, mode,
2946 : XEXP (op0, 0),
2947 : XEXP (op1, 0)),
2948 338550 : XEXP (op0, 1));
2949 :
2950 994823 : if (GET_RTX_CLASS (op) == RTX_COMM_ARITH)
2951 : {
2952 977732 : if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2953 977732 : && ! side_effects_p (XEXP (op0, 0)))
2954 482341 : return simplify_gen_binary (op, mode,
2955 : simplify_gen_binary (code, mode,
2956 : XEXP (op0, 1),
2957 : XEXP (op1, 1)),
2958 482341 : XEXP (op0, 0));
2959 495391 : if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 1))
2960 495391 : && ! side_effects_p (XEXP (op0, 0)))
2961 54 : return simplify_gen_binary (op, mode,
2962 : simplify_gen_binary (code, mode,
2963 : XEXP (op0, 1),
2964 : XEXP (op1, 0)),
2965 54 : XEXP (op0, 0));
2966 495337 : if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 0))
2967 495337 : && ! side_effects_p (XEXP (op0, 1)))
2968 249617 : return simplify_gen_binary (op, mode,
2969 : simplify_gen_binary (code, mode,
2970 : XEXP (op0, 0),
2971 : XEXP (op1, 1)),
2972 249617 : XEXP (op0, 1));
2973 : }
2974 :
2975 : return NULL_RTX;
2976 : }
2977 :
2978 : /* Return TRUE if a rotate in mode MODE with a constant count in OP1
2979 : should be reversed.
2980 :
2981 : If the rotate should not be reversed, return FALSE.
2982 :
2983 : LEFT indicates if this is a rotate left or a rotate right. */
2984 :
2985 : bool
2986 147816 : reverse_rotate_by_imm_p (machine_mode mode, unsigned int left, rtx op1)
2987 : {
2988 147816 : if (!CONST_INT_P (op1))
2989 : return false;
2990 :
2991 : /* Some targets may only be able to rotate by a constant
2992 : in one direction. So we need to query the optab interface
2993 : to see what is possible. */
2994 110615 : optab binoptab = left ? rotl_optab : rotr_optab;
2995 48552 : optab re_binoptab = left ? rotr_optab : rotl_optab;
2996 110615 : enum insn_code icode = optab_handler (binoptab, mode);
2997 110615 : enum insn_code re_icode = optab_handler (re_binoptab, mode);
2998 :
2999 : /* If the target can not support the reversed optab, then there
3000 : is nothing to do. */
3001 110615 : if (re_icode == CODE_FOR_nothing)
3002 : return false;
3003 :
3004 : /* If the target does not support the requested rotate-by-immediate,
3005 : then we want to try reversing the rotate. We also want to try
3006 : reversing to minimize the count. */
3007 108133 : if ((icode == CODE_FOR_nothing)
3008 108133 : || (!insn_operand_matches (icode, 2, op1))
3009 540665 : || (IN_RANGE (INTVAL (op1),
3010 : GET_MODE_UNIT_PRECISION (mode) / 2 + left,
3011 : GET_MODE_UNIT_PRECISION (mode) - 1)))
3012 15493 : return (insn_operand_matches (re_icode, 2, op1));
3013 : return false;
3014 : }
3015 :
3016 : /* Analyse argument X to see if it represents an (ASHIFT X Y) operation
3017 : and return the expression to be shifted in SHIFT_OPND and the shift amount
3018 : in SHIFT_AMNT. This is primarily used to group handling of ASHIFT (X, CST)
3019 : and (PLUS (X, X)) in one place. If the expression is not equivalent to an
3020 : ASHIFT then return FALSE and set SHIFT_OPND and SHIFT_AMNT to NULL. */
3021 :
3022 : static bool
3023 535433143 : extract_ashift_operands_p (rtx x, rtx *shift_opnd, rtx *shift_amnt)
3024 : {
3025 535433143 : if (GET_CODE (x) == ASHIFT)
3026 : {
3027 13683334 : *shift_opnd = XEXP (x, 0);
3028 13683334 : *shift_amnt = XEXP (x, 1);
3029 13683334 : return true;
3030 : }
3031 521749809 : if (GET_CODE (x) == PLUS && rtx_equal_p (XEXP (x, 0), XEXP (x, 1)))
3032 : {
3033 11715 : *shift_opnd = XEXP (x, 0);
3034 11715 : *shift_amnt = CONST1_RTX (GET_MODE (x));
3035 11715 : return true;
3036 : }
3037 521738094 : *shift_opnd = NULL_RTX;
3038 521738094 : *shift_amnt = NULL_RTX;
3039 521738094 : return false;
3040 : }
3041 :
3042 : /* OP0 and OP1 are combined under an operation of mode MODE that can
3043 : potentially result in a ROTATE expression. Analyze the OP0 and OP1
3044 : and return the resulting ROTATE expression if so. Return NULL otherwise.
3045 : This is used in detecting the patterns (X << C1) [+,|,^] (X >> C2) where
3046 : C1 + C2 == GET_MODE_UNIT_PRECISION (mode).
3047 : (X << C1) and (C >> C2) would be OP0 and OP1. */
3048 :
3049 : static rtx
3050 270494019 : simplify_rotate_op (rtx op0, rtx op1, machine_mode mode)
3051 : {
3052 : /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3053 : mode size to (rotate A CX). */
3054 :
3055 270494019 : rtx opleft = op0;
3056 270494019 : rtx opright = op1;
3057 270494019 : rtx ashift_opnd, ashift_amnt;
3058 : /* In some cases the ASHIFT is not a direct ASHIFT. Look deeper and extract
3059 : the relevant operands here. */
3060 270494019 : bool ashift_op_p
3061 270494019 : = extract_ashift_operands_p (op1, &ashift_opnd, &ashift_amnt);
3062 :
3063 270494019 : if (ashift_op_p
3064 268839124 : || GET_CODE (op1) == SUBREG)
3065 : {
3066 : opleft = op1;
3067 : opright = op0;
3068 : }
3069 : else
3070 : {
3071 264939124 : opright = op1;
3072 264939124 : opleft = op0;
3073 264939124 : ashift_op_p
3074 264939124 : = extract_ashift_operands_p (opleft, &ashift_opnd, &ashift_amnt);
3075 : }
3076 :
3077 13695049 : if (ashift_op_p && GET_CODE (opright) == LSHIFTRT
3078 268877036 : && rtx_equal_p (ashift_opnd, XEXP (opright, 0)))
3079 : {
3080 9447 : rtx leftcst = unwrap_const_vec_duplicate (ashift_amnt);
3081 9447 : rtx rightcst = unwrap_const_vec_duplicate (XEXP (opright, 1));
3082 :
3083 5635 : if (CONST_INT_P (leftcst) && CONST_INT_P (rightcst)
3084 15082 : && (INTVAL (leftcst) + INTVAL (rightcst)
3085 5635 : == GET_MODE_UNIT_PRECISION (mode)))
3086 5108 : return gen_rtx_ROTATE (mode, XEXP (opright, 0), ashift_amnt);
3087 : }
3088 :
3089 : /* Same, but for ashift that has been "simplified" to a wider mode
3090 : by simplify_shift_const. */
3091 270488911 : scalar_int_mode int_mode, inner_mode;
3092 :
3093 270488911 : if (GET_CODE (opleft) == SUBREG
3094 275992736 : && is_a <scalar_int_mode> (mode, &int_mode)
3095 5498717 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (opleft)),
3096 : &inner_mode)
3097 5461779 : && GET_CODE (SUBREG_REG (opleft)) == ASHIFT
3098 181153 : && GET_CODE (opright) == LSHIFTRT
3099 1104 : && GET_CODE (XEXP (opright, 0)) == SUBREG
3100 237 : && known_eq (SUBREG_BYTE (opleft), SUBREG_BYTE (XEXP (opright, 0)))
3101 470 : && GET_MODE_SIZE (int_mode) < GET_MODE_SIZE (inner_mode)
3102 221 : && rtx_equal_p (XEXP (SUBREG_REG (opleft), 0),
3103 221 : SUBREG_REG (XEXP (opright, 0)))
3104 5 : && CONST_INT_P (XEXP (SUBREG_REG (opleft), 1))
3105 5 : && CONST_INT_P (XEXP (opright, 1))
3106 270488911 : && (INTVAL (XEXP (SUBREG_REG (opleft), 1))
3107 5 : + INTVAL (XEXP (opright, 1))
3108 5 : == GET_MODE_PRECISION (int_mode)))
3109 1 : return gen_rtx_ROTATE (int_mode, XEXP (opright, 0),
3110 : XEXP (SUBREG_REG (opleft), 1));
3111 : return NULL_RTX;
3112 : }
3113 :
3114 : /* Returns true if OP0 and OP1 match the pattern (OP (plus (A - 1)) (neg A)),
3115 : and the pattern can be simplified (there are no side effects). */
3116 :
3117 : static bool
3118 39238683 : match_plus_neg_pattern (rtx op0, rtx op1, machine_mode mode)
3119 : {
3120 : /* Remove SUBREG from OP0 and OP1, if needed. */
3121 39238683 : if (GET_CODE (op0) == SUBREG
3122 7129979 : && GET_CODE (op1) == SUBREG
3123 303822 : && subreg_lowpart_p (op0)
3124 39541101 : && subreg_lowpart_p (op1))
3125 : {
3126 302409 : op0 = XEXP (op0, 0);
3127 302409 : op1 = XEXP (op1, 0);
3128 : }
3129 :
3130 : /* Check for the pattern (OP (plus (A - 1)) (neg A)). */
3131 39238683 : if (((GET_CODE (op1) == NEG
3132 3770 : && GET_CODE (op0) == PLUS
3133 2241 : && XEXP (op0, 1) == CONSTM1_RTX (mode))
3134 39237993 : || (GET_CODE (op0) == NEG
3135 80440 : && GET_CODE (op1) == PLUS
3136 0 : && XEXP (op1, 1) == CONSTM1_RTX (mode)))
3137 690 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3138 39238685 : && !side_effects_p (XEXP (op0, 0)))
3139 : return true;
3140 : return false;
3141 : }
3142 :
3143 : /* Check if OP matches the pattern of (subreg (not X)) and the subreg is
3144 : non-paradoxical. */
3145 :
3146 : static bool
3147 74323936 : non_paradoxical_subreg_not_p (rtx op)
3148 : {
3149 74323936 : return GET_CODE (op) == SUBREG
3150 8673793 : && !paradoxical_subreg_p (op)
3151 77067501 : && GET_CODE (SUBREG_REG (op)) == NOT;
3152 : }
3153 :
3154 : /* Convert (binop (subreg (not X)) Y) into (binop (not (subreg X)) Y), or
3155 : (binop X (subreg (not Y))) into (binop X (not (subreg Y))) to expose
3156 : opportunities to combine another binary logical operation with NOT. */
3157 :
3158 : static rtx
3159 37163148 : simplify_with_subreg_not (rtx_code binop, machine_mode mode, rtx op0, rtx op1)
3160 : {
3161 37163148 : rtx opn = NULL_RTX;
3162 37163148 : if (non_paradoxical_subreg_not_p (op0))
3163 : opn = op0;
3164 37160788 : else if (non_paradoxical_subreg_not_p (op1))
3165 : opn = op1;
3166 :
3167 2383 : if (opn == NULL_RTX)
3168 : return NULL_RTX;
3169 :
3170 4766 : rtx new_subreg = simplify_gen_subreg (mode,
3171 : XEXP (SUBREG_REG (opn), 0),
3172 2383 : GET_MODE (SUBREG_REG (opn)),
3173 2383 : SUBREG_BYTE (opn));
3174 :
3175 2383 : if (!new_subreg)
3176 : return NULL_RTX;
3177 :
3178 2328 : rtx new_not = simplify_gen_unary (NOT, mode, new_subreg, mode);
3179 2328 : if (opn == op0)
3180 2305 : return simplify_gen_binary (binop, mode, new_not, op1);
3181 : else
3182 23 : return simplify_gen_binary (binop, mode, op0, new_not);
3183 : }
3184 :
3185 : /* Return TRUE iff NOP is a negated form of OP, or vice-versa. */
3186 : static bool
3187 6709151 : negated_ops_p (rtx nop, rtx op)
3188 : {
3189 : /* Explicit negation. */
3190 6709151 : if (GET_CODE (nop) == NOT
3191 6709151 : && rtx_equal_p (XEXP (nop, 0), op))
3192 : return true;
3193 6706040 : if (GET_CODE (op) == NOT
3194 6706040 : && rtx_equal_p (XEXP (op, 0), nop))
3195 : return true;
3196 :
3197 : /* (~C <r A) is a negated form of (C << A) if C == 1. */
3198 6703096 : if (GET_CODE (op) == ASHIFT
3199 1418430 : && GET_CODE (nop) == ROTATE
3200 0 : && XEXP (op, 0) == CONST1_RTX (GET_MODE (op))
3201 0 : && CONST_INT_P (XEXP (nop, 0))
3202 0 : && INTVAL (XEXP (nop, 0)) == -2
3203 6703096 : && rtx_equal_p (XEXP (op, 1), XEXP (nop, 1)))
3204 : return true;
3205 6703096 : if (GET_CODE (nop) == ASHIFT
3206 146363 : && GET_CODE (op) == ROTATE
3207 0 : && XEXP (nop, 0) == CONST1_RTX (GET_MODE (op))
3208 0 : && CONST_INT_P (XEXP (nop, 0))
3209 0 : && INTVAL (XEXP (nop, 0)) == -2
3210 6703096 : && rtx_equal_p (XEXP (op, 1), XEXP (nop, 1)))
3211 : return true;
3212 :
3213 : /* ??? Should we consider rotations of C and ~C by the same amount? */
3214 :
3215 : return false;
3216 : }
3217 :
3218 : /* Subroutine of simplify_binary_operation. Simplify a binary operation
3219 : CODE with result mode MODE, operating on OP0 and OP1. If OP0 and/or
3220 : OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the
3221 : actual constants. */
3222 :
3223 : rtx
3224 455504172 : simplify_context::simplify_binary_operation_1 (rtx_code code,
3225 : machine_mode mode,
3226 : rtx op0, rtx op1,
3227 : rtx trueop0, rtx trueop1)
3228 : {
3229 455504172 : rtx tem, reversed, elt0, elt1;
3230 455504172 : HOST_WIDE_INT val;
3231 455504172 : scalar_int_mode int_mode, inner_mode;
3232 455504172 : poly_int64 offset;
3233 :
3234 : /* Even if we can't compute a constant result,
3235 : there are some cases worth simplifying. */
3236 :
3237 455504172 : switch (code)
3238 : {
3239 260230339 : case PLUS:
3240 : /* Maybe simplify x + 0 to x. The two expressions are equivalent
3241 : when x is NaN, infinite, or finite and nonzero. They aren't
3242 : when x is -0 and the rounding mode is not towards -infinity,
3243 : since (-0) + 0 is then 0. */
3244 516545698 : if (!HONOR_SIGNED_ZEROS (mode) && !HONOR_SNANS (mode)
3245 516545686 : && trueop1 == CONST0_RTX (mode))
3246 : return op0;
3247 :
3248 : /* ((-a) + b) -> (b - a) and similarly for (a + (-b)). These
3249 : transformations are safe even for IEEE. */
3250 258726616 : if (GET_CODE (op0) == NEG)
3251 65329 : return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
3252 258661287 : else if (GET_CODE (op1) == NEG)
3253 7796 : return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
3254 :
3255 : /* (~a) + 1 -> -a */
3256 258653491 : if (INTEGRAL_MODE_P (mode)
3257 253833118 : && GET_CODE (op0) == NOT
3258 1366447 : && trueop1 == const1_rtx)
3259 3842 : return simplify_gen_unary (NEG, mode, XEXP (op0, 0), mode);
3260 :
3261 : /* Handle both-operands-constant cases. We can only add
3262 : CONST_INTs to constants since the sum of relocatable symbols
3263 : can't be handled by most assemblers. Don't add CONST_INT
3264 : to CONST_INT since overflow won't be computed properly if wider
3265 : than HOST_BITS_PER_WIDE_INT. */
3266 :
3267 258649649 : if ((GET_CODE (op0) == CONST
3268 258649649 : || GET_CODE (op0) == SYMBOL_REF
3269 256045166 : || GET_CODE (op0) == LABEL_REF)
3270 258649649 : && poly_int_rtx_p (op1, &offset))
3271 2603509 : return plus_constant (mode, op0, offset);
3272 256046140 : else if ((GET_CODE (op1) == CONST
3273 256046140 : || GET_CODE (op1) == SYMBOL_REF
3274 251793012 : || GET_CODE (op1) == LABEL_REF)
3275 256046140 : && poly_int_rtx_p (op0, &offset))
3276 0 : return plus_constant (mode, op1, offset);
3277 :
3278 : /* See if this is something like X * C - X or vice versa or
3279 : if the multiplication is written as a shift. If so, we can
3280 : distribute and make a new multiply, shift, or maybe just
3281 : have X (if C is 2 in the example above). But don't make
3282 : something more expensive than we had before. */
3283 :
3284 256046140 : if (is_a <scalar_int_mode> (mode, &int_mode))
3285 : {
3286 249051711 : rtx lhs = op0, rhs = op1;
3287 :
3288 249051711 : wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
3289 249051711 : wide_int coeff1 = wi::one (GET_MODE_PRECISION (int_mode));
3290 :
3291 249051711 : if (GET_CODE (lhs) == NEG)
3292 : {
3293 0 : coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3294 0 : lhs = XEXP (lhs, 0);
3295 : }
3296 249051711 : else if (GET_CODE (lhs) == MULT
3297 9820404 : && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
3298 : {
3299 8581679 : coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
3300 8581679 : lhs = XEXP (lhs, 0);
3301 : }
3302 240470032 : else if (GET_CODE (lhs) == ASHIFT
3303 10975425 : && CONST_INT_P (XEXP (lhs, 1))
3304 10903284 : && INTVAL (XEXP (lhs, 1)) >= 0
3305 251373304 : && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
3306 : {
3307 10903272 : coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
3308 21806544 : GET_MODE_PRECISION (int_mode));
3309 10903272 : lhs = XEXP (lhs, 0);
3310 : }
3311 :
3312 249051711 : if (GET_CODE (rhs) == NEG)
3313 : {
3314 0 : coeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3315 0 : rhs = XEXP (rhs, 0);
3316 : }
3317 249051711 : else if (GET_CODE (rhs) == MULT
3318 346994 : && CONST_INT_P (XEXP (rhs, 1)))
3319 : {
3320 194737 : coeff1 = rtx_mode_t (XEXP (rhs, 1), int_mode);
3321 194737 : rhs = XEXP (rhs, 0);
3322 : }
3323 248856974 : else if (GET_CODE (rhs) == ASHIFT
3324 550909 : && CONST_INT_P (XEXP (rhs, 1))
3325 541138 : && INTVAL (XEXP (rhs, 1)) >= 0
3326 249398112 : && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
3327 : {
3328 541138 : coeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
3329 1082276 : GET_MODE_PRECISION (int_mode));
3330 541138 : rhs = XEXP (rhs, 0);
3331 : }
3332 :
3333 : /* Keep PLUS of 2 volatile memory references. */
3334 249051711 : if (rtx_equal_p (lhs, rhs)
3335 249051711 : && (!MEM_P (lhs) || !MEM_VOLATILE_P (lhs)))
3336 : {
3337 814906 : rtx orig = gen_rtx_PLUS (int_mode, op0, op1);
3338 814906 : rtx coeff;
3339 814906 : bool speed = optimize_function_for_speed_p (cfun);
3340 :
3341 814906 : coeff = immed_wide_int_const (coeff0 + coeff1, int_mode);
3342 :
3343 814906 : tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
3344 814906 : return (set_src_cost (tem, int_mode, speed)
3345 814906 : <= set_src_cost (orig, int_mode, speed) ? tem : 0);
3346 : }
3347 :
3348 : /* Optimize (X - 1) * Y + Y to X * Y. */
3349 248236805 : lhs = op0;
3350 248236805 : rhs = op1;
3351 248236805 : if (GET_CODE (op0) == MULT)
3352 : {
3353 9768632 : if (((GET_CODE (XEXP (op0, 0)) == PLUS
3354 625345 : && XEXP (XEXP (op0, 0), 1) == constm1_rtx)
3355 9727131 : || (GET_CODE (XEXP (op0, 0)) == MINUS
3356 53086 : && XEXP (XEXP (op0, 0), 1) == const1_rtx))
3357 9810133 : && rtx_equal_p (XEXP (op0, 1), op1))
3358 86 : lhs = XEXP (XEXP (op0, 0), 0);
3359 9768546 : else if (((GET_CODE (XEXP (op0, 1)) == PLUS
3360 1777 : && XEXP (XEXP (op0, 1), 1) == constm1_rtx)
3361 9768488 : || (GET_CODE (XEXP (op0, 1)) == MINUS
3362 339 : && XEXP (XEXP (op0, 1), 1) == const1_rtx))
3363 9768604 : && rtx_equal_p (XEXP (op0, 0), op1))
3364 0 : lhs = XEXP (XEXP (op0, 1), 0);
3365 : }
3366 238468173 : else if (GET_CODE (op1) == MULT)
3367 : {
3368 124306 : if (((GET_CODE (XEXP (op1, 0)) == PLUS
3369 93 : && XEXP (XEXP (op1, 0), 1) == constm1_rtx)
3370 124300 : || (GET_CODE (XEXP (op1, 0)) == MINUS
3371 27 : && XEXP (XEXP (op1, 0), 1) == const1_rtx))
3372 124312 : && rtx_equal_p (XEXP (op1, 1), op0))
3373 0 : rhs = XEXP (XEXP (op1, 0), 0);
3374 124306 : else if (((GET_CODE (XEXP (op1, 1)) == PLUS
3375 45 : && XEXP (XEXP (op1, 1), 1) == constm1_rtx)
3376 124306 : || (GET_CODE (XEXP (op1, 1)) == MINUS
3377 0 : && XEXP (XEXP (op1, 1), 1) == const1_rtx))
3378 124306 : && rtx_equal_p (XEXP (op1, 0), op0))
3379 0 : rhs = XEXP (XEXP (op1, 1), 0);
3380 : }
3381 248236805 : if (lhs != op0 || rhs != op1)
3382 86 : return simplify_gen_binary (MULT, int_mode, lhs, rhs);
3383 249051711 : }
3384 :
3385 : /* (plus (xor X C1) C2) is (xor X (C1^C2)) if C2 is signbit. */
3386 255231148 : if (CONST_SCALAR_INT_P (op1)
3387 194633866 : && GET_CODE (op0) == XOR
3388 18767 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
3389 255241607 : && mode_signbit_p (mode, op1))
3390 121 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3391 : simplify_gen_binary (XOR, mode, op1,
3392 121 : XEXP (op0, 1)));
3393 :
3394 : /* (plus (xor X C1) C2) is (xor X (C1^C2)) if X is either 0 or 1 and
3395 : 2 * ((X ^ C1) & C2) == 0; based on A + B == A ^ B + 2 * (A & B). */
3396 255231027 : if (CONST_SCALAR_INT_P (op1)
3397 194633745 : && GET_CODE (op0) == XOR
3398 18646 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
3399 10338 : && nonzero_bits (XEXP (op0, 0), mode) == 1
3400 189 : && 2 * (INTVAL (XEXP (op0, 1)) & INTVAL (op1)) == 0
3401 255231027 : && 2 * ((1 ^ INTVAL (XEXP (op0, 1))) & INTVAL (op1)) == 0)
3402 0 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3403 : simplify_gen_binary (XOR, mode, op1,
3404 0 : XEXP (op0, 1)));
3405 :
3406 : /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)). */
3407 255231027 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3408 255228499 : && GET_CODE (op0) == MULT
3409 265371532 : && GET_CODE (XEXP (op0, 0)) == NEG)
3410 : {
3411 5486 : rtx in1, in2;
3412 :
3413 5486 : in1 = XEXP (XEXP (op0, 0), 0);
3414 5486 : in2 = XEXP (op0, 1);
3415 5486 : return simplify_gen_binary (MINUS, mode, op1,
3416 : simplify_gen_binary (MULT, mode,
3417 5486 : in1, in2));
3418 : }
3419 :
3420 : /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
3421 : C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
3422 : is 1. */
3423 255225541 : if (COMPARISON_P (op0)
3424 1260236 : && ((STORE_FLAG_VALUE == -1 && trueop1 == const1_rtx)
3425 1260236 : || (STORE_FLAG_VALUE == 1 && trueop1 == constm1_rtx))
3426 255282335 : && (reversed = reversed_comparison (op0, mode)))
3427 56447 : return
3428 56447 : simplify_gen_unary (NEG, mode, reversed, mode);
3429 :
3430 : /* Convert (plus (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3431 : mode size to (rotate A CX). */
3432 255169094 : if ((tem = simplify_rotate_op (op0, op1, mode)))
3433 : return tem;
3434 :
3435 : /* If one of the operands is a PLUS or a MINUS, see if we can
3436 : simplify this by the associative law.
3437 : Don't use the associative law for floating point.
3438 : The inaccuracy makes it nonassociative,
3439 : and subtle programs can break if operations are associated. */
3440 :
3441 255167624 : if (INTEGRAL_MODE_P (mode)
3442 250347300 : && (plus_minus_operand_p (op0)
3443 216315937 : || plus_minus_operand_p (op1))
3444 35109264 : && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
3445 : return tem;
3446 :
3447 : /* Reassociate floating point addition only when the user
3448 : specifies associative math operations. */
3449 220763166 : if (FLOAT_MODE_P (mode)
3450 4820324 : && flag_associative_math)
3451 : {
3452 905343 : tem = simplify_associative_operation (code, mode, op0, op1);
3453 905343 : if (tem)
3454 : return tem;
3455 : }
3456 :
3457 : /* Handle vector series. */
3458 220749418 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3459 : {
3460 2007905 : tem = simplify_binary_operation_series (code, mode, op0, op1);
3461 2007905 : if (tem)
3462 : return tem;
3463 : }
3464 : break;
3465 :
3466 : case COMPARE:
3467 : break;
3468 :
3469 45127763 : case MINUS:
3470 : /* We can't assume x-x is 0 even with non-IEEE floating point,
3471 : but since it is zero except in very strange circumstances, we
3472 : will treat it as zero with -ffinite-math-only. */
3473 45127763 : if (rtx_equal_p (trueop0, trueop1)
3474 221877 : && ! side_effects_p (op0)
3475 45348393 : && (!FLOAT_MODE_P (mode) || !HONOR_NANS (mode)))
3476 217938 : return CONST0_RTX (mode);
3477 :
3478 : /* Change subtraction from zero into negation. (0 - x) is the
3479 : same as -x when x is NaN, infinite, or finite and nonzero.
3480 : But if the mode has signed zeros, and does not round towards
3481 : -infinity, then 0 - 0 is 0, not -0. */
3482 44909825 : if (!HONOR_SIGNED_ZEROS (mode) && trueop0 == CONST0_RTX (mode))
3483 352100 : return simplify_gen_unary (NEG, mode, op1, mode);
3484 :
3485 : /* (-1 - a) is ~a, unless the expression contains symbolic
3486 : constants, in which case not retaining additions and
3487 : subtractions could cause invalid assembly to be produced. */
3488 44557725 : if (trueop0 == CONSTM1_RTX (mode)
3489 44557725 : && !contains_symbolic_reference_p (op1))
3490 608505 : return simplify_gen_unary (NOT, mode, op1, mode);
3491 :
3492 : /* Subtracting 0 has no effect unless the mode has signalling NaNs,
3493 : or has signed zeros and supports rounding towards -infinity.
3494 : In such a case, 0 - 0 is -0. */
3495 44686981 : if (!(HONOR_SIGNED_ZEROS (mode)
3496 737761 : && HONOR_SIGN_DEPENDENT_ROUNDING (mode))
3497 43948070 : && !HONOR_SNANS (mode)
3498 87897254 : && trueop1 == CONST0_RTX (mode))
3499 : return op0;
3500 :
3501 : /* See if this is something like X * C - X or vice versa or
3502 : if the multiplication is written as a shift. If so, we can
3503 : distribute and make a new multiply, shift, or maybe just
3504 : have X (if C is 2 in the example above). But don't make
3505 : something more expensive than we had before. */
3506 :
3507 43008082 : if (is_a <scalar_int_mode> (mode, &int_mode))
3508 : {
3509 41620574 : rtx lhs = op0, rhs = op1;
3510 :
3511 41620574 : wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
3512 41620574 : wide_int negcoeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3513 :
3514 41620574 : if (GET_CODE (lhs) == NEG)
3515 : {
3516 70063 : coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3517 70063 : lhs = XEXP (lhs, 0);
3518 : }
3519 41550511 : else if (GET_CODE (lhs) == MULT
3520 194953 : && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
3521 : {
3522 71432 : coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
3523 71432 : lhs = XEXP (lhs, 0);
3524 : }
3525 41479079 : else if (GET_CODE (lhs) == ASHIFT
3526 325344 : && CONST_INT_P (XEXP (lhs, 1))
3527 322087 : && INTVAL (XEXP (lhs, 1)) >= 0
3528 41801145 : && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
3529 : {
3530 322066 : coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
3531 644132 : GET_MODE_PRECISION (int_mode));
3532 322066 : lhs = XEXP (lhs, 0);
3533 : }
3534 :
3535 41620574 : if (GET_CODE (rhs) == NEG)
3536 : {
3537 11293 : negcoeff1 = wi::one (GET_MODE_PRECISION (int_mode));
3538 11293 : rhs = XEXP (rhs, 0);
3539 : }
3540 41609281 : else if (GET_CODE (rhs) == MULT
3541 156667 : && CONST_INT_P (XEXP (rhs, 1)))
3542 : {
3543 100502 : negcoeff1 = wi::neg (rtx_mode_t (XEXP (rhs, 1), int_mode));
3544 100502 : rhs = XEXP (rhs, 0);
3545 : }
3546 41508779 : else if (GET_CODE (rhs) == ASHIFT
3547 386073 : && CONST_INT_P (XEXP (rhs, 1))
3548 385566 : && INTVAL (XEXP (rhs, 1)) >= 0
3549 41894345 : && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
3550 : {
3551 385566 : negcoeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
3552 771132 : GET_MODE_PRECISION (int_mode));
3553 385566 : negcoeff1 = -negcoeff1;
3554 385566 : rhs = XEXP (rhs, 0);
3555 : }
3556 :
3557 41620574 : if (rtx_equal_p (lhs, rhs))
3558 : {
3559 101833 : rtx orig = gen_rtx_MINUS (int_mode, op0, op1);
3560 101833 : rtx coeff;
3561 101833 : bool speed = optimize_function_for_speed_p (cfun);
3562 :
3563 101833 : coeff = immed_wide_int_const (coeff0 + negcoeff1, int_mode);
3564 :
3565 101833 : tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
3566 101833 : return (set_src_cost (tem, int_mode, speed)
3567 101833 : <= set_src_cost (orig, int_mode, speed) ? tem : 0);
3568 : }
3569 :
3570 : /* Optimize (X + 1) * Y - Y to X * Y. */
3571 41518741 : lhs = op0;
3572 41518741 : if (GET_CODE (op0) == MULT)
3573 : {
3574 194480 : if (((GET_CODE (XEXP (op0, 0)) == PLUS
3575 4854 : && XEXP (XEXP (op0, 0), 1) == const1_rtx)
3576 192929 : || (GET_CODE (XEXP (op0, 0)) == MINUS
3577 1632 : && XEXP (XEXP (op0, 0), 1) == constm1_rtx))
3578 196031 : && rtx_equal_p (XEXP (op0, 1), op1))
3579 2 : lhs = XEXP (XEXP (op0, 0), 0);
3580 194478 : else if (((GET_CODE (XEXP (op0, 1)) == PLUS
3581 30 : && XEXP (XEXP (op0, 1), 1) == const1_rtx)
3582 194472 : || (GET_CODE (XEXP (op0, 1)) == MINUS
3583 84 : && XEXP (XEXP (op0, 1), 1) == constm1_rtx))
3584 194484 : && rtx_equal_p (XEXP (op0, 0), op1))
3585 0 : lhs = XEXP (XEXP (op0, 1), 0);
3586 : }
3587 41518741 : if (lhs != op0)
3588 2 : return simplify_gen_binary (MULT, int_mode, lhs, op1);
3589 41620574 : }
3590 :
3591 : /* (a - (-b)) -> (a + b). True even for IEEE. */
3592 42906247 : if (GET_CODE (op1) == NEG)
3593 11255 : return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
3594 :
3595 : /* (-x - c) may be simplified as (-c - x). */
3596 42894992 : if (GET_CODE (op0) == NEG
3597 74192 : && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1)))
3598 : {
3599 718 : tem = simplify_unary_operation (NEG, mode, op1, mode);
3600 718 : if (tem)
3601 718 : return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
3602 : }
3603 :
3604 42894274 : if ((GET_CODE (op0) == CONST
3605 42894274 : || GET_CODE (op0) == SYMBOL_REF
3606 37482627 : || GET_CODE (op0) == LABEL_REF)
3607 42894274 : && poly_int_rtx_p (op1, &offset))
3608 53821 : return plus_constant (mode, op0, trunc_int_for_mode (-offset, mode));
3609 :
3610 : /* Don't let a relocatable value get a negative coeff. */
3611 42840453 : if (is_a <scalar_int_mode> (mode)
3612 41452976 : && poly_int_rtx_p (op1)
3613 49983832 : && GET_MODE (op0) != VOIDmode)
3614 7143379 : return simplify_gen_binary (PLUS, mode,
3615 : op0,
3616 7143379 : neg_poly_int_rtx (mode, op1));
3617 :
3618 : /* (x - (x & y)) -> (x & ~y) */
3619 35697074 : if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND)
3620 : {
3621 263275 : if (rtx_equal_p (op0, XEXP (op1, 0)))
3622 : {
3623 482 : tem = simplify_gen_unary (NOT, mode, XEXP (op1, 1),
3624 241 : GET_MODE (XEXP (op1, 1)));
3625 241 : return simplify_gen_binary (AND, mode, op0, tem);
3626 : }
3627 263034 : if (rtx_equal_p (op0, XEXP (op1, 1)))
3628 : {
3629 2286 : tem = simplify_gen_unary (NOT, mode, XEXP (op1, 0),
3630 1143 : GET_MODE (XEXP (op1, 0)));
3631 1143 : return simplify_gen_binary (AND, mode, op0, tem);
3632 : }
3633 : }
3634 :
3635 : /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
3636 : by reversing the comparison code if valid. */
3637 35695690 : if (STORE_FLAG_VALUE == 1
3638 35695690 : && trueop0 == const1_rtx
3639 1170580 : && COMPARISON_P (op1)
3640 35801592 : && (reversed = reversed_comparison (op1, mode)))
3641 : return reversed;
3642 :
3643 : /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A). */
3644 35589831 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3645 35588480 : && GET_CODE (op1) == MULT
3646 35847568 : && GET_CODE (XEXP (op1, 0)) == NEG)
3647 : {
3648 177 : rtx in1, in2;
3649 :
3650 177 : in1 = XEXP (XEXP (op1, 0), 0);
3651 177 : in2 = XEXP (op1, 1);
3652 177 : return simplify_gen_binary (PLUS, mode,
3653 : simplify_gen_binary (MULT, mode,
3654 : in1, in2),
3655 177 : op0);
3656 : }
3657 :
3658 : /* Canonicalize (minus (neg A) (mult B C)) to
3659 : (minus (mult (neg B) C) A). */
3660 35589654 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3661 35588303 : && GET_CODE (op1) == MULT
3662 35847214 : && GET_CODE (op0) == NEG)
3663 : {
3664 673 : rtx in1, in2;
3665 :
3666 673 : in1 = simplify_gen_unary (NEG, mode, XEXP (op1, 0), mode);
3667 673 : in2 = XEXP (op1, 1);
3668 673 : return simplify_gen_binary (MINUS, mode,
3669 : simplify_gen_binary (MULT, mode,
3670 : in1, in2),
3671 673 : XEXP (op0, 0));
3672 : }
3673 :
3674 : /* If one of the operands is a PLUS or a MINUS, see if we can
3675 : simplify this by the associative law. This will, for example,
3676 : canonicalize (minus A (plus B C)) to (minus (minus A B) C).
3677 : Don't use the associative law for floating point.
3678 : The inaccuracy makes it nonassociative,
3679 : and subtle programs can break if operations are associated. */
3680 :
3681 35588981 : if (INTEGRAL_MODE_P (mode)
3682 34730765 : && (plus_minus_operand_p (op0)
3683 31824539 : || plus_minus_operand_p (op1))
3684 4142530 : && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
3685 : return tem;
3686 :
3687 : /* Handle vector series. */
3688 31597906 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3689 : {
3690 506013 : tem = simplify_binary_operation_series (code, mode, op0, op1);
3691 506013 : if (tem)
3692 : return tem;
3693 : }
3694 : break;
3695 :
3696 12615261 : case MULT:
3697 12615261 : if (trueop1 == constm1_rtx)
3698 34108 : return simplify_gen_unary (NEG, mode, op0, mode);
3699 :
3700 12581153 : if (GET_CODE (op0) == NEG)
3701 : {
3702 41057 : rtx temp = simplify_unary_operation (NEG, mode, op1, mode);
3703 : /* If op1 is a MULT as well and simplify_unary_operation
3704 : just moved the NEG to the second operand, simplify_gen_binary
3705 : below could through simplify_associative_operation move
3706 : the NEG around again and recurse endlessly. */
3707 41057 : if (temp
3708 1981 : && GET_CODE (op1) == MULT
3709 0 : && GET_CODE (temp) == MULT
3710 0 : && XEXP (op1, 0) == XEXP (temp, 0)
3711 0 : && GET_CODE (XEXP (temp, 1)) == NEG
3712 0 : && XEXP (op1, 1) == XEXP (XEXP (temp, 1), 0))
3713 : temp = NULL_RTX;
3714 : if (temp)
3715 1981 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp);
3716 : }
3717 12579172 : if (GET_CODE (op1) == NEG)
3718 : {
3719 908 : rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
3720 : /* If op0 is a MULT as well and simplify_unary_operation
3721 : just moved the NEG to the second operand, simplify_gen_binary
3722 : below could through simplify_associative_operation move
3723 : the NEG around again and recurse endlessly. */
3724 908 : if (temp
3725 430 : && GET_CODE (op0) == MULT
3726 318 : && GET_CODE (temp) == MULT
3727 318 : && XEXP (op0, 0) == XEXP (temp, 0)
3728 6 : && GET_CODE (XEXP (temp, 1)) == NEG
3729 5 : && XEXP (op0, 1) == XEXP (XEXP (temp, 1), 0))
3730 : temp = NULL_RTX;
3731 : if (temp)
3732 425 : return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
3733 : }
3734 :
3735 : /* Maybe simplify x * 0 to 0. The reduction is not valid if
3736 : x is NaN, since x * 0 is then also NaN. Nor is it valid
3737 : when the mode has signed zeros, since multiplying a negative
3738 : number by 0 will give -0, not 0. */
3739 12578747 : if (!HONOR_NANS (mode)
3740 11594786 : && !HONOR_SIGNED_ZEROS (mode)
3741 11594331 : && trueop1 == CONST0_RTX (mode)
3742 12620918 : && ! side_effects_p (op0))
3743 : return op1;
3744 :
3745 : /* In IEEE floating point, x*1 is not equivalent to x for
3746 : signalling NaNs. */
3747 12537825 : if (!HONOR_SNANS (mode)
3748 12537825 : && trueop1 == CONST1_RTX (mode))
3749 : return op0;
3750 :
3751 : /* Convert multiply by constant power of two into shift. */
3752 12016124 : if (mem_depth == 0 && CONST_SCALAR_INT_P (trueop1))
3753 : {
3754 6246270 : val = wi::exact_log2 (rtx_mode_t (trueop1, mode));
3755 6246270 : if (val >= 0)
3756 2940888 : return simplify_gen_binary (ASHIFT, mode, op0,
3757 2940888 : gen_int_shift_amount (mode, val));
3758 : }
3759 :
3760 : /* x*2 is x+x and x*(-1) is -x */
3761 9075236 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
3762 171385 : && SCALAR_FLOAT_MODE_P (GET_MODE (trueop1))
3763 171385 : && !DECIMAL_FLOAT_MODE_P (GET_MODE (trueop1))
3764 171101 : && GET_MODE (op0) == mode)
3765 : {
3766 171101 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
3767 :
3768 171101 : if (real_equal (d1, &dconst2))
3769 634 : return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
3770 :
3771 170467 : if (!HONOR_SNANS (mode)
3772 170467 : && real_equal (d1, &dconstm1))
3773 25 : return simplify_gen_unary (NEG, mode, op0, mode);
3774 : }
3775 :
3776 : /* Optimize -x * -x as x * x. */
3777 9074577 : if (FLOAT_MODE_P (mode)
3778 1403354 : && GET_CODE (op0) == NEG
3779 8373 : && GET_CODE (op1) == NEG
3780 0 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3781 0 : && !side_effects_p (XEXP (op0, 0)))
3782 0 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3783 :
3784 : /* Likewise, optimize abs(x) * abs(x) as x * x. */
3785 9074577 : if (SCALAR_FLOAT_MODE_P (mode)
3786 1111427 : && GET_CODE (op0) == ABS
3787 1335 : && GET_CODE (op1) == ABS
3788 0 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3789 9074577 : && !side_effects_p (XEXP (op0, 0)))
3790 0 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3791 :
3792 : /* Reassociate multiplication, but for floating point MULTs
3793 : only when the user specifies unsafe math optimizations. */
3794 9074577 : if (! FLOAT_MODE_P (mode)
3795 1403354 : || flag_unsafe_math_optimizations)
3796 : {
3797 8091738 : tem = simplify_associative_operation (code, mode, op0, op1);
3798 8091738 : if (tem)
3799 : return tem;
3800 : }
3801 : break;
3802 :
3803 15197909 : case IOR:
3804 15197909 : if (trueop1 == CONST0_RTX (mode))
3805 : return op0;
3806 14383553 : if (INTEGRAL_MODE_P (mode)
3807 14108068 : && trueop1 == CONSTM1_RTX (mode)
3808 9622 : && !side_effects_p (op0))
3809 : return op1;
3810 14373931 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
3811 : return op0;
3812 : /* A | (~A) -> -1 */
3813 76538 : if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
3814 14354417 : || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
3815 4 : && ! side_effects_p (op0)
3816 14354425 : && GET_MODE_CLASS (mode) != MODE_CC)
3817 4 : return CONSTM1_RTX (mode);
3818 :
3819 : /* IOR of two single bit bitfields extracted from the same object.
3820 : Bitfields are represented as an AND based extraction */
3821 14354417 : if (GET_CODE (op0) == AND
3822 4038873 : && GET_CODE (op1) == AND
3823 : /* Verify both AND operands are logical right shifts. */
3824 284812 : && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
3825 1599 : && GET_CODE (XEXP (op1, 0)) == LSHIFTRT
3826 : /* Verify both bitfields are extracted from the same object. */
3827 54 : && XEXP (XEXP (op0, 0), 0) == XEXP (XEXP (op1, 0), 0)
3828 : /* Verify both fields are a single bit (could be generalized). */
3829 54 : && XEXP (op0, 1) == CONST1_RTX (mode)
3830 0 : && XEXP (op1, 1) == CONST1_RTX (mode)
3831 : /* Verify bit positions (for cases with variable bit position). */
3832 0 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
3833 0 : && CONST_INT_P (XEXP (XEXP (op1, 0), 1)))
3834 : {
3835 0 : unsigned HOST_WIDE_INT bitpos1 = INTVAL (XEXP (XEXP (op0, 0), 1));
3836 0 : unsigned HOST_WIDE_INT bitpos2 = INTVAL (XEXP (XEXP (op1, 0), 1));
3837 0 : unsigned HOST_WIDE_INT mask
3838 0 : = (HOST_WIDE_INT_1U << bitpos1) | (HOST_WIDE_INT_1U << bitpos2);
3839 :
3840 0 : rtx m = GEN_INT (mask);
3841 0 : rtx t = gen_rtx_AND (mode, XEXP (XEXP (op0, 0), 0), m);
3842 0 : t = gen_rtx_NE (mode, t, CONST0_RTX (mode));
3843 0 : return t;
3844 : }
3845 :
3846 : /* IOR of multiple single bit bitfields extracted from the same object
3847 : (building on previous case).
3848 : First bitfield is represented as an AND based extraction, as done
3849 : above. Second represented as NE based extraction, from
3850 : output above. */
3851 14354417 : if (GET_CODE (op0) == AND
3852 4038873 : && GET_CODE (op1) == NE
3853 : /* Verify AND operand is logical right shift. */
3854 3281 : && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
3855 : /* Verify NE operand is an AND (based on output above). */
3856 86 : && GET_CODE (XEXP (op1, 0)) == AND
3857 : /* Verify both bitfields are extracted from the same object. */
3858 0 : && XEXP (XEXP (op0, 0), 0) == XEXP (XEXP (op1, 0), 0)
3859 : /* Verify masking is with a single bit and that we have a NE 0
3860 : comparison for the other operand. */
3861 0 : && XEXP (op0, 1) == CONST1_RTX (mode)
3862 0 : && XEXP (op1, 1) == CONST0_RTX (mode)
3863 : /* Verify bit position. */
3864 0 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
3865 : {
3866 0 : unsigned HOST_WIDE_INT bitpos1 = INTVAL (XEXP (XEXP (op0, 0), 1));
3867 0 : unsigned HOST_WIDE_INT mask
3868 0 : = (HOST_WIDE_INT_1U << bitpos1) | INTVAL (XEXP (XEXP (op1, 0), 1));
3869 :
3870 0 : rtx m = GEN_INT (mask);
3871 0 : rtx t = gen_rtx_AND (mode, XEXP (XEXP (op0, 0), 0), m);
3872 0 : t = gen_rtx_NE (mode, t, CONST0_RTX (mode));
3873 0 : return t;
3874 : }
3875 :
3876 : /* Convert (ior (plus (A - 1)) (neg A)) to -1. */
3877 14354417 : if (match_plus_neg_pattern (op0, op1, mode))
3878 0 : return CONSTM1_RTX (mode);
3879 :
3880 : /* (ior A C) is C if all bits of A that might be nonzero are on in C. */
3881 14354417 : if (CONST_INT_P (op1)
3882 3534876 : && HWI_COMPUTABLE_MODE_P (mode)
3883 3480500 : && (nonzero_bits (op0, mode) & ~UINTVAL (op1)) == 0
3884 14763128 : && !side_effects_p (op0))
3885 : return op1;
3886 :
3887 : /* Canonicalize (X & C1) | C2. */
3888 13945706 : if (GET_CODE (op0) == AND
3889 4030013 : && CONST_INT_P (trueop1)
3890 659153 : && CONST_INT_P (XEXP (op0, 1)))
3891 : {
3892 490788 : HOST_WIDE_INT mask = GET_MODE_MASK (mode);
3893 490788 : HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
3894 490788 : HOST_WIDE_INT c2 = INTVAL (trueop1);
3895 :
3896 : /* If (C1&C2) == C1, then (X&C1)|C2 becomes C2. */
3897 490788 : if ((c1 & c2) == c1
3898 490788 : && !side_effects_p (XEXP (op0, 0)))
3899 : return trueop1;
3900 :
3901 : /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2. */
3902 490768 : if (((c1|c2) & mask) == mask)
3903 71094 : return simplify_gen_binary (IOR, mode, XEXP (op0, 0), op1);
3904 :
3905 : /* If (C1|C2) has a single bit clear, then adjust C1 so that
3906 : when split it'll match a single bit clear style insn.
3907 :
3908 : This could have been done with a target dependent splitter, but
3909 : then every target with single bit manipulation insns would need
3910 : to implement such splitters. */
3911 419674 : if (exact_log2 (~(c1 | c2)) >= 0)
3912 : {
3913 61668 : rtx temp = gen_rtx_AND (mode, XEXP (op0, 0), GEN_INT (c1 | c2));
3914 61668 : temp = gen_rtx_IOR (mode, temp, trueop1);
3915 61668 : return temp;
3916 : }
3917 : }
3918 :
3919 : /* Convert (A & B) | A to A. */
3920 13812924 : if (GET_CODE (op0) == AND
3921 3897231 : && (rtx_equal_p (XEXP (op0, 0), op1)
3922 3897120 : || rtx_equal_p (XEXP (op0, 1), op1))
3923 3127 : && ! side_effects_p (XEXP (op0, 0))
3924 13816051 : && ! side_effects_p (XEXP (op0, 1)))
3925 : return op1;
3926 :
3927 : /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3928 : mode size to (rotate A CX). */
3929 13809797 : tem = simplify_rotate_op (op0, op1, mode);
3930 13809797 : if (tem)
3931 : return tem;
3932 :
3933 : /* If OP0 is (ashiftrt (plus ...) C), it might actually be
3934 : a (sign_extend (plus ...)). Then check if OP1 is a CONST_INT and
3935 : the PLUS does not affect any of the bits in OP1: then we can do
3936 : the IOR as a PLUS and we can associate. This is valid if OP1
3937 : can be safely shifted left C bits. */
3938 13807538 : if (CONST_INT_P (trueop1) && GET_CODE (op0) == ASHIFTRT
3939 6527 : && GET_CODE (XEXP (op0, 0)) == PLUS
3940 141 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
3941 87 : && CONST_INT_P (XEXP (op0, 1))
3942 87 : && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
3943 : {
3944 87 : int count = INTVAL (XEXP (op0, 1));
3945 87 : HOST_WIDE_INT mask = UINTVAL (trueop1) << count;
3946 :
3947 87 : if (mask >> count == INTVAL (trueop1)
3948 80 : && trunc_int_for_mode (mask, mode) == mask
3949 154 : && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
3950 0 : return simplify_gen_binary (ASHIFTRT, mode,
3951 : plus_constant (mode, XEXP (op0, 0),
3952 0 : mask),
3953 : XEXP (op0, 1));
3954 : }
3955 :
3956 : /* The following happens with bitfield merging.
3957 : (X & C) | ((X | Y) & ~C) -> X | (Y & ~C) */
3958 13807538 : if (GET_CODE (op0) == AND
3959 3894104 : && GET_CODE (op1) == AND
3960 284812 : && CONST_INT_P (XEXP (op0, 1))
3961 119586 : && CONST_INT_P (XEXP (op1, 1))
3962 114134 : && (INTVAL (XEXP (op0, 1))
3963 114134 : == ~INTVAL (XEXP (op1, 1))))
3964 : {
3965 : /* The IOR/XOR may be on both sides. */
3966 33215 : rtx top0 = NULL_RTX, top1 = NULL_RTX;
3967 33215 : if (GET_CODE (XEXP (op1, 0)) == IOR
3968 33215 : || GET_CODE (XEXP (op1, 0)) == XOR)
3969 : top0 = op0, top1 = op1;
3970 33096 : else if (GET_CODE (XEXP (op0, 0)) == IOR
3971 33096 : || GET_CODE (XEXP (op0, 0)) == XOR)
3972 3 : top0 = op1, top1 = op0;
3973 33215 : if (top0 && top1)
3974 : {
3975 : /* X may be on either side of the inner IOR/XOR. */
3976 122 : rtx tem = NULL_RTX;
3977 122 : if (rtx_equal_p (XEXP (top0, 0),
3978 122 : XEXP (XEXP (top1, 0), 0)))
3979 76 : tem = XEXP (XEXP (top1, 0), 1);
3980 46 : else if (rtx_equal_p (XEXP (top0, 0),
3981 46 : XEXP (XEXP (top1, 0), 1)))
3982 13 : tem = XEXP (XEXP (top1, 0), 0);
3983 89 : if (tem)
3984 89 : return simplify_gen_binary (GET_CODE (XEXP (top1, 0)),
3985 : mode, XEXP (top0, 0),
3986 : simplify_gen_binary
3987 89 : (AND, mode, tem, XEXP (top1, 1)));
3988 : }
3989 : }
3990 :
3991 : /* Convert (ior (and A C) (and B C)) into (and (ior A B) C). */
3992 13807449 : if (GET_CODE (op0) == GET_CODE (op1)
3993 3439734 : && (GET_CODE (op0) == AND
3994 : || GET_CODE (op0) == IOR
3995 3439734 : || GET_CODE (op0) == LSHIFTRT
3996 3154012 : || GET_CODE (op0) == ASHIFTRT
3997 3153891 : || GET_CODE (op0) == ASHIFT
3998 3138469 : || GET_CODE (op0) == ROTATE
3999 3138469 : || GET_CODE (op0) == ROTATERT))
4000 : {
4001 301265 : tem = simplify_distributive_operation (code, mode, op0, op1);
4002 301265 : if (tem)
4003 : return tem;
4004 : }
4005 :
4006 : /* Convert (ior (and (not A) B) A) into A | B. */
4007 13720662 : if (GET_CODE (op0) == AND
4008 13720662 : && negated_ops_p (XEXP (op0, 0), op1))
4009 6030 : return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
4010 :
4011 : /* op0/op1 may have a common term which in turn may allow simplification
4012 : of the the outer IOR. There are likely other cases we should
4013 : handle for the outer code as well as the form of the operands. */
4014 13714632 : tem = simplify_ior_with_common_term (mode, op0, op1);
4015 13714632 : if (tem)
4016 : return tem;
4017 :
4018 : /* IOR is commutative and we can't rely on canonicalization at this point,
4019 : so try again to simplify with the operands reversed. */
4020 13714541 : tem = simplify_ior_with_common_term (mode, op1, op0);
4021 13714541 : if (tem)
4022 : return tem;
4023 :
4024 13714541 : tem = simplify_with_subreg_not (code, mode, op0, op1);
4025 13714541 : if (tem)
4026 : return tem;
4027 :
4028 13714536 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
4029 13714536 : if (tem)
4030 : return tem;
4031 :
4032 13714503 : tem = simplify_associative_operation (code, mode, op0, op1);
4033 13714503 : if (tem)
4034 : return tem;
4035 :
4036 13443128 : tem = simplify_logical_relational_operation (code, mode, op0, op1);
4037 13443128 : if (tem)
4038 : return tem;
4039 : break;
4040 :
4041 1792459 : case XOR:
4042 1792459 : if (trueop1 == CONST0_RTX (mode))
4043 : return op0;
4044 1734656 : if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
4045 29544 : return simplify_gen_unary (NOT, mode, op0, mode);
4046 1705112 : if (rtx_equal_p (trueop0, trueop1)
4047 2657 : && ! side_effects_p (op0)
4048 1707765 : && GET_MODE_CLASS (mode) != MODE_CC)
4049 2653 : return CONST0_RTX (mode);
4050 :
4051 : /* Canonicalize XOR of the most significant bit to PLUS. */
4052 1702459 : if (CONST_SCALAR_INT_P (op1)
4053 1702459 : && mode_signbit_p (mode, op1))
4054 41070 : return simplify_gen_binary (PLUS, mode, op0, op1);
4055 : /* (xor (plus X C1) C2) is (xor X (C1^C2)) if C1 is signbit. */
4056 1661389 : if (CONST_SCALAR_INT_P (op1)
4057 485858 : && GET_CODE (op0) == PLUS
4058 2551 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
4059 1662997 : && mode_signbit_p (mode, XEXP (op0, 1)))
4060 189 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
4061 : simplify_gen_binary (XOR, mode, op1,
4062 189 : XEXP (op0, 1)));
4063 :
4064 : /* If we are XORing two things that have no bits in common,
4065 : convert them into an IOR. This helps to detect rotation encoded
4066 : using those methods and possibly other simplifications. */
4067 :
4068 1661200 : if (HWI_COMPUTABLE_MODE_P (mode)
4069 1340167 : && (nonzero_bits (op0, mode)
4070 1340167 : & nonzero_bits (op1, mode)) == 0)
4071 11092 : return (simplify_gen_binary (IOR, mode, op0, op1));
4072 :
4073 : /* Convert (xor (plus (A - 1)) (neg A)) to -1. */
4074 1650108 : if (match_plus_neg_pattern (op0, op1, mode))
4075 0 : return CONSTM1_RTX (mode);
4076 :
4077 : /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
4078 : Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
4079 : (NOT y). */
4080 1650108 : {
4081 1650108 : int num_negated = 0;
4082 :
4083 1650108 : if (GET_CODE (op0) == NOT)
4084 885 : num_negated++, op0 = XEXP (op0, 0);
4085 1650108 : if (GET_CODE (op1) == NOT)
4086 64 : num_negated++, op1 = XEXP (op1, 0);
4087 :
4088 64 : if (num_negated == 2)
4089 0 : return simplify_gen_binary (XOR, mode, op0, op1);
4090 1650108 : else if (num_negated == 1)
4091 949 : return simplify_gen_unary (NOT, mode,
4092 : simplify_gen_binary (XOR, mode, op0, op1),
4093 949 : mode);
4094 : }
4095 :
4096 : /* Convert (xor (and A B) B) to (and (not A) B). The latter may
4097 : correspond to a machine insn or result in further simplifications
4098 : if B is a constant. */
4099 :
4100 1649159 : if (GET_CODE (op0) == AND
4101 177800 : && rtx_equal_p (XEXP (op0, 1), op1)
4102 1670506 : && ! side_effects_p (op1))
4103 21347 : return simplify_gen_binary (AND, mode,
4104 : simplify_gen_unary (NOT, mode,
4105 : XEXP (op0, 0), mode),
4106 21347 : op1);
4107 :
4108 1627812 : else if (GET_CODE (op0) == AND
4109 156453 : && rtx_equal_p (XEXP (op0, 0), op1)
4110 1629069 : && ! side_effects_p (op1))
4111 1257 : return simplify_gen_binary (AND, mode,
4112 : simplify_gen_unary (NOT, mode,
4113 : XEXP (op0, 1), mode),
4114 1257 : op1);
4115 :
4116 : /* Given (xor (ior (xor A B) C) D), where B, C and D are
4117 : constants, simplify to (xor (ior A C) (B&~C)^D), canceling
4118 : out bits inverted twice and not set by C. Similarly, given
4119 : (xor (and (xor A B) C) D), simplify without inverting C in
4120 : the xor operand: (xor (and A C) (B&C)^D).
4121 : */
4122 1626555 : else if ((GET_CODE (op0) == IOR || GET_CODE (op0) == AND)
4123 178695 : && GET_CODE (XEXP (op0, 0)) == XOR
4124 7232 : && CONST_INT_P (op1)
4125 212 : && CONST_INT_P (XEXP (op0, 1))
4126 158 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
4127 : {
4128 38 : enum rtx_code op = GET_CODE (op0);
4129 38 : rtx a = XEXP (XEXP (op0, 0), 0);
4130 38 : rtx b = XEXP (XEXP (op0, 0), 1);
4131 38 : rtx c = XEXP (op0, 1);
4132 38 : rtx d = op1;
4133 38 : HOST_WIDE_INT bval = INTVAL (b);
4134 38 : HOST_WIDE_INT cval = INTVAL (c);
4135 38 : HOST_WIDE_INT dval = INTVAL (d);
4136 38 : HOST_WIDE_INT xcval;
4137 :
4138 38 : if (op == IOR)
4139 8 : xcval = ~cval;
4140 : else
4141 : xcval = cval;
4142 :
4143 38 : return simplify_gen_binary (XOR, mode,
4144 : simplify_gen_binary (op, mode, a, c),
4145 38 : gen_int_mode ((bval & xcval) ^ dval,
4146 : mode));
4147 : }
4148 :
4149 : /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P),
4150 : we can transform like this:
4151 : (A&B)^C == ~(A&B)&C | ~C&(A&B)
4152 : == (~A|~B)&C | ~C&(A&B) * DeMorgan's Law
4153 : == ~A&C | ~B&C | A&(~C&B) * Distribute and re-order
4154 : Attempt a few simplifications when B and C are both constants. */
4155 1626517 : if (GET_CODE (op0) == AND
4156 155166 : && CONST_INT_P (op1)
4157 13894 : && CONST_INT_P (XEXP (op0, 1)))
4158 : {
4159 11435 : rtx a = XEXP (op0, 0);
4160 11435 : rtx b = XEXP (op0, 1);
4161 11435 : rtx c = op1;
4162 11435 : HOST_WIDE_INT bval = INTVAL (b);
4163 11435 : HOST_WIDE_INT cval = INTVAL (c);
4164 :
4165 : /* Instead of computing ~A&C, we compute its negated value,
4166 : ~(A|~C). If it yields -1, ~A&C is zero, so we can
4167 : optimize for sure. If it does not simplify, we still try
4168 : to compute ~A&C below, but since that always allocates
4169 : RTL, we don't try that before committing to returning a
4170 : simplified expression. */
4171 11435 : rtx n_na_c = simplify_binary_operation (IOR, mode, a,
4172 : GEN_INT (~cval));
4173 :
4174 11435 : if ((~cval & bval) == 0)
4175 : {
4176 824 : rtx na_c = NULL_RTX;
4177 824 : if (n_na_c)
4178 0 : na_c = simplify_gen_unary (NOT, mode, n_na_c, mode);
4179 : else
4180 : {
4181 : /* If ~A does not simplify, don't bother: we don't
4182 : want to simplify 2 operations into 3, and if na_c
4183 : were to simplify with na, n_na_c would have
4184 : simplified as well. */
4185 824 : rtx na = simplify_unary_operation (NOT, mode, a, mode);
4186 824 : if (na)
4187 0 : na_c = simplify_gen_binary (AND, mode, na, c);
4188 : }
4189 :
4190 : /* Try to simplify ~A&C | ~B&C. */
4191 0 : if (na_c != NULL_RTX)
4192 0 : return simplify_gen_binary (IOR, mode, na_c,
4193 0 : gen_int_mode (~bval & cval, mode));
4194 : }
4195 : else
4196 : {
4197 : /* If ~A&C is zero, simplify A&(~C&B) | ~B&C. */
4198 10611 : if (n_na_c == CONSTM1_RTX (mode))
4199 : {
4200 0 : rtx a_nc_b = simplify_gen_binary (AND, mode, a,
4201 0 : gen_int_mode (~cval & bval,
4202 : mode));
4203 0 : return simplify_gen_binary (IOR, mode, a_nc_b,
4204 0 : gen_int_mode (~bval & cval,
4205 : mode));
4206 : }
4207 : }
4208 : }
4209 :
4210 : /* If we have (xor (and (xor A B) C) A) with C a constant we can instead
4211 : do (ior (and A ~C) (and B C)) which is a machine instruction on some
4212 : machines, and also has shorter instruction path length. */
4213 1626517 : if (GET_CODE (op0) == AND
4214 155166 : && GET_CODE (XEXP (op0, 0)) == XOR
4215 6722 : && CONST_INT_P (XEXP (op0, 1))
4216 1629959 : && rtx_equal_p (XEXP (XEXP (op0, 0), 0), trueop1))
4217 : {
4218 7 : rtx a = trueop1;
4219 7 : rtx b = XEXP (XEXP (op0, 0), 1);
4220 7 : rtx c = XEXP (op0, 1);
4221 7 : rtx nc = simplify_gen_unary (NOT, mode, c, mode);
4222 7 : rtx a_nc = simplify_gen_binary (AND, mode, a, nc);
4223 7 : rtx bc = simplify_gen_binary (AND, mode, b, c);
4224 7 : return simplify_gen_binary (IOR, mode, a_nc, bc);
4225 : }
4226 : /* Similarly, (xor (and (xor A B) C) B) as (ior (and A C) (and B ~C)) */
4227 1626510 : else if (GET_CODE (op0) == AND
4228 155159 : && GET_CODE (XEXP (op0, 0)) == XOR
4229 6715 : && CONST_INT_P (XEXP (op0, 1))
4230 1629945 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), trueop1))
4231 : {
4232 8 : rtx a = XEXP (XEXP (op0, 0), 0);
4233 8 : rtx b = trueop1;
4234 8 : rtx c = XEXP (op0, 1);
4235 8 : rtx nc = simplify_gen_unary (NOT, mode, c, mode);
4236 8 : rtx b_nc = simplify_gen_binary (AND, mode, b, nc);
4237 8 : rtx ac = simplify_gen_binary (AND, mode, a, c);
4238 8 : return simplify_gen_binary (IOR, mode, ac, b_nc);
4239 : }
4240 :
4241 : /* (xor (comparison foo bar) (const_int 1)) can become the reversed
4242 : comparison if STORE_FLAG_VALUE is 1. */
4243 1626502 : if (STORE_FLAG_VALUE == 1
4244 1626502 : && trueop1 == const1_rtx
4245 205840 : && COMPARISON_P (op0)
4246 1633109 : && (reversed = reversed_comparison (op0, mode)))
4247 : return reversed;
4248 :
4249 : /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
4250 : is (lt foo (const_int 0)), so we can perform the above
4251 : simplification if STORE_FLAG_VALUE is 1. */
4252 :
4253 1619903 : if (is_a <scalar_int_mode> (mode, &int_mode)
4254 : && STORE_FLAG_VALUE == 1
4255 1303271 : && trueop1 == const1_rtx
4256 199241 : && GET_CODE (op0) == LSHIFTRT
4257 35705 : && CONST_INT_P (XEXP (op0, 1))
4258 35705 : && INTVAL (XEXP (op0, 1)) == GET_MODE_PRECISION (int_mode) - 1)
4259 34774 : return gen_rtx_GE (int_mode, XEXP (op0, 0), const0_rtx);
4260 :
4261 : /* (xor (comparison foo bar) (const_int sign-bit))
4262 : when STORE_FLAG_VALUE is the sign bit. */
4263 1585129 : if (is_a <scalar_int_mode> (mode, &int_mode)
4264 1268497 : && val_signbit_p (int_mode, STORE_FLAG_VALUE)
4265 0 : && trueop1 == const_true_rtx
4266 0 : && COMPARISON_P (op0)
4267 0 : && (reversed = reversed_comparison (op0, int_mode)))
4268 : return reversed;
4269 :
4270 : /* Convert (xor (and A C) (and B C)) into (and (xor A B) C). */
4271 1585129 : if (GET_CODE (op0) == GET_CODE (op1)
4272 553326 : && (GET_CODE (op0) == AND
4273 553326 : || GET_CODE (op0) == LSHIFTRT
4274 480704 : || GET_CODE (op0) == ASHIFTRT
4275 480608 : || GET_CODE (op0) == ASHIFT
4276 480474 : || GET_CODE (op0) == ROTATE
4277 480366 : || GET_CODE (op0) == ROTATERT))
4278 : {
4279 73494 : tem = simplify_distributive_operation (code, mode, op0, op1);
4280 73494 : if (tem)
4281 : return tem;
4282 : }
4283 :
4284 : /* Convert (xor (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
4285 : mode size to (rotate A CX). */
4286 1515128 : tem = simplify_rotate_op (op0, op1, mode);
4287 1515128 : if (tem)
4288 : return tem;
4289 :
4290 : /* Convert (xor (and (not A) B) A) into A | B. */
4291 1513748 : if (GET_CODE (op0) == AND
4292 1513748 : && negated_ops_p (XEXP (op0, 0), op1))
4293 1 : return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
4294 :
4295 : /* Convert (xor (and (rotate (~1) A) B) (ashift 1 A))
4296 : into B | (1 << A). */
4297 1513747 : if (SHIFT_COUNT_TRUNCATED
4298 : && GET_CODE (op0) == AND
4299 : && GET_CODE (XEXP (op0, 0)) == ROTATE
4300 : && CONST_INT_P (XEXP (XEXP (op0, 0), 0))
4301 : && INTVAL (XEXP (XEXP (op0, 0), 0)) == -2
4302 : && GET_CODE (op1) == ASHIFT
4303 : && CONST_INT_P (XEXP (op1, 0))
4304 : && INTVAL (XEXP (op1, 0)) == 1
4305 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), XEXP (op1, 1))
4306 : && !side_effects_p (XEXP (op1, 1)))
4307 : return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
4308 :
4309 1513747 : tem = simplify_with_subreg_not (code, mode, op0, op1);
4310 1513747 : if (tem)
4311 : return tem;
4312 :
4313 1513746 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
4314 1513746 : if (tem)
4315 : return tem;
4316 :
4317 1513746 : tem = simplify_associative_operation (code, mode, op0, op1);
4318 1513746 : if (tem)
4319 : return tem;
4320 : break;
4321 :
4322 24325329 : case AND:
4323 24325329 : if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
4324 : return trueop1;
4325 24050060 : if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
4326 : return op0;
4327 23665810 : if (HWI_COMPUTABLE_MODE_P (mode))
4328 : {
4329 : /* When WORD_REGISTER_OPERATIONS is true, we need to know the
4330 : nonzero bits in WORD_MODE rather than MODE. */
4331 20724768 : scalar_int_mode tmode = as_a <scalar_int_mode> (mode);
4332 20724768 : if (WORD_REGISTER_OPERATIONS
4333 : && GET_MODE_BITSIZE (tmode) < BITS_PER_WORD)
4334 : tmode = word_mode;
4335 20724768 : HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, tmode);
4336 20724768 : HOST_WIDE_INT nzop1;
4337 20724768 : if (CONST_INT_P (trueop1))
4338 : {
4339 17593952 : HOST_WIDE_INT val1 = INTVAL (trueop1);
4340 : /* If we are turning off bits already known off in OP0, we need
4341 : not do an AND. */
4342 17593952 : if ((nzop0 & ~val1) == 0)
4343 423560 : return op0;
4344 :
4345 : /* Canonicalize (and (subreg (lshiftrt X shift)) mask) into
4346 : (and (lshiftrt (subreg X) shift) mask).
4347 :
4348 : Keeps shift and AND in the same mode, improving recognition.
4349 : Only applied when subreg is a lowpart, shift is valid,
4350 : and no precision is lost. */
4351 17254243 : if (SUBREG_P (op0)
4352 6161663 : && subreg_lowpart_p (op0)
4353 6144739 : && !paradoxical_subreg_p (op0)
4354 725875 : && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
4355 : /* simplify_subreg asserts the object being accessed is not
4356 : VOIDmode or BLKmode. We may have a REG_EQUAL note which
4357 : is not simplified and the source operand is a constant,
4358 : and thus VOIDmode. Guard against that. */
4359 106477 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) != VOIDmode
4360 106427 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) != BLKmode
4361 106427 : && !CONST_INT_P (XEXP (XEXP (op0, 0), 0))
4362 106427 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
4363 85657 : && INTVAL (XEXP (XEXP (op0, 0), 1)) >= 0
4364 85657 : && INTVAL (XEXP (XEXP (op0, 0), 1)) < HOST_BITS_PER_WIDE_INT
4365 17339899 : && ((INTVAL (XEXP (XEXP (op0, 0), 1))
4366 85656 : + floor_log2 (val1))
4367 17254243 : < GET_MODE_PRECISION (as_a <scalar_int_mode> (mode))))
4368 : {
4369 10705 : tem = XEXP (XEXP (op0, 0), 0);
4370 10705 : if (SUBREG_P (tem))
4371 : {
4372 265 : if (subreg_lowpart_p (tem))
4373 265 : tem = SUBREG_REG (tem);
4374 : else
4375 : tem = NULL_RTX;
4376 : }
4377 265 : if (tem != NULL_RTX)
4378 : {
4379 10705 : offset = subreg_lowpart_offset (mode, GET_MODE (tem));
4380 10705 : tem = simplify_gen_subreg (mode, tem, GET_MODE (tem),
4381 10705 : offset);
4382 10705 : if (tem)
4383 : {
4384 10705 : unsigned shiftamt = INTVAL (XEXP (XEXP (op0, 0), 1));
4385 10705 : rtx shiftamtrtx = gen_int_shift_amount (mode,
4386 10705 : shiftamt);
4387 10705 : op0 = simplify_gen_binary (LSHIFTRT, mode, tem,
4388 : shiftamtrtx);
4389 10705 : return simplify_gen_binary (AND, mode, op0, op1);
4390 : }
4391 : }
4392 : }
4393 : }
4394 20374354 : nzop1 = nonzero_bits (trueop1, mode);
4395 : /* If we are clearing all the nonzero bits, the result is zero. */
4396 20374354 : if ((nzop1 & nzop0) == 0
4397 20374354 : && !side_effects_p (op0) && !side_effects_p (op1))
4398 73146 : return CONST0_RTX (mode);
4399 : }
4400 23246396 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
4401 23246392 : && GET_MODE_CLASS (mode) != MODE_CC)
4402 : return op0;
4403 : /* A & (~A) -> 0 */
4404 626713 : if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
4405 23234203 : || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
4406 3951 : && ! side_effects_p (op0)
4407 23242058 : && GET_MODE_CLASS (mode) != MODE_CC)
4408 3950 : return CONST0_RTX (mode);
4409 :
4410 : /* Convert (and (plus (A - 1)) (neg A)) to 0. */
4411 23234158 : if (match_plus_neg_pattern (op0, op1, mode))
4412 2 : return CONST0_RTX (mode);
4413 :
4414 : /* Transform (and (extend X) C) into (zero_extend (and X C)) if
4415 : there are no nonzero bits of C outside of X's mode. */
4416 46468312 : if ((GET_CODE (op0) == SIGN_EXTEND
4417 23234156 : || GET_CODE (op0) == ZERO_EXTEND)
4418 94627 : && CONST_SCALAR_INT_P (trueop1)
4419 80669 : && is_a <scalar_int_mode> (mode, &int_mode)
4420 80669 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
4421 23314825 : && (wi::mask (GET_MODE_PRECISION (inner_mode), true,
4422 80669 : GET_MODE_PRECISION (int_mode))
4423 23314825 : & rtx_mode_t (trueop1, mode)) == 0)
4424 : {
4425 78750 : machine_mode imode = GET_MODE (XEXP (op0, 0));
4426 78750 : tem = immed_wide_int_const (rtx_mode_t (trueop1, mode), imode);
4427 78750 : tem = simplify_gen_binary (AND, imode, XEXP (op0, 0), tem);
4428 78750 : return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
4429 : }
4430 :
4431 : /* Transform (and (truncate X) C) into (truncate (and X C)). This way
4432 : we might be able to further simplify the AND with X and potentially
4433 : remove the truncation altogether. */
4434 23155406 : if (GET_CODE (op0) == TRUNCATE && CONST_INT_P (trueop1))
4435 : {
4436 6 : rtx x = XEXP (op0, 0);
4437 6 : machine_mode xmode = GET_MODE (x);
4438 6 : tem = simplify_gen_binary (AND, xmode, x,
4439 6 : gen_int_mode (INTVAL (trueop1), xmode));
4440 6 : return simplify_gen_unary (TRUNCATE, mode, tem, xmode);
4441 : }
4442 :
4443 : /* Canonicalize (A | C1) & C2 as (A & C2) | (C1 & C2). */
4444 23155400 : if (GET_CODE (op0) == IOR
4445 1405463 : && CONST_INT_P (trueop1)
4446 216880 : && CONST_INT_P (XEXP (op0, 1)))
4447 : {
4448 134720 : HOST_WIDE_INT tmp = INTVAL (trueop1) & INTVAL (XEXP (op0, 1));
4449 134720 : return simplify_gen_binary (IOR, mode,
4450 : simplify_gen_binary (AND, mode,
4451 : XEXP (op0, 0), op1),
4452 134720 : gen_int_mode (tmp, mode));
4453 : }
4454 :
4455 : /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
4456 : insn (and may simplify more). */
4457 23020680 : if (GET_CODE (op0) == XOR
4458 142684 : && rtx_equal_p (XEXP (op0, 0), op1)
4459 23022121 : && ! side_effects_p (op1))
4460 1441 : return simplify_gen_binary (AND, mode,
4461 : simplify_gen_unary (NOT, mode,
4462 : XEXP (op0, 1), mode),
4463 1441 : op1);
4464 :
4465 23019239 : if (GET_CODE (op0) == XOR
4466 141243 : && rtx_equal_p (XEXP (op0, 1), op1)
4467 23022272 : && ! side_effects_p (op1))
4468 3033 : return simplify_gen_binary (AND, mode,
4469 : simplify_gen_unary (NOT, mode,
4470 : XEXP (op0, 0), mode),
4471 3033 : op1);
4472 :
4473 : /* Similarly for (~(A ^ B)) & A. */
4474 23016206 : if (GET_CODE (op0) == NOT
4475 622809 : && GET_CODE (XEXP (op0, 0)) == XOR
4476 3918 : && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
4477 23016260 : && ! side_effects_p (op1))
4478 54 : return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
4479 :
4480 23016152 : if (GET_CODE (op0) == NOT
4481 622755 : && GET_CODE (XEXP (op0, 0)) == XOR
4482 3864 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
4483 23016189 : && ! side_effects_p (op1))
4484 37 : return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
4485 :
4486 : /* Convert (A | B) & A to A. */
4487 23016115 : if (GET_CODE (op0) == IOR
4488 1270743 : && (rtx_equal_p (XEXP (op0, 0), op1)
4489 1270218 : || rtx_equal_p (XEXP (op0, 1), op1))
4490 743 : && ! side_effects_p (XEXP (op0, 0))
4491 23016858 : && ! side_effects_p (XEXP (op0, 1)))
4492 : return op1;
4493 :
4494 : /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
4495 : ((A & N) + B) & M -> (A + B) & M
4496 : Similarly if (N & M) == 0,
4497 : ((A | N) + B) & M -> (A + B) & M
4498 : and for - instead of + and/or ^ instead of |.
4499 : Also, if (N & M) == 0, then
4500 : (A +- N) & M -> A & M. */
4501 23015372 : if (CONST_INT_P (trueop1)
4502 17052488 : && HWI_COMPUTABLE_MODE_P (mode)
4503 17030719 : && ~UINTVAL (trueop1)
4504 17030719 : && (UINTVAL (trueop1) & (UINTVAL (trueop1) + 1)) == 0
4505 34240970 : && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS))
4506 : {
4507 957027 : rtx pmop[2];
4508 957027 : int which;
4509 :
4510 957027 : pmop[0] = XEXP (op0, 0);
4511 957027 : pmop[1] = XEXP (op0, 1);
4512 :
4513 957027 : if (CONST_INT_P (pmop[1])
4514 492725 : && (UINTVAL (pmop[1]) & UINTVAL (trueop1)) == 0)
4515 166588 : return simplify_gen_binary (AND, mode, pmop[0], op1);
4516 :
4517 2394558 : for (which = 0; which < 2; which++)
4518 : {
4519 1596372 : tem = pmop[which];
4520 1596372 : switch (GET_CODE (tem))
4521 : {
4522 11626 : case AND:
4523 11626 : if (CONST_INT_P (XEXP (tem, 1))
4524 10140 : && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1))
4525 : == UINTVAL (trueop1))
4526 7608 : pmop[which] = XEXP (tem, 0);
4527 : break;
4528 1724 : case IOR:
4529 1724 : case XOR:
4530 1724 : if (CONST_INT_P (XEXP (tem, 1))
4531 695 : && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1)) == 0)
4532 139 : pmop[which] = XEXP (tem, 0);
4533 : break;
4534 : default:
4535 : break;
4536 : }
4537 : }
4538 :
4539 798186 : if (pmop[0] != XEXP (op0, 0) || pmop[1] != XEXP (op0, 1))
4540 : {
4541 7747 : tem = simplify_gen_binary (GET_CODE (op0), mode,
4542 : pmop[0], pmop[1]);
4543 7747 : return simplify_gen_binary (code, mode, tem, op1);
4544 : }
4545 : }
4546 :
4547 : /* (and X (ior (not X) Y) -> (and X Y) */
4548 22848784 : if (GET_CODE (op1) == IOR
4549 958784 : && GET_CODE (XEXP (op1, 0)) == NOT
4550 22854297 : && rtx_equal_p (op0, XEXP (XEXP (op1, 0), 0)))
4551 0 : return simplify_gen_binary (AND, mode, op0, XEXP (op1, 1));
4552 :
4553 : /* (and (ior (not X) Y) X) -> (and X Y) */
4554 22848784 : if (GET_CODE (op0) == IOR
4555 1270000 : && GET_CODE (XEXP (op0, 0)) == NOT
4556 22900883 : && rtx_equal_p (op1, XEXP (XEXP (op0, 0), 0)))
4557 6 : return simplify_gen_binary (AND, mode, op1, XEXP (op0, 1));
4558 :
4559 : /* (and X (ior Y (not X)) -> (and X Y) */
4560 22848778 : if (GET_CODE (op1) == IOR
4561 958784 : && GET_CODE (XEXP (op1, 1)) == NOT
4562 22849369 : && rtx_equal_p (op0, XEXP (XEXP (op1, 1), 0)))
4563 0 : return simplify_gen_binary (AND, mode, op0, XEXP (op1, 0));
4564 :
4565 : /* (and (ior Y (not X)) X) -> (and X Y) */
4566 22848778 : if (GET_CODE (op0) == IOR
4567 1269994 : && GET_CODE (XEXP (op0, 1)) == NOT
4568 22856108 : && rtx_equal_p (op1, XEXP (XEXP (op0, 1), 0)))
4569 78 : return simplify_gen_binary (AND, mode, op1, XEXP (op0, 0));
4570 :
4571 : /* (and (ior/xor X Y) (not Y)) -> X & ~Y */
4572 22848700 : if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
4573 22848700 : && negated_ops_p (op1, XEXP (op0, 1)))
4574 20 : return simplify_gen_binary (AND, mode, XEXP (op0, 0),
4575 : simplify_gen_unary (NOT, mode,
4576 : XEXP (op0, 1),
4577 20 : mode));
4578 : /* (and (ior/xor Y X) (not Y)) -> X & ~Y */
4579 22848680 : if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
4580 22848680 : && negated_ops_p (op1, XEXP (op0, 0)))
4581 4 : return simplify_gen_binary (AND, mode, XEXP (op0, 1),
4582 : simplify_gen_unary (NOT, mode,
4583 : XEXP (op0, 0),
4584 4 : mode));
4585 :
4586 : /* Convert (and (ior A C) (ior B C)) into (ior (and A B) C). */
4587 22848676 : if (GET_CODE (op0) == GET_CODE (op1)
4588 2228619 : && (GET_CODE (op0) == AND
4589 : || GET_CODE (op0) == IOR
4590 2228619 : || GET_CODE (op0) == LSHIFTRT
4591 1270324 : || GET_CODE (op0) == ASHIFTRT
4592 1270174 : || GET_CODE (op0) == ASHIFT
4593 1270005 : || GET_CODE (op0) == ROTATE
4594 1270005 : || GET_CODE (op0) == ROTATERT))
4595 : {
4596 958614 : tem = simplify_distributive_operation (code, mode, op0, op1);
4597 958614 : if (tem)
4598 : return tem;
4599 : }
4600 :
4601 : /* (and:v4si
4602 : (ashiftrt:v4si A 16)
4603 : (const_vector: 0xffff x4))
4604 : is just (lshiftrt:v4si A 16). */
4605 21934902 : if (VECTOR_MODE_P (mode) && GET_CODE (op0) == ASHIFTRT
4606 4846 : && (CONST_INT_P (XEXP (op0, 1))
4607 2016 : || (GET_CODE (XEXP (op0, 1)) == CONST_VECTOR
4608 94 : && const_vec_duplicate_p (XEXP (op0, 1))
4609 0 : && CONST_INT_P (XVECEXP (XEXP (op0, 1), 0, 0))))
4610 2830 : && GET_CODE (op1) == CONST_VECTOR
4611 21934936 : && const_vec_duplicate_p (op1)
4612 21934978 : && CONST_INT_P (XVECEXP (op1, 0, 0)))
4613 : {
4614 148 : unsigned HOST_WIDE_INT shift_count
4615 : = (CONST_INT_P (XEXP (op0, 1))
4616 74 : ? UINTVAL (XEXP (op0, 1))
4617 0 : : UINTVAL (XVECEXP (XEXP (op0, 1), 0, 0)));
4618 74 : unsigned HOST_WIDE_INT inner_prec
4619 148 : = GET_MODE_PRECISION (GET_MODE_INNER (mode));
4620 :
4621 : /* Avoid UD shift count. */
4622 74 : if (shift_count < inner_prec
4623 62 : && (UINTVAL (XVECEXP (op1, 0, 0))
4624 62 : == (HOST_WIDE_INT_1U << (inner_prec - shift_count)) - 1))
4625 42 : return simplify_gen_binary (LSHIFTRT, mode, XEXP (op0, 0), XEXP (op0, 1));
4626 : }
4627 :
4628 21934860 : tem = simplify_with_subreg_not (code, mode, op0, op1);
4629 21934860 : if (tem)
4630 : return tem;
4631 :
4632 21932538 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
4633 21932538 : if (tem)
4634 : return tem;
4635 :
4636 21932317 : tem = simplify_associative_operation (code, mode, op0, op1);
4637 21932317 : if (tem)
4638 : return tem;
4639 : break;
4640 :
4641 895302 : case UDIV:
4642 : /* 0/x is 0 (or x&0 if x has side-effects). */
4643 895302 : if (trueop0 == CONST0_RTX (mode)
4644 384 : && !cfun->can_throw_non_call_exceptions)
4645 : {
4646 384 : if (side_effects_p (op1))
4647 0 : return simplify_gen_binary (AND, mode, op1, trueop0);
4648 : return trueop0;
4649 : }
4650 : /* x/1 is x. */
4651 894918 : if (trueop1 == CONST1_RTX (mode))
4652 : {
4653 239200 : tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4654 239200 : if (tem)
4655 : return tem;
4656 : }
4657 : /* Convert divide by power of two into shift. */
4658 655718 : if (CONST_INT_P (trueop1)
4659 977284 : && (val = exact_log2 (UINTVAL (trueop1))) > 0)
4660 321566 : return simplify_gen_binary (LSHIFTRT, mode, op0,
4661 321566 : gen_int_shift_amount (mode, val));
4662 : break;
4663 :
4664 1404498 : case DIV:
4665 : /* Handle floating point and integers separately. */
4666 1404498 : if (SCALAR_FLOAT_MODE_P (mode))
4667 : {
4668 : /* Maybe change 0.0 / x to 0.0. This transformation isn't
4669 : safe for modes with NaNs, since 0.0 / 0.0 will then be
4670 : NaN rather than 0.0. Nor is it safe for modes with signed
4671 : zeros, since dividing 0 by a negative number gives -0.0 */
4672 331383 : if (trueop0 == CONST0_RTX (mode)
4673 2800 : && !HONOR_NANS (mode)
4674 14 : && !HONOR_SIGNED_ZEROS (mode)
4675 331397 : && ! side_effects_p (op1))
4676 : return op0;
4677 : /* x/1.0 is x. */
4678 331369 : if (trueop1 == CONST1_RTX (mode)
4679 331369 : && !HONOR_SNANS (mode))
4680 : return op0;
4681 :
4682 331364 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
4683 27458 : && trueop1 != CONST0_RTX (mode))
4684 : {
4685 21344 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
4686 :
4687 : /* x/-1.0 is -x. */
4688 21344 : if (real_equal (d1, &dconstm1)
4689 21344 : && !HONOR_SNANS (mode))
4690 0 : return simplify_gen_unary (NEG, mode, op0, mode);
4691 :
4692 : /* Change FP division by a constant into multiplication.
4693 : Only do this with -freciprocal-math. */
4694 21344 : if (flag_reciprocal_math
4695 21344 : && !real_equal (d1, &dconst0))
4696 : {
4697 7 : REAL_VALUE_TYPE d;
4698 7 : real_arithmetic (&d, RDIV_EXPR, &dconst1, d1);
4699 7 : tem = const_double_from_real_value (d, mode);
4700 7 : return simplify_gen_binary (MULT, mode, op0, tem);
4701 : }
4702 : }
4703 : }
4704 1073115 : else if (SCALAR_INT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
4705 : {
4706 : /* 0/x is 0 (or x&0 if x has side-effects). */
4707 1049608 : if (trueop0 == CONST0_RTX (mode)
4708 985 : && !cfun->can_throw_non_call_exceptions)
4709 : {
4710 931 : if (side_effects_p (op1))
4711 8 : return simplify_gen_binary (AND, mode, op1, trueop0);
4712 : return trueop0;
4713 : }
4714 : /* x/1 is x. */
4715 1048677 : if (trueop1 == CONST1_RTX (mode))
4716 : {
4717 85 : tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4718 85 : if (tem)
4719 : return tem;
4720 : }
4721 : /* x/-1 is -x. */
4722 1048592 : if (trueop1 == CONSTM1_RTX (mode))
4723 : {
4724 503 : rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4725 503 : if (x)
4726 503 : return simplify_gen_unary (NEG, mode, x, mode);
4727 : }
4728 : }
4729 : break;
4730 :
4731 912278 : case UMOD:
4732 : /* 0%x is 0 (or x&0 if x has side-effects). */
4733 912278 : if (trueop0 == CONST0_RTX (mode))
4734 : {
4735 939 : if (side_effects_p (op1))
4736 0 : return simplify_gen_binary (AND, mode, op1, trueop0);
4737 : return trueop0;
4738 : }
4739 : /* x%1 is 0 (of x&0 if x has side-effects). */
4740 911339 : if (trueop1 == CONST1_RTX (mode))
4741 : {
4742 270612 : if (side_effects_p (op0))
4743 0 : return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
4744 270612 : return CONST0_RTX (mode);
4745 : }
4746 : /* Implement modulus by power of two as AND. */
4747 640727 : if (CONST_INT_P (trueop1)
4748 935866 : && exact_log2 (UINTVAL (trueop1)) > 0)
4749 295139 : return simplify_gen_binary (AND, mode, op0,
4750 295139 : gen_int_mode (UINTVAL (trueop1) - 1,
4751 : mode));
4752 : break;
4753 :
4754 563161 : case MOD:
4755 : /* 0%x is 0 (or x&0 if x has side-effects). */
4756 563161 : if (trueop0 == CONST0_RTX (mode))
4757 : {
4758 1213 : if (side_effects_p (op1))
4759 8 : return simplify_gen_binary (AND, mode, op1, trueop0);
4760 : return trueop0;
4761 : }
4762 : /* x%1 and x%-1 is 0 (or x&0 if x has side-effects). */
4763 561948 : if (trueop1 == CONST1_RTX (mode) || trueop1 == constm1_rtx)
4764 : {
4765 487 : if (side_effects_p (op0))
4766 0 : return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
4767 487 : return CONST0_RTX (mode);
4768 : }
4769 : break;
4770 :
4771 139483 : case ROTATERT:
4772 139483 : case ROTATE:
4773 139483 : if (trueop1 == CONST0_RTX (mode))
4774 : return op0;
4775 : /* Canonicalize rotates by constant amount. If the condition of
4776 : reversing direction is met, then reverse the direction. */
4777 : #if defined(HAVE_rotate) && defined(HAVE_rotatert)
4778 139393 : if (reverse_rotate_by_imm_p (mode, (code == ROTATE), trueop1))
4779 : {
4780 12368 : int new_amount = GET_MODE_UNIT_PRECISION (mode) - INTVAL (trueop1);
4781 12368 : rtx new_amount_rtx = gen_int_shift_amount (mode, new_amount);
4782 13076 : return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
4783 : mode, op0, new_amount_rtx);
4784 : }
4785 : #endif
4786 : /* ROTATE/ROTATERT:HI (X:HI, 8) is BSWAP:HI (X). Other combinations
4787 : such as SImode with a count of 16 do not correspond to RTL BSWAP
4788 : semantics. */
4789 127025 : tem = unwrap_const_vec_duplicate (trueop1);
4790 127025 : if (GET_MODE_UNIT_BITSIZE (mode) == (2 * BITS_PER_UNIT)
4791 127025 : && CONST_INT_P (tem) && INTVAL (tem) == BITS_PER_UNIT)
4792 692 : return simplify_gen_unary (BSWAP, mode, op0, mode);
4793 :
4794 : /* FALLTHRU */
4795 5358715 : case ASHIFTRT:
4796 5358715 : if (trueop1 == CONST0_RTX (mode))
4797 : return op0;
4798 5356688 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4799 : return op0;
4800 : /* Rotating ~0 always results in ~0. */
4801 5356515 : if (CONST_INT_P (trueop0)
4802 15319 : && HWI_COMPUTABLE_MODE_P (mode)
4803 15291 : && UINTVAL (trueop0) == GET_MODE_MASK (mode)
4804 5356515 : && ! side_effects_p (op1))
4805 : return op0;
4806 :
4807 31638036 : canonicalize_shift:
4808 : /* Given:
4809 : scalar modes M1, M2
4810 : scalar constants c1, c2
4811 : size (M2) > size (M1)
4812 : c1 == size (M2) - size (M1)
4813 : optimize:
4814 : ([a|l]shiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int <c1>))
4815 : <low_part>)
4816 : (const_int <c2>))
4817 : to:
4818 : (subreg:M1 ([a|l]shiftrt:M2 (reg:M2) (const_int <c1 + c2>))
4819 : <low_part>). */
4820 31638036 : if ((code == ASHIFTRT || code == LSHIFTRT)
4821 12165402 : && is_a <scalar_int_mode> (mode, &int_mode)
4822 11367045 : && SUBREG_P (op0)
4823 1348041 : && CONST_INT_P (op1)
4824 1344626 : && GET_CODE (SUBREG_REG (op0)) == LSHIFTRT
4825 18723 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op0)),
4826 : &inner_mode)
4827 18723 : && CONST_INT_P (XEXP (SUBREG_REG (op0), 1))
4828 37140 : && GET_MODE_BITSIZE (inner_mode) > GET_MODE_BITSIZE (int_mode)
4829 18570 : && (INTVAL (XEXP (SUBREG_REG (op0), 1))
4830 37140 : == GET_MODE_BITSIZE (inner_mode) - GET_MODE_BITSIZE (int_mode))
4831 31656369 : && subreg_lowpart_p (op0))
4832 : {
4833 18333 : rtx tmp = gen_int_shift_amount
4834 18333 : (inner_mode, INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (op1));
4835 :
4836 : /* Combine would usually zero out the value when combining two
4837 : local shifts and the range becomes larger or equal to the mode.
4838 : However since we fold away one of the shifts here combine won't
4839 : see it so we should immediately zero the result if it's out of
4840 : range. */
4841 18333 : if (code == LSHIFTRT
4842 33164 : && INTVAL (tmp) >= GET_MODE_BITSIZE (inner_mode))
4843 0 : tmp = const0_rtx;
4844 : else
4845 18333 : tmp = simplify_gen_binary (code,
4846 : inner_mode,
4847 18333 : XEXP (SUBREG_REG (op0), 0),
4848 : tmp);
4849 :
4850 18333 : return lowpart_subreg (int_mode, tmp, inner_mode);
4851 : }
4852 :
4853 31619703 : if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
4854 : {
4855 : val = INTVAL (op1) & (GET_MODE_UNIT_PRECISION (mode) - 1);
4856 : if (val != INTVAL (op1))
4857 : return simplify_gen_binary (code, mode, op0,
4858 : gen_int_shift_amount (mode, val));
4859 : }
4860 :
4861 : /* Simplify:
4862 :
4863 : (code:M1
4864 : (subreg:M1
4865 : ([al]shiftrt:M2
4866 : (subreg:M2
4867 : (ashift:M1 X C1))
4868 : C2))
4869 : C3)
4870 :
4871 : to:
4872 :
4873 : (code:M1
4874 : ([al]shiftrt:M1
4875 : (ashift:M1 X C1+N)
4876 : C2+N)
4877 : C3)
4878 :
4879 : where M1 is N bits wider than M2. Optimizing the (subreg:M1 ...)
4880 : directly would be arithmetically correct, but restricting the
4881 : simplification to shifts by constants is more conservative,
4882 : since it is more likely to lead to further simplifications. */
4883 31619703 : if (is_a<scalar_int_mode> (mode, &int_mode)
4884 5838984 : && paradoxical_subreg_p (op0)
4885 5338673 : && is_a<scalar_int_mode> (GET_MODE (SUBREG_REG (op0)), &inner_mode)
4886 5314656 : && (GET_CODE (SUBREG_REG (op0)) == ASHIFTRT
4887 5314656 : || GET_CODE (SUBREG_REG (op0)) == LSHIFTRT)
4888 145871 : && CONST_INT_P (op1))
4889 : {
4890 145871 : auto xcode = GET_CODE (SUBREG_REG (op0));
4891 145871 : rtx xop0 = XEXP (SUBREG_REG (op0), 0);
4892 145871 : rtx xop1 = XEXP (SUBREG_REG (op0), 1);
4893 145871 : if (SUBREG_P (xop0)
4894 10901 : && GET_MODE (SUBREG_REG (xop0)) == mode
4895 10756 : && GET_CODE (SUBREG_REG (xop0)) == ASHIFT
4896 594 : && CONST_INT_P (xop1)
4897 146465 : && UINTVAL (xop1) < GET_MODE_PRECISION (inner_mode))
4898 : {
4899 594 : rtx yop0 = XEXP (SUBREG_REG (xop0), 0);
4900 594 : rtx yop1 = XEXP (SUBREG_REG (xop0), 1);
4901 594 : if (CONST_INT_P (yop1)
4902 594 : && UINTVAL (yop1) < GET_MODE_PRECISION (inner_mode))
4903 : {
4904 1188 : auto bias = (GET_MODE_BITSIZE (int_mode)
4905 594 : - GET_MODE_BITSIZE (inner_mode));
4906 594 : tem = simplify_gen_binary (ASHIFT, mode, yop0,
4907 594 : GEN_INT (INTVAL (yop1) + bias));
4908 594 : tem = simplify_gen_binary (xcode, mode, tem,
4909 594 : GEN_INT (INTVAL (xop1) + bias));
4910 594 : return simplify_gen_binary (code, mode, tem, op1);
4911 : }
4912 : }
4913 : }
4914 : break;
4915 :
4916 0 : case SS_ASHIFT:
4917 0 : if (CONST_INT_P (trueop0)
4918 0 : && HWI_COMPUTABLE_MODE_P (mode)
4919 0 : && (UINTVAL (trueop0) == (GET_MODE_MASK (mode) >> 1)
4920 0 : || mode_signbit_p (mode, trueop0))
4921 0 : && ! side_effects_p (op1))
4922 : return op0;
4923 0 : goto simplify_ashift;
4924 :
4925 0 : case US_ASHIFT:
4926 0 : if (CONST_INT_P (trueop0)
4927 0 : && HWI_COMPUTABLE_MODE_P (mode)
4928 0 : && UINTVAL (trueop0) == GET_MODE_MASK (mode)
4929 0 : && ! side_effects_p (op1))
4930 : return op0;
4931 : /* FALLTHRU */
4932 :
4933 19780197 : case ASHIFT:
4934 19780197 : simplify_ashift:
4935 19780197 : if (trueop1 == CONST0_RTX (mode))
4936 : return op0;
4937 19611419 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4938 : return op0;
4939 19581885 : if (mem_depth
4940 235553 : && code == ASHIFT
4941 235553 : && CONST_INT_P (trueop1)
4942 235545 : && is_a <scalar_int_mode> (mode, &int_mode)
4943 19817418 : && IN_RANGE (UINTVAL (trueop1),
4944 : 1, GET_MODE_PRECISION (int_mode) - 1))
4945 : {
4946 235533 : auto c = (wi::one (GET_MODE_PRECISION (int_mode))
4947 235533 : << UINTVAL (trueop1));
4948 235533 : rtx new_op1 = immed_wide_int_const (c, int_mode);
4949 235533 : return simplify_gen_binary (MULT, int_mode, op0, new_op1);
4950 235533 : }
4951 :
4952 : /* If we're shifting left a signed bitfield extraction and the
4953 : shift count + bitfield size is a natural integral mode and
4954 : the field starts at offset 0 (counting from the LSB), then
4955 : this can be simplified to a sign extension of a left shift.
4956 :
4957 : Some ISAs (RISC-V 64-bit) have inherent support for such
4958 : instructions and it's better for various optimizations to
4959 : express as a SIGN_EXTEND rather than a shifted SIGN_EXTRACT. */
4960 19346352 : if (GET_CODE (op0) == SIGN_EXTRACT
4961 28 : && REG_P (XEXP (op0, 0))
4962 : /* The size of the bitfield, the location of the bitfield and
4963 : shift count must be CONST_INTs. */
4964 22 : && CONST_INT_P (op1)
4965 22 : && CONST_INT_P (XEXP (op0, 1))
4966 22 : && CONST_INT_P (XEXP (op0, 2)))
4967 : {
4968 22 : int size = INTVAL (op1) + INTVAL (XEXP (op0, 1));
4969 22 : machine_mode smaller_mode;
4970 : /* Now we need to verify the size of the bitfield plus the shift
4971 : count is an integral mode and smaller than MODE. This is
4972 : requirement for using SIGN_EXTEND. We also need to verify the
4973 : field starts at bit location 0 and that the subreg lowpart also
4974 : starts at zero. */
4975 22 : if (int_mode_for_size (size, size).exists (&smaller_mode)
4976 3 : && mode > smaller_mode
4977 22 : && (subreg_lowpart_offset (smaller_mode, mode).to_constant ()
4978 3 : == UINTVAL (XEXP (op0, 2)))
4979 1 : && XEXP (op0, 2) == CONST0_RTX (mode))
4980 : {
4981 : /* Everything passed. So we just need to get the subreg of the
4982 : original input, shift it and sign extend the result. */
4983 1 : rtx op = gen_lowpart (smaller_mode, XEXP (op0, 0));
4984 1 : rtx x = gen_rtx_ASHIFT (smaller_mode, op, op1);
4985 1 : return gen_rtx_SIGN_EXTEND (mode, x);
4986 : }
4987 : }
4988 19346351 : goto canonicalize_shift;
4989 :
4990 8780377 : case LSHIFTRT:
4991 8780377 : if (trueop1 == CONST0_RTX (mode))
4992 : return op0;
4993 6936660 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4994 : return op0;
4995 : /* Optimize (lshiftrt (clz X) C) as (eq X 0). */
4996 6935170 : if (GET_CODE (op0) == CLZ
4997 0 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
4998 0 : && CONST_INT_P (trueop1)
4999 : && STORE_FLAG_VALUE == 1
5000 6935170 : && INTVAL (trueop1) < GET_MODE_UNIT_PRECISION (mode))
5001 : {
5002 0 : unsigned HOST_WIDE_INT zero_val = 0;
5003 :
5004 0 : if (CLZ_DEFINED_VALUE_AT_ZERO (inner_mode, zero_val)
5005 0 : && zero_val == GET_MODE_PRECISION (inner_mode)
5006 0 : && INTVAL (trueop1) == exact_log2 (zero_val))
5007 0 : return simplify_gen_relational (EQ, mode, inner_mode,
5008 0 : XEXP (op0, 0), const0_rtx);
5009 : }
5010 6935170 : goto canonicalize_shift;
5011 :
5012 243623 : case SMIN:
5013 243623 : if (HWI_COMPUTABLE_MODE_P (mode)
5014 222782 : && mode_signbit_p (mode, trueop1)
5015 0 : && ! side_effects_p (op0))
5016 : return op1;
5017 243623 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5018 : return op0;
5019 243467 : tem = simplify_associative_operation (code, mode, op0, op1);
5020 243467 : if (tem)
5021 : return tem;
5022 : break;
5023 :
5024 697999 : case SMAX:
5025 697999 : if (HWI_COMPUTABLE_MODE_P (mode)
5026 670307 : && CONST_INT_P (trueop1)
5027 637915 : && (UINTVAL (trueop1) == GET_MODE_MASK (mode) >> 1)
5028 0 : && ! side_effects_p (op0))
5029 : return op1;
5030 697999 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5031 : return op0;
5032 697892 : tem = simplify_associative_operation (code, mode, op0, op1);
5033 697892 : if (tem)
5034 : return tem;
5035 : break;
5036 :
5037 346417 : case UMIN:
5038 346417 : if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
5039 : return op1;
5040 346405 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5041 : return op0;
5042 346287 : tem = simplify_associative_operation (code, mode, op0, op1);
5043 346287 : if (tem)
5044 : return tem;
5045 : break;
5046 :
5047 284287 : case UMAX:
5048 284287 : if (trueop1 == constm1_rtx && ! side_effects_p (op0))
5049 : return op1;
5050 284287 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5051 : return op0;
5052 284197 : tem = simplify_associative_operation (code, mode, op0, op1);
5053 284197 : if (tem)
5054 : return tem;
5055 : break;
5056 :
5057 12118 : case SS_PLUS:
5058 12118 : case US_PLUS:
5059 12118 : case SS_MINUS:
5060 12118 : case US_MINUS:
5061 : /* Simplify x +/- 0 to x, if possible. */
5062 12118 : if (trueop1 == CONST0_RTX (mode))
5063 : return op0;
5064 : return 0;
5065 :
5066 0 : case SS_MULT:
5067 0 : case US_MULT:
5068 : /* Simplify x * 0 to 0, if possible. */
5069 0 : if (trueop1 == CONST0_RTX (mode)
5070 0 : && !side_effects_p (op0))
5071 : return op1;
5072 :
5073 : /* Simplify x * 1 to x, if possible. */
5074 0 : if (trueop1 == CONST1_RTX (mode))
5075 : return op0;
5076 : return 0;
5077 :
5078 466015 : case SMUL_HIGHPART:
5079 466015 : case UMUL_HIGHPART:
5080 : /* Simplify x * 0 to 0, if possible. */
5081 466015 : if (trueop1 == CONST0_RTX (mode)
5082 466015 : && !side_effects_p (op0))
5083 : return op1;
5084 : return 0;
5085 :
5086 0 : case SS_DIV:
5087 0 : case US_DIV:
5088 : /* Simplify x / 1 to x, if possible. */
5089 0 : if (trueop1 == CONST1_RTX (mode))
5090 : return op0;
5091 : return 0;
5092 :
5093 0 : case COPYSIGN:
5094 0 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5095 : return op0;
5096 0 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1))
5097 : {
5098 0 : REAL_VALUE_TYPE f1;
5099 0 : real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (trueop1));
5100 0 : rtx tmp = simplify_gen_unary (ABS, mode, op0, mode);
5101 0 : if (REAL_VALUE_NEGATIVE (f1))
5102 0 : tmp = simplify_unary_operation (NEG, mode, tmp, mode);
5103 0 : return tmp;
5104 : }
5105 0 : if (GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
5106 0 : return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
5107 0 : if (GET_CODE (op1) == ABS
5108 0 : && ! side_effects_p (op1))
5109 0 : return simplify_gen_unary (ABS, mode, op0, mode);
5110 0 : if (GET_CODE (op0) == COPYSIGN
5111 0 : && ! side_effects_p (XEXP (op0, 1)))
5112 0 : return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
5113 0 : if (GET_CODE (op1) == COPYSIGN
5114 0 : && ! side_effects_p (XEXP (op1, 0)))
5115 0 : return simplify_gen_binary (COPYSIGN, mode, op0, XEXP (op1, 1));
5116 : return 0;
5117 :
5118 1116 : case VEC_SERIES:
5119 2232 : if (op1 == CONST0_RTX (GET_MODE_INNER (mode)))
5120 92 : return gen_vec_duplicate (mode, op0);
5121 1024 : if (valid_for_const_vector_p (mode, op0)
5122 1024 : && valid_for_const_vector_p (mode, op1))
5123 93 : return gen_const_vec_series (mode, op0, op1);
5124 : return 0;
5125 :
5126 3528150 : case VEC_SELECT:
5127 3528150 : if (!VECTOR_MODE_P (mode))
5128 : {
5129 988865 : gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
5130 1977730 : gcc_assert (mode == GET_MODE_INNER (GET_MODE (trueop0)));
5131 988865 : gcc_assert (GET_CODE (trueop1) == PARALLEL);
5132 988865 : gcc_assert (XVECLEN (trueop1, 0) == 1);
5133 :
5134 : /* We can't reason about selections made at runtime. */
5135 988865 : if (!CONST_INT_P (XVECEXP (trueop1, 0, 0)))
5136 455504172 : return 0;
5137 :
5138 988865 : if (vec_duplicate_p (trueop0, &elt0))
5139 2097 : return elt0;
5140 :
5141 986768 : if (GET_CODE (trueop0) == CONST_VECTOR)
5142 7247 : return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP
5143 : (trueop1, 0, 0)));
5144 :
5145 : /* Extract a scalar element from a nested VEC_SELECT expression
5146 : (with optional nested VEC_CONCAT expression). Some targets
5147 : (i386) extract scalar element from a vector using chain of
5148 : nested VEC_SELECT expressions. When input operand is a memory
5149 : operand, this operation can be simplified to a simple scalar
5150 : load from an offsetted memory address. */
5151 979521 : int n_elts;
5152 979521 : if (GET_CODE (trueop0) == VEC_SELECT
5153 1055438 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
5154 75917 : .is_constant (&n_elts)))
5155 : {
5156 75917 : rtx op0 = XEXP (trueop0, 0);
5157 75917 : rtx op1 = XEXP (trueop0, 1);
5158 :
5159 75917 : int i = INTVAL (XVECEXP (trueop1, 0, 0));
5160 75917 : int elem;
5161 :
5162 75917 : rtvec vec;
5163 75917 : rtx tmp_op, tmp;
5164 :
5165 75917 : gcc_assert (GET_CODE (op1) == PARALLEL);
5166 75917 : gcc_assert (i < XVECLEN (op1, 0));
5167 :
5168 : /* Select element, pointed by nested selector. */
5169 75917 : elem = INTVAL (XVECEXP (op1, 0, i));
5170 :
5171 75917 : gcc_assert (elem < n_elts);
5172 :
5173 : /* Handle the case when nested VEC_SELECT wraps VEC_CONCAT. */
5174 75917 : if (GET_CODE (op0) == VEC_CONCAT)
5175 : {
5176 30761 : rtx op00 = XEXP (op0, 0);
5177 30761 : rtx op01 = XEXP (op0, 1);
5178 :
5179 30761 : machine_mode mode00, mode01;
5180 30761 : int n_elts00, n_elts01;
5181 :
5182 30761 : mode00 = GET_MODE (op00);
5183 30761 : mode01 = GET_MODE (op01);
5184 :
5185 : /* Find out the number of elements of each operand.
5186 : Since the concatenated result has a constant number
5187 : of elements, the operands must too. */
5188 30761 : n_elts00 = GET_MODE_NUNITS (mode00).to_constant ();
5189 30761 : n_elts01 = GET_MODE_NUNITS (mode01).to_constant ();
5190 :
5191 30761 : gcc_assert (n_elts == n_elts00 + n_elts01);
5192 :
5193 : /* Select correct operand of VEC_CONCAT
5194 : and adjust selector. */
5195 30761 : if (elem < n_elts01)
5196 : tmp_op = op00;
5197 : else
5198 : {
5199 45 : tmp_op = op01;
5200 45 : elem -= n_elts00;
5201 : }
5202 : }
5203 : else
5204 : tmp_op = op0;
5205 :
5206 75917 : vec = rtvec_alloc (1);
5207 75917 : RTVEC_ELT (vec, 0) = GEN_INT (elem);
5208 :
5209 75917 : tmp = gen_rtx_fmt_ee (code, mode,
5210 : tmp_op, gen_rtx_PARALLEL (VOIDmode, vec));
5211 75917 : return tmp;
5212 : }
5213 : }
5214 : else
5215 : {
5216 2539285 : gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
5217 7617855 : gcc_assert (GET_MODE_INNER (mode)
5218 : == GET_MODE_INNER (GET_MODE (trueop0)));
5219 2539285 : gcc_assert (GET_CODE (trueop1) == PARALLEL);
5220 :
5221 2539285 : if (vec_duplicate_p (trueop0, &elt0))
5222 : /* It doesn't matter which elements are selected by trueop1,
5223 : because they are all the same. */
5224 15982 : return gen_vec_duplicate (mode, elt0);
5225 :
5226 2523303 : if (GET_CODE (trueop0) == CONST_VECTOR)
5227 : {
5228 17581 : unsigned n_elts = XVECLEN (trueop1, 0);
5229 17581 : rtvec v = rtvec_alloc (n_elts);
5230 17581 : unsigned int i;
5231 :
5232 35162 : gcc_assert (known_eq (n_elts, GET_MODE_NUNITS (mode)));
5233 82055 : for (i = 0; i < n_elts; i++)
5234 : {
5235 64474 : rtx x = XVECEXP (trueop1, 0, i);
5236 :
5237 64474 : if (!CONST_INT_P (x))
5238 : return 0;
5239 :
5240 64474 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0,
5241 : INTVAL (x));
5242 : }
5243 :
5244 17581 : return gen_rtx_CONST_VECTOR (mode, v);
5245 : }
5246 :
5247 : /* Recognize the identity. */
5248 2505722 : if (GET_MODE (trueop0) == mode)
5249 : {
5250 599912 : bool maybe_ident = true;
5251 599912 : for (int i = 0; i < XVECLEN (trueop1, 0); i++)
5252 : {
5253 599504 : rtx j = XVECEXP (trueop1, 0, i);
5254 599504 : if (!CONST_INT_P (j) || INTVAL (j) != i)
5255 : {
5256 : maybe_ident = false;
5257 : break;
5258 : }
5259 : }
5260 372141 : if (maybe_ident)
5261 : return trueop0;
5262 : }
5263 :
5264 : /* If we select a low-part subreg, return that. */
5265 2505314 : if (vec_series_lowpart_p (mode, GET_MODE (trueop0), trueop1))
5266 : {
5267 0 : rtx new_rtx = lowpart_subreg (mode, trueop0,
5268 0 : GET_MODE (trueop0));
5269 0 : if (new_rtx != NULL_RTX)
5270 : return new_rtx;
5271 : }
5272 :
5273 : /* If we build {a,b} then permute it, build the result directly. */
5274 2505314 : if (XVECLEN (trueop1, 0) == 2
5275 598741 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
5276 598741 : && CONST_INT_P (XVECEXP (trueop1, 0, 1))
5277 598741 : && GET_CODE (trueop0) == VEC_CONCAT
5278 181103 : && GET_CODE (XEXP (trueop0, 0)) == VEC_CONCAT
5279 106 : && GET_MODE (XEXP (trueop0, 0)) == mode
5280 106 : && GET_CODE (XEXP (trueop0, 1)) == VEC_CONCAT
5281 80 : && GET_MODE (XEXP (trueop0, 1)) == mode)
5282 : {
5283 80 : unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5284 80 : unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
5285 80 : rtx subop0, subop1;
5286 :
5287 80 : gcc_assert (i0 < 4 && i1 < 4);
5288 80 : subop0 = XEXP (XEXP (trueop0, i0 / 2), i0 % 2);
5289 80 : subop1 = XEXP (XEXP (trueop0, i1 / 2), i1 % 2);
5290 :
5291 80 : return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
5292 : }
5293 :
5294 2505234 : if (XVECLEN (trueop1, 0) == 2
5295 598661 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
5296 598661 : && CONST_INT_P (XVECEXP (trueop1, 0, 1))
5297 598661 : && GET_CODE (trueop0) == VEC_CONCAT
5298 181023 : && GET_MODE (trueop0) == mode)
5299 : {
5300 2 : unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5301 2 : unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
5302 2 : rtx subop0, subop1;
5303 :
5304 2 : gcc_assert (i0 < 2 && i1 < 2);
5305 2 : subop0 = XEXP (trueop0, i0);
5306 2 : subop1 = XEXP (trueop0, i1);
5307 :
5308 2 : return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
5309 : }
5310 :
5311 : /* If we select one half of a vec_concat, return that. */
5312 2505232 : int l0, l1;
5313 2505232 : if (GET_CODE (trueop0) == VEC_CONCAT
5314 3108256 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
5315 1554128 : .is_constant (&l0))
5316 3108256 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 1)))
5317 1554128 : .is_constant (&l1))
5318 4059360 : && CONST_INT_P (XVECEXP (trueop1, 0, 0)))
5319 : {
5320 1554128 : rtx subop0 = XEXP (trueop0, 0);
5321 1554128 : rtx subop1 = XEXP (trueop0, 1);
5322 1554128 : machine_mode mode0 = GET_MODE (subop0);
5323 1554128 : machine_mode mode1 = GET_MODE (subop1);
5324 1554128 : int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5325 1554128 : if (i0 == 0 && !side_effects_p (op1) && mode == mode0)
5326 : {
5327 991598 : bool success = true;
5328 991598 : for (int i = 1; i < l0; ++i)
5329 : {
5330 991269 : rtx j = XVECEXP (trueop1, 0, i);
5331 991269 : if (!CONST_INT_P (j) || INTVAL (j) != i)
5332 : {
5333 : success = false;
5334 : break;
5335 : }
5336 : }
5337 906411 : if (success)
5338 : return subop0;
5339 : }
5340 1553799 : if (i0 == l0 && !side_effects_p (op0) && mode == mode1)
5341 : {
5342 590 : bool success = true;
5343 590 : for (int i = 1; i < l1; ++i)
5344 : {
5345 543 : rtx j = XVECEXP (trueop1, 0, i);
5346 543 : if (!CONST_INT_P (j) || INTVAL (j) != i0 + i)
5347 : {
5348 : success = false;
5349 : break;
5350 : }
5351 : }
5352 76 : if (success)
5353 : return subop1;
5354 : }
5355 : }
5356 :
5357 : /* Simplify vec_select of a subreg of X to just a vec_select of X
5358 : when X has same component mode as vec_select. */
5359 2504856 : unsigned HOST_WIDE_INT subreg_offset = 0;
5360 2504856 : if (GET_CODE (trueop0) == SUBREG
5361 367367 : && GET_MODE_INNER (mode)
5362 734734 : == GET_MODE_INNER (GET_MODE (SUBREG_REG (trueop0)))
5363 29586 : && GET_MODE_NUNITS (mode).is_constant (&l1)
5364 2872223 : && constant_multiple_p (subreg_memory_offset (trueop0),
5365 29586 : GET_MODE_UNIT_BITSIZE (mode),
5366 : &subreg_offset))
5367 : {
5368 14793 : poly_uint64 nunits
5369 29586 : = GET_MODE_NUNITS (GET_MODE (SUBREG_REG (trueop0)));
5370 14793 : bool success = true;
5371 91529 : for (int i = 0; i != l1; i++)
5372 : {
5373 87085 : rtx idx = XVECEXP (trueop1, 0, i);
5374 87085 : if (!CONST_INT_P (idx)
5375 87085 : || maybe_ge (UINTVAL (idx) + subreg_offset, nunits))
5376 : {
5377 : success = false;
5378 : break;
5379 : }
5380 : }
5381 :
5382 14793 : if (success)
5383 : {
5384 4444 : rtx par = trueop1;
5385 4444 : if (subreg_offset)
5386 : {
5387 0 : rtvec vec = rtvec_alloc (l1);
5388 0 : for (int i = 0; i < l1; i++)
5389 0 : RTVEC_ELT (vec, i)
5390 0 : = GEN_INT (INTVAL (XVECEXP (trueop1, 0, i))
5391 : + subreg_offset);
5392 0 : par = gen_rtx_PARALLEL (VOIDmode, vec);
5393 : }
5394 4444 : return gen_rtx_VEC_SELECT (mode, SUBREG_REG (trueop0), par);
5395 : }
5396 : }
5397 : }
5398 :
5399 3404016 : if (XVECLEN (trueop1, 0) == 1
5400 903688 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
5401 903688 : && GET_CODE (trueop0) == VEC_CONCAT)
5402 : {
5403 1312 : rtx vec = trueop0;
5404 2624 : offset = INTVAL (XVECEXP (trueop1, 0, 0)) * GET_MODE_SIZE (mode);
5405 :
5406 : /* Try to find the element in the VEC_CONCAT. */
5407 1312 : while (GET_MODE (vec) != mode
5408 2624 : && GET_CODE (vec) == VEC_CONCAT)
5409 : {
5410 1312 : poly_int64 vec_size;
5411 :
5412 1312 : if (CONST_INT_P (XEXP (vec, 0)))
5413 : {
5414 : /* vec_concat of two const_ints doesn't make sense with
5415 : respect to modes. */
5416 3 : if (CONST_INT_P (XEXP (vec, 1)))
5417 390825100 : return 0;
5418 :
5419 3 : vec_size = GET_MODE_SIZE (GET_MODE (trueop0))
5420 9 : - GET_MODE_SIZE (GET_MODE (XEXP (vec, 1)));
5421 : }
5422 : else
5423 2618 : vec_size = GET_MODE_SIZE (GET_MODE (XEXP (vec, 0)));
5424 :
5425 1312 : if (known_lt (offset, vec_size))
5426 : vec = XEXP (vec, 0);
5427 246 : else if (known_ge (offset, vec_size))
5428 : {
5429 246 : offset -= vec_size;
5430 246 : vec = XEXP (vec, 1);
5431 : }
5432 : else
5433 : break;
5434 1312 : vec = avoid_constant_pool_reference (vec);
5435 : }
5436 :
5437 1312 : if (GET_MODE (vec) == mode)
5438 : return vec;
5439 : }
5440 :
5441 : /* If we select elements in a vec_merge that all come from the same
5442 : operand, select from that operand directly. */
5443 3402884 : if (GET_CODE (op0) == VEC_MERGE)
5444 : {
5445 9889 : rtx trueop02 = avoid_constant_pool_reference (XEXP (op0, 2));
5446 9889 : if (CONST_INT_P (trueop02))
5447 : {
5448 3071 : unsigned HOST_WIDE_INT sel = UINTVAL (trueop02);
5449 3071 : bool all_operand0 = true;
5450 3071 : bool all_operand1 = true;
5451 11350 : for (int i = 0; i < XVECLEN (trueop1, 0); i++)
5452 : {
5453 8279 : rtx j = XVECEXP (trueop1, 0, i);
5454 8279 : if (sel & (HOST_WIDE_INT_1U << UINTVAL (j)))
5455 : all_operand1 = false;
5456 : else
5457 3791 : all_operand0 = false;
5458 : }
5459 3071 : if (all_operand0 && !side_effects_p (XEXP (op0, 1)))
5460 1443 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 0), op1);
5461 1628 : if (all_operand1 && !side_effects_p (XEXP (op0, 0)))
5462 47 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 1), op1);
5463 : }
5464 : }
5465 :
5466 : /* If we have two nested selects that are inverses of each
5467 : other, replace them with the source operand. */
5468 3401394 : if (GET_CODE (trueop0) == VEC_SELECT
5469 69456 : && GET_MODE (XEXP (trueop0, 0)) == mode)
5470 : {
5471 1040 : rtx op0_subop1 = XEXP (trueop0, 1);
5472 1040 : gcc_assert (GET_CODE (op0_subop1) == PARALLEL);
5473 2080 : gcc_assert (known_eq (XVECLEN (trueop1, 0), GET_MODE_NUNITS (mode)));
5474 : bool identical_p = true;
5475 :
5476 : /* Apply the outer ordering vector to the inner one. (The inner
5477 : ordering vector is expressly permitted to be of a different
5478 : length than the outer one.) If the result is { 0, 1, ..., n-1 }
5479 : then the two VEC_SELECTs cancel. */
5480 8996 : for (int i = 0; i < XVECLEN (trueop1, 0); ++i)
5481 : {
5482 7956 : rtx x = XVECEXP (trueop1, 0, i);
5483 7956 : if (!CONST_INT_P (x))
5484 : return 0;
5485 7956 : rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
5486 7956 : if (!CONST_INT_P (y))
5487 : return 0;
5488 7956 : if (i != INTVAL (y))
5489 5884 : identical_p = false;
5490 : }
5491 1040 : if (identical_p)
5492 : return XEXP (trueop0, 0);
5493 :
5494 : /* Otherwise a permutation of a permutation is a permutation. */
5495 1040 : int len = XVECLEN (trueop1, 0);
5496 1040 : rtvec vec = rtvec_alloc (len);
5497 8996 : for (int i = 0; i < len; ++i)
5498 : {
5499 7956 : rtx x = XVECEXP (trueop1, 0, i);
5500 7956 : rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
5501 7956 : RTVEC_ELT (vec, i) = y;
5502 : }
5503 1040 : return gen_rtx_fmt_ee (code, mode, XEXP (trueop0, 0),
5504 : gen_rtx_PARALLEL (VOIDmode, vec));
5505 : }
5506 :
5507 : return 0;
5508 4224875 : case VEC_CONCAT:
5509 4224875 : {
5510 4224875 : machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
5511 4224875 : ? GET_MODE (trueop0)
5512 4224875 : : GET_MODE_INNER (mode));
5513 4224875 : machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
5514 4224875 : ? GET_MODE (trueop1)
5515 4224875 : : GET_MODE_INNER (mode));
5516 :
5517 4224875 : gcc_assert (VECTOR_MODE_P (mode));
5518 16899500 : gcc_assert (known_eq (GET_MODE_SIZE (op0_mode)
5519 : + GET_MODE_SIZE (op1_mode),
5520 : GET_MODE_SIZE (mode)));
5521 :
5522 4224875 : if (VECTOR_MODE_P (op0_mode))
5523 5853951 : gcc_assert (GET_MODE_INNER (mode)
5524 : == GET_MODE_INNER (op0_mode));
5525 : else
5526 4547116 : gcc_assert (GET_MODE_INNER (mode) == op0_mode);
5527 :
5528 4224875 : if (VECTOR_MODE_P (op1_mode))
5529 5853951 : gcc_assert (GET_MODE_INNER (mode)
5530 : == GET_MODE_INNER (op1_mode));
5531 : else
5532 4547116 : gcc_assert (GET_MODE_INNER (mode) == op1_mode);
5533 :
5534 4224875 : unsigned int n_elts, in_n_elts;
5535 4224875 : if ((GET_CODE (trueop0) == CONST_VECTOR
5536 4224875 : || CONST_SCALAR_INT_P (trueop0)
5537 4059224 : || CONST_DOUBLE_AS_FLOAT_P (trueop0))
5538 167352 : && (GET_CODE (trueop1) == CONST_VECTOR
5539 167352 : || CONST_SCALAR_INT_P (trueop1)
5540 167352 : || CONST_DOUBLE_AS_FLOAT_P (trueop1))
5541 0 : && GET_MODE_NUNITS (mode).is_constant (&n_elts)
5542 4224875 : && GET_MODE_NUNITS (op0_mode).is_constant (&in_n_elts))
5543 : {
5544 0 : rtvec v = rtvec_alloc (n_elts);
5545 0 : unsigned int i;
5546 0 : for (i = 0; i < n_elts; i++)
5547 : {
5548 0 : if (i < in_n_elts)
5549 : {
5550 0 : if (!VECTOR_MODE_P (op0_mode))
5551 0 : RTVEC_ELT (v, i) = trueop0;
5552 : else
5553 0 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
5554 : }
5555 : else
5556 : {
5557 0 : if (!VECTOR_MODE_P (op1_mode))
5558 0 : RTVEC_ELT (v, i) = trueop1;
5559 : else
5560 0 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
5561 : i - in_n_elts);
5562 : }
5563 : }
5564 :
5565 0 : return gen_rtx_CONST_VECTOR (mode, v);
5566 : }
5567 :
5568 : /* Try to merge two VEC_SELECTs from the same vector into a single one.
5569 : Restrict the transformation to avoid generating a VEC_SELECT with a
5570 : mode unrelated to its operand. */
5571 4224875 : if (GET_CODE (trueop0) == VEC_SELECT
5572 133695 : && GET_CODE (trueop1) == VEC_SELECT
5573 28629 : && rtx_equal_p (XEXP (trueop0, 0), XEXP (trueop1, 0))
5574 4240981 : && GET_MODE_INNER (GET_MODE (XEXP (trueop0, 0)))
5575 32212 : == GET_MODE_INNER(mode))
5576 : {
5577 16106 : rtx par0 = XEXP (trueop0, 1);
5578 16106 : rtx par1 = XEXP (trueop1, 1);
5579 16106 : int len0 = XVECLEN (par0, 0);
5580 16106 : int len1 = XVECLEN (par1, 0);
5581 16106 : rtvec vec = rtvec_alloc (len0 + len1);
5582 99613 : for (int i = 0; i < len0; i++)
5583 83507 : RTVEC_ELT (vec, i) = XVECEXP (par0, 0, i);
5584 99613 : for (int i = 0; i < len1; i++)
5585 83507 : RTVEC_ELT (vec, len0 + i) = XVECEXP (par1, 0, i);
5586 16106 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (trueop0, 0),
5587 16106 : gen_rtx_PARALLEL (VOIDmode, vec));
5588 : }
5589 : /* (vec_concat:
5590 : (subreg_lowpart:N OP)
5591 : (vec_select:N OP P)) --> OP when P selects the high half
5592 : of the OP. */
5593 4208769 : if (GET_CODE (trueop0) == SUBREG
5594 503651 : && subreg_lowpart_p (trueop0)
5595 503444 : && GET_CODE (trueop1) == VEC_SELECT
5596 3 : && SUBREG_REG (trueop0) == XEXP (trueop1, 0)
5597 0 : && !side_effects_p (XEXP (trueop1, 0))
5598 4208769 : && vec_series_highpart_p (op1_mode, mode, XEXP (trueop1, 1)))
5599 0 : return XEXP (trueop1, 0);
5600 : }
5601 : return 0;
5602 :
5603 0 : default:
5604 0 : gcc_unreachable ();
5605 : }
5606 :
5607 382736963 : if (mode == GET_MODE (op0)
5608 328259997 : && mode == GET_MODE (op1)
5609 104440612 : && vec_duplicate_p (op0, &elt0)
5610 382860376 : && vec_duplicate_p (op1, &elt1))
5611 : {
5612 : /* Try applying the operator to ELT and see if that simplifies.
5613 : We can duplicate the result if so.
5614 :
5615 : The reason we don't use simplify_gen_binary is that it isn't
5616 : necessarily a win to convert things like:
5617 :
5618 : (plus:V (vec_duplicate:V (reg:S R1))
5619 : (vec_duplicate:V (reg:S R2)))
5620 :
5621 : to:
5622 :
5623 : (vec_duplicate:V (plus:S (reg:S R1) (reg:S R2)))
5624 :
5625 : The first might be done entirely in vector registers while the
5626 : second might need a move between register files. */
5627 132 : tem = simplify_binary_operation (code, GET_MODE_INNER (mode),
5628 : elt0, elt1);
5629 66 : if (tem)
5630 2 : return gen_vec_duplicate (mode, tem);
5631 : }
5632 :
5633 : return 0;
5634 : }
5635 :
5636 : /* Return true if binary operation OP distributes over addition in operand
5637 : OPNO, with the other operand being held constant. OPNO counts from 1. */
5638 :
5639 : static bool
5640 8291 : distributes_over_addition_p (rtx_code op, int opno)
5641 : {
5642 0 : switch (op)
5643 : {
5644 : case PLUS:
5645 : case MINUS:
5646 : case MULT:
5647 : return true;
5648 :
5649 0 : case ASHIFT:
5650 0 : return opno == 1;
5651 :
5652 0 : default:
5653 0 : return false;
5654 : }
5655 : }
5656 :
5657 : rtx
5658 489350931 : simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
5659 : rtx op0, rtx op1)
5660 : {
5661 489350931 : if (VECTOR_MODE_P (mode)
5662 15257567 : && code != VEC_CONCAT
5663 11018223 : && GET_CODE (op0) == CONST_VECTOR
5664 179519 : && GET_CODE (op1) == CONST_VECTOR)
5665 : {
5666 9006 : bool step_ok_p;
5667 9006 : if (CONST_VECTOR_STEPPED_P (op0)
5668 9006 : && CONST_VECTOR_STEPPED_P (op1))
5669 : /* We can operate directly on the encoding if:
5670 :
5671 : a3 - a2 == a2 - a1 && b3 - b2 == b2 - b1
5672 : implies
5673 : (a3 op b3) - (a2 op b2) == (a2 op b2) - (a1 op b1)
5674 :
5675 : Addition and subtraction are the supported operators
5676 : for which this is true. */
5677 715 : step_ok_p = (code == PLUS || code == MINUS);
5678 8291 : else if (CONST_VECTOR_STEPPED_P (op0))
5679 : /* We can operate directly on stepped encodings if:
5680 :
5681 : a3 - a2 == a2 - a1
5682 : implies:
5683 : (a3 op c) - (a2 op c) == (a2 op c) - (a1 op c)
5684 :
5685 : which is true if (x -> x op c) distributes over addition. */
5686 1304 : step_ok_p = distributes_over_addition_p (code, 1);
5687 : else
5688 : /* Similarly in reverse. */
5689 6987 : step_ok_p = distributes_over_addition_p (code, 2);
5690 9006 : rtx_vector_builder builder;
5691 9006 : if (!builder.new_binary_operation (mode, op0, op1, step_ok_p))
5692 : return 0;
5693 :
5694 9006 : unsigned int count = builder.encoded_nelts ();
5695 54615 : for (unsigned int i = 0; i < count; i++)
5696 : {
5697 91318 : rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
5698 : CONST_VECTOR_ELT (op0, i),
5699 45659 : CONST_VECTOR_ELT (op1, i));
5700 45659 : if (!x || !valid_for_const_vector_p (mode, x))
5701 50 : return 0;
5702 45609 : builder.quick_push (x);
5703 : }
5704 8956 : return builder.build ();
5705 9006 : }
5706 :
5707 489341925 : if (VECTOR_MODE_P (mode)
5708 15248561 : && code == VEC_CONCAT
5709 4239344 : && (CONST_SCALAR_INT_P (op0)
5710 4082505 : || CONST_FIXED_P (op0)
5711 4082505 : || CONST_DOUBLE_AS_FLOAT_P (op0)
5712 4078439 : || CONST_VECTOR_P (op0))
5713 181821 : && (CONST_SCALAR_INT_P (op1)
5714 177428 : || CONST_DOUBLE_AS_FLOAT_P (op1)
5715 175063 : || CONST_FIXED_P (op1)
5716 175063 : || CONST_VECTOR_P (op1)))
5717 : {
5718 : /* Both inputs have a constant number of elements, so the result
5719 : must too. */
5720 14469 : unsigned n_elts = GET_MODE_NUNITS (mode).to_constant ();
5721 14469 : rtvec v = rtvec_alloc (n_elts);
5722 :
5723 14469 : gcc_assert (n_elts >= 2);
5724 14469 : if (n_elts == 2)
5725 : {
5726 6758 : gcc_assert (GET_CODE (op0) != CONST_VECTOR);
5727 6758 : gcc_assert (GET_CODE (op1) != CONST_VECTOR);
5728 :
5729 6758 : RTVEC_ELT (v, 0) = op0;
5730 6758 : RTVEC_ELT (v, 1) = op1;
5731 : }
5732 : else
5733 : {
5734 7711 : unsigned op0_n_elts = GET_MODE_NUNITS (GET_MODE (op0)).to_constant ();
5735 7711 : unsigned op1_n_elts = GET_MODE_NUNITS (GET_MODE (op1)).to_constant ();
5736 7711 : unsigned i;
5737 :
5738 7711 : gcc_assert (GET_CODE (op0) == CONST_VECTOR);
5739 7711 : gcc_assert (GET_CODE (op1) == CONST_VECTOR);
5740 7711 : gcc_assert (op0_n_elts + op1_n_elts == n_elts);
5741 :
5742 50179 : for (i = 0; i < op0_n_elts; ++i)
5743 42468 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op0, i);
5744 50371 : for (i = 0; i < op1_n_elts; ++i)
5745 42660 : RTVEC_ELT (v, op0_n_elts+i) = CONST_VECTOR_ELT (op1, i);
5746 : }
5747 :
5748 14469 : return gen_rtx_CONST_VECTOR (mode, v);
5749 : }
5750 :
5751 477367880 : if (VECTOR_MODE_P (mode)
5752 15234092 : && GET_CODE (op0) == CONST_VECTOR
5753 183718 : && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1))
5754 489327456 : && (CONST_VECTOR_DUPLICATE_P (op0)
5755 : || CONST_VECTOR_NUNITS (op0).is_constant ()))
5756 : {
5757 120433 : switch (code)
5758 : {
5759 120433 : case PLUS:
5760 120433 : case MINUS:
5761 120433 : case MULT:
5762 120433 : case DIV:
5763 120433 : case MOD:
5764 120433 : case UDIV:
5765 120433 : case UMOD:
5766 120433 : case AND:
5767 120433 : case IOR:
5768 120433 : case XOR:
5769 120433 : case SMIN:
5770 120433 : case SMAX:
5771 120433 : case UMIN:
5772 120433 : case UMAX:
5773 120433 : case LSHIFTRT:
5774 120433 : case ASHIFTRT:
5775 120433 : case ASHIFT:
5776 120433 : case ROTATE:
5777 120433 : case ROTATERT:
5778 120433 : case SS_PLUS:
5779 120433 : case US_PLUS:
5780 120433 : case SS_MINUS:
5781 120433 : case US_MINUS:
5782 120433 : case SS_ASHIFT:
5783 120433 : case US_ASHIFT:
5784 120433 : case COPYSIGN:
5785 120433 : break;
5786 : default:
5787 : return NULL_RTX;
5788 : }
5789 :
5790 120433 : unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op0)
5791 120433 : ? CONST_VECTOR_NPATTERNS (op0)
5792 128274 : : CONST_VECTOR_NUNITS (op0).to_constant ());
5793 120433 : rtx_vector_builder builder (mode, npatterns, 1);
5794 254035 : for (unsigned i = 0; i < npatterns; i++)
5795 : {
5796 267204 : rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
5797 133602 : CONST_VECTOR_ELT (op0, i), op1);
5798 133602 : if (!x || !valid_for_const_vector_p (mode, x))
5799 0 : return 0;
5800 133602 : builder.quick_push (x);
5801 : }
5802 120433 : return builder.build ();
5803 : }
5804 :
5805 489207023 : if (SCALAR_FLOAT_MODE_P (mode)
5806 6460689 : && CONST_DOUBLE_AS_FLOAT_P (op0)
5807 76934 : && CONST_DOUBLE_AS_FLOAT_P (op1)
5808 11521 : && mode == GET_MODE (op0) && mode == GET_MODE (op1))
5809 : {
5810 11521 : if (code == AND
5811 : || code == IOR
5812 11521 : || code == XOR)
5813 : {
5814 2537 : long tmp0[4];
5815 2537 : long tmp1[4];
5816 2537 : REAL_VALUE_TYPE r;
5817 2537 : int i;
5818 :
5819 2537 : real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0),
5820 2537 : GET_MODE (op0));
5821 2537 : real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1),
5822 2537 : GET_MODE (op1));
5823 12685 : for (i = 0; i < 4; i++)
5824 : {
5825 10148 : switch (code)
5826 : {
5827 5268 : case AND:
5828 5268 : tmp0[i] &= tmp1[i];
5829 5268 : break;
5830 2512 : case IOR:
5831 2512 : tmp0[i] |= tmp1[i];
5832 2512 : break;
5833 2368 : case XOR:
5834 2368 : tmp0[i] ^= tmp1[i];
5835 2368 : break;
5836 : default:
5837 : gcc_unreachable ();
5838 : }
5839 : }
5840 2537 : real_from_target (&r, tmp0, mode);
5841 2537 : return const_double_from_real_value (r, mode);
5842 : }
5843 8984 : else if (code == COPYSIGN)
5844 : {
5845 0 : REAL_VALUE_TYPE f0, f1;
5846 0 : real_convert (&f0, mode, CONST_DOUBLE_REAL_VALUE (op0));
5847 0 : real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (op1));
5848 0 : real_copysign (&f0, &f1);
5849 0 : return const_double_from_real_value (f0, mode);
5850 : }
5851 : else
5852 : {
5853 8984 : REAL_VALUE_TYPE f0, f1, value, result;
5854 8984 : const REAL_VALUE_TYPE *opr0, *opr1;
5855 8984 : bool inexact;
5856 :
5857 8984 : opr0 = CONST_DOUBLE_REAL_VALUE (op0);
5858 8984 : opr1 = CONST_DOUBLE_REAL_VALUE (op1);
5859 :
5860 8984 : if (HONOR_SNANS (mode)
5861 8984 : && (REAL_VALUE_ISSIGNALING_NAN (*opr0)
5862 803 : || REAL_VALUE_ISSIGNALING_NAN (*opr1)))
5863 10 : return 0;
5864 :
5865 8974 : real_convert (&f0, mode, opr0);
5866 8974 : real_convert (&f1, mode, opr1);
5867 :
5868 8974 : if (code == DIV
5869 4102 : && real_equal (&f1, &dconst0)
5870 12612 : && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
5871 3634 : return 0;
5872 :
5873 26599 : if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
5874 5248 : && flag_trapping_math
5875 5170 : && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
5876 : {
5877 9 : int s0 = REAL_VALUE_NEGATIVE (f0);
5878 9 : int s1 = REAL_VALUE_NEGATIVE (f1);
5879 :
5880 9 : switch (code)
5881 : {
5882 0 : case PLUS:
5883 : /* Inf + -Inf = NaN plus exception. */
5884 0 : if (s0 != s1)
5885 : return 0;
5886 : break;
5887 0 : case MINUS:
5888 : /* Inf - Inf = NaN plus exception. */
5889 0 : if (s0 == s1)
5890 : return 0;
5891 : break;
5892 : case DIV:
5893 : /* Inf / Inf = NaN plus exception. */
5894 : return 0;
5895 : default:
5896 : break;
5897 : }
5898 : }
5899 :
5900 7904 : if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
5901 1942 : && flag_trapping_math
5902 7225 : && ((REAL_VALUE_ISINF (f0) && real_equal (&f1, &dconst0))
5903 1886 : || (REAL_VALUE_ISINF (f1)
5904 10 : && real_equal (&f0, &dconst0))))
5905 : /* Inf * 0 = NaN plus exception. */
5906 18 : return 0;
5907 :
5908 5313 : inexact = real_arithmetic (&value, rtx_to_tree_code (code),
5909 : &f0, &f1);
5910 5313 : real_convert (&result, mode, &value);
5911 :
5912 : /* Don't constant fold this floating point operation if
5913 : the result has overflowed and flag_trapping_math. */
5914 :
5915 5313 : if (flag_trapping_math
5916 20572 : && MODE_HAS_INFINITIES (mode)
5917 5143 : && REAL_VALUE_ISINF (result)
5918 1104 : && !REAL_VALUE_ISINF (f0)
5919 6403 : && !REAL_VALUE_ISINF (f1))
5920 : /* Overflow plus exception. */
5921 1090 : return 0;
5922 :
5923 : /* Don't constant fold this floating point operation if the
5924 : result may dependent upon the run-time rounding mode and
5925 : flag_rounding_math is set, or if GCC's software emulation
5926 : is unable to accurately represent the result. */
5927 :
5928 4223 : if ((flag_rounding_math
5929 26880 : || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
5930 4223 : && (inexact || !real_identical (&result, &value)))
5931 378 : return NULL_RTX;
5932 :
5933 3845 : return const_double_from_real_value (result, mode);
5934 : }
5935 : }
5936 :
5937 : /* We can fold some multi-word operations. */
5938 489195502 : scalar_int_mode int_mode;
5939 489195502 : if (is_a <scalar_int_mode> (mode, &int_mode)
5940 418929827 : && CONST_SCALAR_INT_P (op0)
5941 40783852 : && CONST_SCALAR_INT_P (op1)
5942 33698917 : && GET_MODE_PRECISION (int_mode) <= MAX_BITSIZE_MODE_ANY_INT)
5943 : {
5944 33698917 : wide_int result;
5945 33698917 : wi::overflow_type overflow;
5946 33698917 : rtx_mode_t pop0 = rtx_mode_t (op0, int_mode);
5947 33698917 : rtx_mode_t pop1 = rtx_mode_t (op1, int_mode);
5948 :
5949 : #if TARGET_SUPPORTS_WIDE_INT == 0
5950 : /* This assert keeps the simplification from producing a result
5951 : that cannot be represented in a CONST_DOUBLE but a lot of
5952 : upstream callers expect that this function never fails to
5953 : simplify something and so you if you added this to the test
5954 : above the code would die later anyway. If this assert
5955 : happens, you just need to make the port support wide int. */
5956 : gcc_assert (GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_DOUBLE_INT);
5957 : #endif
5958 33698917 : switch (code)
5959 : {
5960 1081539 : case MINUS:
5961 1081539 : result = wi::sub (pop0, pop1);
5962 1081539 : break;
5963 :
5964 26317018 : case PLUS:
5965 26317018 : result = wi::add (pop0, pop1);
5966 26317018 : break;
5967 :
5968 320572 : case MULT:
5969 320572 : result = wi::mul (pop0, pop1);
5970 320572 : break;
5971 :
5972 8325 : case DIV:
5973 8325 : result = wi::div_trunc (pop0, pop1, SIGNED, &overflow);
5974 8325 : if (overflow)
5975 : return NULL_RTX;
5976 : break;
5977 :
5978 1207 : case MOD:
5979 1207 : result = wi::mod_trunc (pop0, pop1, SIGNED, &overflow);
5980 1207 : if (overflow)
5981 : return NULL_RTX;
5982 : break;
5983 :
5984 6239 : case UDIV:
5985 6239 : result = wi::div_trunc (pop0, pop1, UNSIGNED, &overflow);
5986 6239 : if (overflow)
5987 : return NULL_RTX;
5988 : break;
5989 :
5990 16213 : case UMOD:
5991 16213 : result = wi::mod_trunc (pop0, pop1, UNSIGNED, &overflow);
5992 16213 : if (overflow)
5993 : return NULL_RTX;
5994 : break;
5995 :
5996 702544 : case AND:
5997 702544 : result = wi::bit_and (pop0, pop1);
5998 702544 : break;
5999 :
6000 287102 : case IOR:
6001 287102 : result = wi::bit_or (pop0, pop1);
6002 287102 : break;
6003 :
6004 44656 : case XOR:
6005 44656 : result = wi::bit_xor (pop0, pop1);
6006 44656 : break;
6007 :
6008 1763 : case SMIN:
6009 1763 : result = wi::smin (pop0, pop1);
6010 1763 : break;
6011 :
6012 1984 : case SMAX:
6013 1984 : result = wi::smax (pop0, pop1);
6014 1984 : break;
6015 :
6016 3222 : case UMIN:
6017 3222 : result = wi::umin (pop0, pop1);
6018 3222 : break;
6019 :
6020 2856 : case UMAX:
6021 2856 : result = wi::umax (pop0, pop1);
6022 2856 : break;
6023 :
6024 4864795 : case LSHIFTRT:
6025 4864795 : case ASHIFTRT:
6026 4864795 : case ASHIFT:
6027 4864795 : case SS_ASHIFT:
6028 4864795 : case US_ASHIFT:
6029 4864795 : {
6030 : /* The shift count might be in SImode while int_mode might
6031 : be narrower. On IA-64 it is even DImode. If the shift
6032 : count is too large and doesn't fit into int_mode, we'd
6033 : ICE. So, if int_mode is narrower than
6034 : HOST_BITS_PER_WIDE_INT, use DImode for the shift count. */
6035 4864795 : if (GET_MODE (op1) == VOIDmode
6036 4864795 : && GET_MODE_PRECISION (int_mode) < HOST_BITS_PER_WIDE_INT)
6037 1860590 : pop1 = rtx_mode_t (op1, DImode);
6038 :
6039 4864795 : wide_int wop1 = pop1;
6040 4864795 : if (SHIFT_COUNT_TRUNCATED)
6041 : wop1 = wi::umod_trunc (wop1, GET_MODE_PRECISION (int_mode));
6042 4864795 : else if (wi::geu_p (wop1, GET_MODE_PRECISION (int_mode)))
6043 132 : return NULL_RTX;
6044 :
6045 4864663 : switch (code)
6046 : {
6047 2809485 : case LSHIFTRT:
6048 2809485 : result = wi::lrshift (pop0, wop1);
6049 2809485 : break;
6050 :
6051 81032 : case ASHIFTRT:
6052 81032 : result = wi::arshift (pop0, wop1);
6053 81032 : break;
6054 :
6055 1974146 : case ASHIFT:
6056 1974146 : result = wi::lshift (pop0, wop1);
6057 1974146 : break;
6058 :
6059 0 : case SS_ASHIFT:
6060 0 : if (wi::leu_p (wop1, wi::clrsb (pop0)))
6061 0 : result = wi::lshift (pop0, wop1);
6062 0 : else if (wi::neg_p (pop0))
6063 0 : result = wi::min_value (int_mode, SIGNED);
6064 : else
6065 0 : result = wi::max_value (int_mode, SIGNED);
6066 : break;
6067 :
6068 0 : case US_ASHIFT:
6069 0 : if (wi::eq_p (pop0, 0))
6070 0 : result = pop0;
6071 0 : else if (wi::leu_p (wop1, wi::clz (pop0)))
6072 0 : result = wi::lshift (pop0, wop1);
6073 : else
6074 0 : result = wi::max_value (int_mode, UNSIGNED);
6075 : break;
6076 :
6077 0 : default:
6078 0 : gcc_unreachable ();
6079 : }
6080 4864663 : break;
6081 4864795 : }
6082 30320 : case ROTATE:
6083 30320 : case ROTATERT:
6084 30320 : {
6085 : /* The rotate count might be in SImode while int_mode might
6086 : be narrower. On IA-64 it is even DImode. If the shift
6087 : count is too large and doesn't fit into int_mode, we'd
6088 : ICE. So, if int_mode is narrower than
6089 : HOST_BITS_PER_WIDE_INT, use DImode for the shift count. */
6090 30320 : if (GET_MODE (op1) == VOIDmode
6091 30320 : && GET_MODE_PRECISION (int_mode) < HOST_BITS_PER_WIDE_INT)
6092 23932 : pop1 = rtx_mode_t (op1, DImode);
6093 :
6094 30320 : if (wi::neg_p (pop1))
6095 : return NULL_RTX;
6096 :
6097 30220 : switch (code)
6098 : {
6099 10498 : case ROTATE:
6100 10498 : result = wi::lrotate (pop0, pop1);
6101 10498 : break;
6102 :
6103 19722 : case ROTATERT:
6104 19722 : result = wi::rrotate (pop0, pop1);
6105 19722 : break;
6106 :
6107 0 : default:
6108 0 : gcc_unreachable ();
6109 : }
6110 : break;
6111 : }
6112 :
6113 2270 : case SS_PLUS:
6114 2270 : result = wi::add (pop0, pop1, SIGNED, &overflow);
6115 4484 : clamp_signed_saturation:
6116 4484 : if (overflow == wi::OVF_OVERFLOW)
6117 314 : result = wi::max_value (GET_MODE_PRECISION (int_mode), SIGNED);
6118 4170 : else if (overflow == wi::OVF_UNDERFLOW)
6119 278 : result = wi::min_value (GET_MODE_PRECISION (int_mode), SIGNED);
6120 3892 : else if (overflow != wi::OVF_NONE)
6121 : return NULL_RTX;
6122 : break;
6123 :
6124 2220 : case US_PLUS:
6125 2220 : result = wi::add (pop0, pop1, UNSIGNED, &overflow);
6126 2220 : clamp_unsigned_saturation:
6127 2220 : if (overflow != wi::OVF_NONE)
6128 461 : result = wi::max_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
6129 : break;
6130 :
6131 2214 : case SS_MINUS:
6132 2214 : result = wi::sub (pop0, pop1, SIGNED, &overflow);
6133 2214 : goto clamp_signed_saturation;
6134 :
6135 1852 : case US_MINUS:
6136 1852 : result = wi::sub (pop0, pop1, UNSIGNED, &overflow);
6137 1852 : if (overflow != wi::OVF_NONE)
6138 1203 : result = wi::min_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
6139 : break;
6140 :
6141 0 : case SS_MULT:
6142 0 : result = wi::mul (pop0, pop1, SIGNED, &overflow);
6143 0 : goto clamp_signed_saturation;
6144 :
6145 0 : case US_MULT:
6146 0 : result = wi::mul (pop0, pop1, UNSIGNED, &overflow);
6147 0 : goto clamp_unsigned_saturation;
6148 :
6149 6 : case SMUL_HIGHPART:
6150 6 : result = wi::mul_high (pop0, pop1, SIGNED);
6151 6 : break;
6152 :
6153 0 : case UMUL_HIGHPART:
6154 0 : result = wi::mul_high (pop0, pop1, UNSIGNED);
6155 0 : break;
6156 :
6157 : default:
6158 : return NULL_RTX;
6159 : }
6160 33696519 : return immed_wide_int_const (result, int_mode);
6161 33698917 : }
6162 :
6163 : /* Handle polynomial integers. */
6164 : if (NUM_POLY_INT_COEFFS > 1
6165 : && is_a <scalar_int_mode> (mode, &int_mode)
6166 : && poly_int_rtx_p (op0)
6167 : && poly_int_rtx_p (op1))
6168 : {
6169 : poly_wide_int result;
6170 : switch (code)
6171 : {
6172 : case PLUS:
6173 : result = wi::to_poly_wide (op0, mode) + wi::to_poly_wide (op1, mode);
6174 : break;
6175 :
6176 : case MINUS:
6177 : result = wi::to_poly_wide (op0, mode) - wi::to_poly_wide (op1, mode);
6178 : break;
6179 :
6180 : case MULT:
6181 : if (CONST_SCALAR_INT_P (op1))
6182 : result = wi::to_poly_wide (op0, mode) * rtx_mode_t (op1, mode);
6183 : else
6184 : return NULL_RTX;
6185 : break;
6186 :
6187 : case ASHIFT:
6188 : if (CONST_SCALAR_INT_P (op1))
6189 : {
6190 : wide_int shift
6191 : = rtx_mode_t (op1,
6192 : GET_MODE (op1) == VOIDmode
6193 : && (GET_MODE_PRECISION (int_mode)
6194 : < HOST_BITS_PER_WIDE_INT)
6195 : ? DImode : mode);
6196 : if (SHIFT_COUNT_TRUNCATED)
6197 : shift = wi::umod_trunc (shift, GET_MODE_PRECISION (int_mode));
6198 : else if (wi::geu_p (shift, GET_MODE_PRECISION (int_mode)))
6199 : return NULL_RTX;
6200 : result = wi::to_poly_wide (op0, mode) << shift;
6201 : }
6202 : else
6203 : return NULL_RTX;
6204 : break;
6205 :
6206 : case IOR:
6207 : if (!CONST_SCALAR_INT_P (op1)
6208 : || !can_ior_p (wi::to_poly_wide (op0, mode),
6209 : rtx_mode_t (op1, mode), &result))
6210 : return NULL_RTX;
6211 : break;
6212 :
6213 : default:
6214 : return NULL_RTX;
6215 : }
6216 : return immed_wide_int_const (result, int_mode);
6217 : }
6218 :
6219 : return NULL_RTX;
6220 : }
6221 :
6222 :
6223 :
6224 : /* Return a positive integer if X should sort after Y. The value
6225 : returned is 1 if and only if X and Y are both regs. */
6226 :
6227 : static int
6228 116415184 : simplify_plus_minus_op_data_cmp (rtx x, rtx y)
6229 : {
6230 116415184 : int result;
6231 :
6232 116415184 : result = (commutative_operand_precedence (y)
6233 116415184 : - commutative_operand_precedence (x));
6234 116415184 : if (result)
6235 81250385 : return result + result;
6236 :
6237 : /* Group together equal REGs to do more simplification. */
6238 35164799 : if (REG_P (x) && REG_P (y))
6239 8783137 : return REGNO (x) > REGNO (y);
6240 :
6241 : return 0;
6242 : }
6243 :
6244 : /* Simplify and canonicalize a PLUS or MINUS, at least one of whose
6245 : operands may be another PLUS or MINUS.
6246 :
6247 : Rather than test for specific case, we do this by a brute-force method
6248 : and do all possible simplifications until no more changes occur. Then
6249 : we rebuild the operation.
6250 :
6251 : May return NULL_RTX when no changes were made. */
6252 :
6253 : rtx
6254 39251794 : simplify_context::simplify_plus_minus (rtx_code code, machine_mode mode,
6255 : rtx op0, rtx op1)
6256 : {
6257 39251794 : struct simplify_plus_minus_op_data
6258 : {
6259 : rtx op;
6260 : short neg;
6261 : } ops[16];
6262 39251794 : rtx result, tem;
6263 39251794 : int n_ops = 2;
6264 39251794 : int changed, n_constants, canonicalized = 0;
6265 39251794 : int i, j;
6266 :
6267 39251794 : memset (ops, 0, sizeof ops);
6268 :
6269 : /* Set up the two operands and then expand them until nothing has been
6270 : changed. If we run out of room in our array, give up; this should
6271 : almost never happen. */
6272 :
6273 39251794 : ops[0].op = op0;
6274 39251794 : ops[0].neg = 0;
6275 39251794 : ops[1].op = op1;
6276 39251794 : ops[1].neg = (code == MINUS);
6277 :
6278 79801619 : do
6279 : {
6280 79801619 : changed = 0;
6281 79801619 : n_constants = 0;
6282 :
6283 322992953 : for (i = 0; i < n_ops; i++)
6284 : {
6285 243191350 : rtx this_op = ops[i].op;
6286 243191350 : int this_neg = ops[i].neg;
6287 243191350 : enum rtx_code this_code = GET_CODE (this_op);
6288 :
6289 243191350 : switch (this_code)
6290 : {
6291 39553419 : case PLUS:
6292 39553419 : case MINUS:
6293 39553419 : if (n_ops == ARRAY_SIZE (ops))
6294 : return NULL_RTX;
6295 :
6296 39553403 : ops[n_ops].op = XEXP (this_op, 1);
6297 39553403 : ops[n_ops].neg = (this_code == MINUS) ^ this_neg;
6298 39553403 : n_ops++;
6299 :
6300 39553403 : ops[i].op = XEXP (this_op, 0);
6301 39553403 : changed = 1;
6302 : /* If this operand was negated then we will potentially
6303 : canonicalize the expression. Similarly if we don't
6304 : place the operands adjacent we're re-ordering the
6305 : expression and thus might be performing a
6306 : canonicalization. Ignore register re-ordering.
6307 : ??? It might be better to shuffle the ops array here,
6308 : but then (plus (plus (A, B), plus (C, D))) wouldn't
6309 : be seen as non-canonical. */
6310 39553403 : if (this_neg
6311 38853267 : || (i != n_ops - 2
6312 38172773 : && !(REG_P (ops[i].op) && REG_P (ops[n_ops - 1].op))))
6313 243191334 : canonicalized = 1;
6314 : break;
6315 :
6316 1865 : case NEG:
6317 1865 : ops[i].op = XEXP (this_op, 0);
6318 1865 : ops[i].neg = ! this_neg;
6319 1865 : changed = 1;
6320 1865 : canonicalized = 1;
6321 1865 : break;
6322 :
6323 1621883 : case CONST:
6324 1621883 : if (n_ops != ARRAY_SIZE (ops)
6325 1621883 : && GET_CODE (XEXP (this_op, 0)) == PLUS
6326 1488643 : && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
6327 1467821 : && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
6328 : {
6329 1467821 : ops[i].op = XEXP (XEXP (this_op, 0), 0);
6330 1467821 : ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
6331 1467821 : ops[n_ops].neg = this_neg;
6332 1467821 : n_ops++;
6333 1467821 : changed = 1;
6334 1467821 : canonicalized = 1;
6335 : }
6336 : break;
6337 :
6338 67210 : case NOT:
6339 : /* ~a -> (-a - 1) */
6340 67210 : if (n_ops != ARRAY_SIZE (ops))
6341 : {
6342 67210 : ops[n_ops].op = CONSTM1_RTX (mode);
6343 67210 : ops[n_ops++].neg = this_neg;
6344 67210 : ops[i].op = XEXP (this_op, 0);
6345 67210 : ops[i].neg = !this_neg;
6346 67210 : changed = 1;
6347 67210 : canonicalized = 1;
6348 : }
6349 : break;
6350 :
6351 120924631 : CASE_CONST_SCALAR_INT:
6352 120924631 : case CONST_POLY_INT:
6353 120924631 : n_constants++;
6354 120924631 : if (this_neg)
6355 : {
6356 1207120 : ops[i].op = neg_poly_int_rtx (mode, this_op);
6357 1207120 : ops[i].neg = 0;
6358 1207120 : changed = 1;
6359 1207120 : canonicalized = 1;
6360 : }
6361 : break;
6362 :
6363 : default:
6364 : break;
6365 : }
6366 : }
6367 : }
6368 79801603 : while (changed);
6369 :
6370 39251778 : if (n_constants > 1)
6371 23929932 : canonicalized = 1;
6372 :
6373 39251778 : gcc_assert (n_ops >= 2);
6374 :
6375 : /* If we only have two operands, we can avoid the loops. */
6376 39251778 : if (n_ops == 2)
6377 : {
6378 0 : enum rtx_code code = ops[0].neg || ops[1].neg ? MINUS : PLUS;
6379 0 : rtx lhs, rhs;
6380 :
6381 : /* Get the two operands. Be careful with the order, especially for
6382 : the cases where code == MINUS. */
6383 0 : if (ops[0].neg && ops[1].neg)
6384 : {
6385 0 : lhs = gen_rtx_NEG (mode, ops[0].op);
6386 0 : rhs = ops[1].op;
6387 : }
6388 0 : else if (ops[0].neg)
6389 : {
6390 0 : lhs = ops[1].op;
6391 0 : rhs = ops[0].op;
6392 : }
6393 : else
6394 : {
6395 0 : lhs = ops[0].op;
6396 0 : rhs = ops[1].op;
6397 : }
6398 :
6399 0 : return simplify_const_binary_operation (code, mode, lhs, rhs);
6400 : }
6401 :
6402 : /* Now simplify each pair of operands until nothing changes. */
6403 64198192 : while (1)
6404 : {
6405 : /* Insertion sort is good enough for a small array. */
6406 169919882 : for (i = 1; i < n_ops; i++)
6407 : {
6408 105721690 : struct simplify_plus_minus_op_data save;
6409 105721690 : int cmp;
6410 :
6411 105721690 : j = i - 1;
6412 105721690 : cmp = simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op);
6413 105721690 : if (cmp <= 0)
6414 92899466 : continue;
6415 : /* Just swapping registers doesn't count as canonicalization. */
6416 12822224 : if (cmp != 1)
6417 9796516 : canonicalized = 1;
6418 :
6419 12822224 : save = ops[i];
6420 15191581 : do
6421 15191581 : ops[j + 1] = ops[j];
6422 15191581 : while (j--
6423 28013805 : && simplify_plus_minus_op_data_cmp (ops[j].op, save.op) > 0);
6424 12822224 : ops[j + 1] = save;
6425 : }
6426 :
6427 64198192 : changed = 0;
6428 169919882 : for (i = n_ops - 1; i > 0; i--)
6429 253608051 : for (j = i - 1; j >= 0; j--)
6430 : {
6431 148800839 : rtx lhs = ops[j].op, rhs = ops[i].op;
6432 148800839 : int lneg = ops[j].neg, rneg = ops[i].neg;
6433 :
6434 148800839 : if (lhs != 0 && rhs != 0)
6435 : {
6436 123122049 : enum rtx_code ncode = PLUS;
6437 :
6438 123122049 : if (lneg != rneg)
6439 : {
6440 11665782 : ncode = MINUS;
6441 11665782 : if (lneg)
6442 7350883 : std::swap (lhs, rhs);
6443 : }
6444 111456267 : else if (swap_commutative_operands_p (lhs, rhs))
6445 421535 : std::swap (lhs, rhs);
6446 :
6447 123122049 : if ((GET_CODE (lhs) == CONST || CONST_INT_P (lhs))
6448 28865420 : && (GET_CODE (rhs) == CONST || CONST_INT_P (rhs)))
6449 : {
6450 24083129 : rtx tem_lhs, tem_rhs;
6451 :
6452 24083129 : tem_lhs = GET_CODE (lhs) == CONST ? XEXP (lhs, 0) : lhs;
6453 24083129 : tem_rhs = GET_CODE (rhs) == CONST ? XEXP (rhs, 0) : rhs;
6454 24083129 : tem = simplify_binary_operation (ncode, mode, tem_lhs,
6455 : tem_rhs);
6456 :
6457 24083129 : if (tem && !CONSTANT_P (tem))
6458 1758 : tem = gen_rtx_CONST (GET_MODE (tem), tem);
6459 : }
6460 : else
6461 99038920 : tem = simplify_binary_operation (ncode, mode, lhs, rhs);
6462 :
6463 99040678 : if (tem)
6464 : {
6465 : /* Reject "simplifications" that just wrap the two
6466 : arguments in a CONST. Failure to do so can result
6467 : in infinite recursion with simplify_binary_operation
6468 : when it calls us to simplify CONST operations.
6469 : Also, if we find such a simplification, don't try
6470 : any more combinations with this rhs: We must have
6471 : something like symbol+offset, ie. one of the
6472 : trivial CONST expressions we handle later. */
6473 26300058 : if (GET_CODE (tem) == CONST
6474 916236 : && GET_CODE (XEXP (tem, 0)) == ncode
6475 915684 : && XEXP (XEXP (tem, 0), 0) == lhs
6476 914478 : && XEXP (XEXP (tem, 0), 1) == rhs)
6477 : break;
6478 25385580 : lneg &= rneg;
6479 25385580 : if (GET_CODE (tem) == NEG)
6480 45427 : tem = XEXP (tem, 0), lneg = !lneg;
6481 25385580 : if (poly_int_rtx_p (tem) && lneg)
6482 0 : tem = neg_poly_int_rtx (mode, tem), lneg = 0;
6483 :
6484 25385580 : ops[i].op = tem;
6485 25385580 : ops[i].neg = lneg;
6486 25385580 : ops[j].op = NULL_RTX;
6487 25385580 : changed = 1;
6488 25385580 : canonicalized = 1;
6489 : }
6490 : }
6491 : }
6492 :
6493 64198192 : if (!changed)
6494 : break;
6495 :
6496 : /* Pack all the operands to the lower-numbered entries. */
6497 100660110 : for (i = 0, j = 0; j < n_ops; j++)
6498 75713696 : if (ops[j].op)
6499 : {
6500 50328116 : ops[i] = ops[j];
6501 50328116 : i++;
6502 : }
6503 : n_ops = i;
6504 : }
6505 :
6506 : /* If nothing changed, check that rematerialization of rtl instructions
6507 : is still required. */
6508 39251778 : if (!canonicalized)
6509 : {
6510 : /* Perform rematerialization if only all operands are registers and
6511 : all operations are PLUS. */
6512 : /* ??? Also disallow (non-global, non-frame) fixed registers to work
6513 : around rs6000 and how it uses the CA register. See PR67145. */
6514 5141889 : for (i = 0; i < n_ops; i++)
6515 4149024 : if (ops[i].neg
6516 3859328 : || !REG_P (ops[i].op)
6517 7441803 : || (REGNO (ops[i].op) < FIRST_PSEUDO_REGISTER
6518 324101 : && fixed_regs[REGNO (ops[i].op)]
6519 232 : && !global_regs[REGNO (ops[i].op)]
6520 232 : && ops[i].op != frame_pointer_rtx
6521 118 : && ops[i].op != arg_pointer_rtx
6522 105 : && ops[i].op != stack_pointer_rtx))
6523 : return NULL_RTX;
6524 992865 : goto gen_result;
6525 : }
6526 :
6527 : /* Create (minus -C X) instead of (neg (const (plus X C))). */
6528 37402668 : if (n_ops == 2
6529 23343333 : && CONST_INT_P (ops[1].op)
6530 22682808 : && CONSTANT_P (ops[0].op)
6531 162 : && ops[0].neg)
6532 56 : return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
6533 :
6534 : /* We suppressed creation of trivial CONST expressions in the
6535 : combination loop to avoid recursion. Create one manually now.
6536 : The combination loop should have ensured that there is exactly
6537 : one CONST_INT, and the sort will have ensured that it is last
6538 : in the array and that any other constant will be next-to-last. */
6539 :
6540 37402612 : if (n_ops > 1
6541 36888342 : && poly_int_rtx_p (ops[n_ops - 1].op)
6542 71554565 : && CONSTANT_P (ops[n_ops - 2].op))
6543 : {
6544 1546927 : rtx value = ops[n_ops - 1].op;
6545 1546927 : if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg)
6546 710983 : value = neg_poly_int_rtx (mode, value);
6547 1546927 : if (CONST_INT_P (value))
6548 : {
6549 3093854 : ops[n_ops - 2].op = plus_constant (mode, ops[n_ops - 2].op,
6550 1546927 : INTVAL (value));
6551 1546927 : n_ops--;
6552 : }
6553 : }
6554 :
6555 : /* Put a non-negated operand first, if possible. */
6556 :
6557 39128632 : for (i = 0; i < n_ops && ops[i].neg; i++)
6558 1726020 : continue;
6559 37402612 : if (i == n_ops)
6560 8765 : ops[0].op = gen_rtx_NEG (mode, ops[0].op);
6561 37393847 : else if (i != 0)
6562 : {
6563 1621485 : tem = ops[0].op;
6564 1621485 : ops[0] = ops[i];
6565 1621485 : ops[i].op = tem;
6566 1621485 : ops[i].neg = 1;
6567 : }
6568 :
6569 : /* Now make the result by performing the requested operations. */
6570 35772362 : gen_result:
6571 38395477 : result = ops[0].op;
6572 90081968 : for (i = 1; i < n_ops; i++)
6573 103372982 : result = gen_rtx_fmt_ee (ops[i].neg ? MINUS : PLUS,
6574 : mode, result, ops[i].op);
6575 :
6576 : return result;
6577 1726020 : }
6578 :
6579 : /* Check whether an operand is suitable for calling simplify_plus_minus. */
6580 : static bool
6581 533218541 : plus_minus_operand_p (const_rtx x)
6582 : {
6583 533218541 : return GET_CODE (x) == PLUS
6584 533218541 : || GET_CODE (x) == MINUS
6585 533218541 : || (GET_CODE (x) == CONST
6586 1979696 : && GET_CODE (XEXP (x, 0)) == PLUS
6587 1356961 : && CONSTANT_P (XEXP (XEXP (x, 0), 0))
6588 1282999 : && CONSTANT_P (XEXP (XEXP (x, 0), 1)));
6589 : }
6590 :
6591 : /* Like simplify_binary_operation except used for relational operators.
6592 : MODE is the mode of the result. If MODE is VOIDmode, both operands must
6593 : not also be VOIDmode.
6594 :
6595 : CMP_MODE specifies in which mode the comparison is done in, so it is
6596 : the mode of the operands. If CMP_MODE is VOIDmode, it is taken from
6597 : the operands or, if both are VOIDmode, the operands are compared in
6598 : "infinite precision". */
6599 : rtx
6600 131011538 : simplify_context::simplify_relational_operation (rtx_code code,
6601 : machine_mode mode,
6602 : machine_mode cmp_mode,
6603 : rtx op0, rtx op1)
6604 : {
6605 131011538 : rtx tem, trueop0, trueop1;
6606 :
6607 131011538 : if (cmp_mode == VOIDmode)
6608 28957954 : cmp_mode = GET_MODE (op0);
6609 28957954 : if (cmp_mode == VOIDmode)
6610 271047 : cmp_mode = GET_MODE (op1);
6611 :
6612 131011538 : tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
6613 131011538 : if (tem)
6614 776376 : return relational_result (mode, cmp_mode, tem);
6615 :
6616 : /* For the following tests, ensure const0_rtx is op1. */
6617 130235162 : if (swap_commutative_operands_p (op0, op1)
6618 130235162 : || (op0 == const0_rtx && op1 != const0_rtx))
6619 2713263 : std::swap (op0, op1), code = swap_condition (code);
6620 :
6621 : /* If op0 is a compare, extract the comparison arguments from it. */
6622 130235162 : if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
6623 14220321 : return simplify_gen_relational (code, mode, VOIDmode,
6624 14220321 : XEXP (op0, 0), XEXP (op0, 1));
6625 :
6626 116014841 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
6627 : return NULL_RTX;
6628 :
6629 85292909 : trueop0 = avoid_constant_pool_reference (op0);
6630 85292909 : trueop1 = avoid_constant_pool_reference (op1);
6631 85292909 : return simplify_relational_operation_1 (code, mode, cmp_mode,
6632 85292909 : trueop0, trueop1);
6633 : }
6634 :
6635 : /* This part of simplify_relational_operation is only used when CMP_MODE
6636 : is not in class MODE_CC (i.e. it is a real comparison).
6637 :
6638 : MODE is the mode of the result, while CMP_MODE specifies in which
6639 : mode the comparison is done in, so it is the mode of the operands. */
6640 :
6641 : rtx
6642 85292909 : simplify_context::simplify_relational_operation_1 (rtx_code code,
6643 : machine_mode mode,
6644 : machine_mode cmp_mode,
6645 : rtx op0, rtx op1)
6646 : {
6647 85292909 : enum rtx_code op0code = GET_CODE (op0);
6648 :
6649 85292909 : if (op1 == const0_rtx && COMPARISON_P (op0))
6650 : {
6651 : /* If op0 is a comparison, extract the comparison arguments
6652 : from it. */
6653 297964 : if (code == NE)
6654 : {
6655 131988 : if (GET_MODE (op0) == mode)
6656 187 : return simplify_rtx (op0);
6657 : else
6658 131801 : return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
6659 131801 : XEXP (op0, 0), XEXP (op0, 1));
6660 : }
6661 165976 : else if (code == EQ)
6662 : {
6663 134407 : enum rtx_code new_code = reversed_comparison_code (op0, NULL);
6664 134407 : if (new_code != UNKNOWN)
6665 134090 : return simplify_gen_relational (new_code, mode, VOIDmode,
6666 134090 : XEXP (op0, 0), XEXP (op0, 1));
6667 : }
6668 : }
6669 :
6670 : /* (LTU/GEU (PLUS a C) C), where C is constant, can be simplified to
6671 : (GEU/LTU a -C). Likewise for (LTU/GEU (PLUS a C) a). */
6672 85026831 : if ((code == LTU || code == GEU)
6673 5159222 : && GET_CODE (op0) == PLUS
6674 641642 : && CONST_INT_P (XEXP (op0, 1))
6675 420326 : && (rtx_equal_p (op1, XEXP (op0, 0))
6676 282657 : || rtx_equal_p (op1, XEXP (op0, 1)))
6677 : /* (LTU/GEU (PLUS a 0) 0) is not the same as (GEU/LTU a 0). */
6678 85227852 : && XEXP (op0, 1) != const0_rtx)
6679 : {
6680 201021 : rtx new_cmp
6681 201021 : = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
6682 202560 : return simplify_gen_relational ((code == LTU ? GEU : LTU), mode,
6683 201021 : cmp_mode, XEXP (op0, 0), new_cmp);
6684 : }
6685 :
6686 : /* (GTU (PLUS a C) (C - 1)) where C is a non-zero constant can be
6687 : transformed into (LTU a -C). */
6688 84825810 : if (code == GTU && GET_CODE (op0) == PLUS && CONST_INT_P (op1)
6689 314105 : && CONST_INT_P (XEXP (op0, 1))
6690 241172 : && (UINTVAL (op1) == UINTVAL (XEXP (op0, 1)) - 1)
6691 18991 : && XEXP (op0, 1) != const0_rtx)
6692 : {
6693 18991 : rtx new_cmp
6694 18991 : = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
6695 18991 : return simplify_gen_relational (LTU, mode, cmp_mode,
6696 18991 : XEXP (op0, 0), new_cmp);
6697 : }
6698 :
6699 : /* Canonicalize (LTU/GEU (PLUS a b) b) as (LTU/GEU (PLUS a b) a). */
6700 84806819 : if ((code == LTU || code == GEU)
6701 4958201 : && GET_CODE (op0) == PLUS
6702 440621 : && rtx_equal_p (op1, XEXP (op0, 1))
6703 : /* Don't recurse "infinitely" for (LTU/GEU (PLUS b b) b). */
6704 84812239 : && !rtx_equal_p (op1, XEXP (op0, 0)))
6705 5420 : return simplify_gen_relational (code, mode, cmp_mode, op0,
6706 5420 : copy_rtx (XEXP (op0, 0)));
6707 :
6708 84801399 : if (op1 == const0_rtx)
6709 : {
6710 : /* Canonicalize (GTU x 0) as (NE x 0). */
6711 37104888 : if (code == GTU)
6712 76117 : return simplify_gen_relational (NE, mode, cmp_mode, op0, op1);
6713 : /* Canonicalize (LEU x 0) as (EQ x 0). */
6714 37028771 : if (code == LEU)
6715 33271 : return simplify_gen_relational (EQ, mode, cmp_mode, op0, op1);
6716 :
6717 36995500 : if ((code == NE || code == EQ)
6718 : /* Verify op0 is IOR */
6719 33267669 : && GET_CODE (op0) == IOR
6720 : /* only enters if op1 is 0 */
6721 : /* Verify IOR operand is NE */
6722 600696 : && GET_CODE (XEXP (op0, 0)) == NE
6723 21067 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) == cmp_mode
6724 : /* Verify second NE operand is 0 */
6725 352 : && XEXP (XEXP (op0, 0), 1) == CONST0_RTX (cmp_mode))
6726 : {
6727 31 : rtx t = gen_rtx_IOR (cmp_mode, XEXP (XEXP (op0, 0), 0), XEXP (op0, 1));
6728 31 : t = gen_rtx_fmt_ee (code, mode, t, CONST0_RTX (mode));
6729 31 : return t;
6730 : }
6731 :
6732 : }
6733 47696511 : else if (op1 == const1_rtx)
6734 : {
6735 3235727 : switch (code)
6736 : {
6737 8636 : case GE:
6738 : /* Canonicalize (GE x 1) as (GT x 0). */
6739 8636 : return simplify_gen_relational (GT, mode, cmp_mode,
6740 8636 : op0, const0_rtx);
6741 193743 : case GEU:
6742 : /* Canonicalize (GEU x 1) as (NE x 0). */
6743 193743 : return simplify_gen_relational (NE, mode, cmp_mode,
6744 193743 : op0, const0_rtx);
6745 10491 : case LT:
6746 : /* Canonicalize (LT x 1) as (LE x 0). */
6747 10491 : return simplify_gen_relational (LE, mode, cmp_mode,
6748 10491 : op0, const0_rtx);
6749 53687 : case LTU:
6750 : /* Canonicalize (LTU x 1) as (EQ x 0). */
6751 53687 : return simplify_gen_relational (EQ, mode, cmp_mode,
6752 53687 : op0, const0_rtx);
6753 : default:
6754 : break;
6755 : }
6756 : }
6757 44460784 : else if (op1 == constm1_rtx)
6758 : {
6759 : /* Canonicalize (LE x -1) as (LT x 0). */
6760 1131181 : if (code == LE)
6761 1572 : return simplify_gen_relational (LT, mode, cmp_mode, op0, const0_rtx);
6762 : /* Canonicalize (GT x -1) as (GE x 0). */
6763 1129609 : if (code == GT)
6764 5215 : return simplify_gen_relational (GE, mode, cmp_mode, op0, const0_rtx);
6765 : }
6766 :
6767 : /* (eq/ne (plus x cst1) cst2) simplifies to (eq/ne x (cst2 - cst1)) */
6768 80690805 : if ((code == EQ || code == NE)
6769 62804292 : && (op0code == PLUS || op0code == MINUS)
6770 2508146 : && CONSTANT_P (op1)
6771 906911 : && CONSTANT_P (XEXP (op0, 1))
6772 505037 : && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
6773 : {
6774 505003 : rtx x = XEXP (op0, 0);
6775 505003 : rtx c = XEXP (op0, 1);
6776 505003 : enum rtx_code invcode = op0code == PLUS ? MINUS : PLUS;
6777 505003 : rtx tem = simplify_gen_binary (invcode, cmp_mode, op1, c);
6778 :
6779 : /* Detect an infinite recursive condition, where we oscillate at this
6780 : simplification case between:
6781 : A + B == C <---> C - B == A,
6782 : where A, B, and C are all constants with non-simplifiable expressions,
6783 : usually SYMBOL_REFs. */
6784 505003 : if (GET_CODE (tem) == invcode
6785 57 : && CONSTANT_P (x)
6786 505021 : && rtx_equal_p (c, XEXP (tem, 1)))
6787 : return NULL_RTX;
6788 :
6789 504985 : return simplify_gen_relational (code, mode, cmp_mode, x, tem);
6790 : }
6791 :
6792 : /* (eq/ne (plus (x) (y)) y) simplifies to (eq/ne x 0). */
6793 62299289 : if ((code == EQ || code == NE)
6794 62299289 : && op0code == PLUS
6795 1664740 : && rtx_equal_p (XEXP (op0, 1), op1)
6796 3663 : && !side_effects_p (op1)
6797 3663 : && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
6798 3639 : return simplify_gen_relational (code, mode, cmp_mode,
6799 3639 : XEXP (op0, 0), CONST0_RTX (cmp_mode));
6800 :
6801 : /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is
6802 : the same as (zero_extract:SI FOO (const_int 1) BAR). */
6803 83909994 : scalar_int_mode int_mode, int_cmp_mode;
6804 83909994 : if (code == NE
6805 33544507 : && op1 == const0_rtx
6806 2257744 : && is_int_mode (mode, &int_mode)
6807 86093718 : && is_a <scalar_int_mode> (cmp_mode, &int_cmp_mode)
6808 : /* ??? Work-around BImode bugs in the ia64 backend. */
6809 2257744 : && int_mode != BImode
6810 2257720 : && int_cmp_mode != BImode
6811 2257720 : && nonzero_bits (op0, int_cmp_mode) == 1
6812 83909994 : && STORE_FLAG_VALUE == 1)
6813 148040 : return GET_MODE_SIZE (int_mode) > GET_MODE_SIZE (int_cmp_mode)
6814 74020 : ? simplify_gen_unary (ZERO_EXTEND, int_mode, op0, int_cmp_mode)
6815 18224 : : lowpart_subreg (int_mode, op0, int_cmp_mode);
6816 :
6817 : /* (eq/ne (xor x y) 0) simplifies to (eq/ne x y). */
6818 83835974 : if ((code == EQ || code == NE)
6819 62221630 : && op1 == const0_rtx
6820 33119834 : && op0code == XOR)
6821 13799 : return simplify_gen_relational (code, mode, cmp_mode,
6822 13799 : XEXP (op0, 0), XEXP (op0, 1));
6823 :
6824 : /* (eq/ne (xor x y) x) simplifies to (eq/ne y 0). */
6825 62207831 : if ((code == EQ || code == NE)
6826 62207831 : && op0code == XOR
6827 4818 : && rtx_equal_p (XEXP (op0, 0), op1)
6828 6 : && !side_effects_p (XEXP (op0, 0)))
6829 0 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 1),
6830 0 : CONST0_RTX (mode));
6831 :
6832 : /* Likewise (eq/ne (xor x y) y) simplifies to (eq/ne x 0). */
6833 83822175 : if ((code == EQ || code == NE)
6834 62207831 : && op0code == XOR
6835 4818 : && rtx_equal_p (XEXP (op0, 1), op1)
6836 83822349 : && !side_effects_p (XEXP (op0, 1)))
6837 174 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6838 174 : CONST0_RTX (mode));
6839 :
6840 : /* (eq/ne (xor x C1) C2) simplifies to (eq/ne x (C1^C2)). */
6841 83822001 : if ((code == EQ || code == NE)
6842 62207657 : && op0code == XOR
6843 4644 : && CONST_SCALAR_INT_P (op1)
6844 1017 : && CONST_SCALAR_INT_P (XEXP (op0, 1)))
6845 484 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6846 : simplify_gen_binary (XOR, cmp_mode,
6847 484 : XEXP (op0, 1), op1));
6848 :
6849 : /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or
6850 : constant folding if x/y is a constant. */
6851 62207173 : if ((code == EQ || code == NE)
6852 62207173 : && (op0code == AND || op0code == IOR)
6853 3572513 : && !side_effects_p (op1)
6854 3572407 : && op1 != CONST0_RTX (cmp_mode))
6855 : {
6856 : /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to
6857 : (eq/ne (and (not y) x) 0). */
6858 457124 : if ((op0code == AND && rtx_equal_p (XEXP (op0, 0), op1))
6859 916956 : || (op0code == IOR && rtx_equal_p (XEXP (op0, 1), op1)))
6860 : {
6861 24691 : rtx not_y = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 1),
6862 : cmp_mode);
6863 24691 : rtx lhs = simplify_gen_binary (AND, cmp_mode, not_y, XEXP (op0, 0));
6864 :
6865 24691 : return simplify_gen_relational (code, mode, cmp_mode, lhs,
6866 24691 : CONST0_RTX (cmp_mode));
6867 : }
6868 :
6869 : /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to
6870 : (eq/ne (and (not x) y) 0). */
6871 432508 : if ((op0code == AND && rtx_equal_p (XEXP (op0, 1), op1))
6872 848537 : || (op0code == IOR && rtx_equal_p (XEXP (op0, 0), op1)))
6873 : {
6874 43750 : rtx not_x = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 0),
6875 : cmp_mode);
6876 43750 : rtx lhs = simplify_gen_binary (AND, cmp_mode, not_x, XEXP (op0, 1));
6877 :
6878 43750 : return simplify_gen_relational (code, mode, cmp_mode, lhs,
6879 43750 : CONST0_RTX (cmp_mode));
6880 : }
6881 : }
6882 :
6883 : /* Optimize (cmp (and/ior x C1) C2) depending on the CMP and C1 and C2's
6884 : relationship. */
6885 83753076 : if ((op0code == AND || op0code == IOR)
6886 3743728 : && CONST_INT_P (op1)
6887 3563219 : && CONST_INT_P (XEXP (op0, 1)))
6888 : {
6889 2283672 : unsigned HOST_WIDE_INT c1 = UINTVAL (XEXP (op0, 1));
6890 2283672 : unsigned HOST_WIDE_INT c2 = UINTVAL (op1);
6891 :
6892 : /* For AND operations:
6893 : - (x & c1) == c2 when some bits are set in c2 but not in c1 -> false
6894 : - (x & c1) != c2 when some bits are set in c2 but not in c1 -> true
6895 : - (x & c1) >= c2 when c1 is less than c2 -> false
6896 : - (x & c1) < c2 when c1 is less than c2 -> true
6897 : - (x & c1) > c2 when c1 is less than or equal to c2 -> false
6898 : - (x & c1) <= c2 when c1 is less than or equal to c2 -> true
6899 :
6900 : For IOR operations:
6901 : - (x | c1) == c2 when some bits are set in c1 but not in c2 -> false
6902 : - (x | c1) != c2 when some bits are set in c1 but not in c2 -> true
6903 : - (x | c1) <= c2 when c1 is greater than c2 -> false
6904 : - (x | c1) > c2 when c1 is greater than c2 -> true
6905 : - (x | c1) < c2 when c1 is greater than or equal to c2 -> false
6906 : - (x | c1) >= c2 when c1 is greater than or equal to c2 -> true */
6907 2283672 : if ((op0code == AND
6908 2279444 : && ((code == EQ && (c1 & c2) != c2)
6909 2279431 : || (code == GEU && c1 < c2)
6910 2279431 : || (code == GTU && c1 <= c2)))
6911 2283659 : || ((op0code == IOR
6912 4228 : && ((code == EQ && (c1 & c2) != c1)
6913 4224 : || (code == LEU && c1 > c2)
6914 4224 : || (code == LTU && c1 >= c2)))))
6915 17 : return const0_rtx;
6916 :
6917 2283655 : if ((op0code == AND
6918 2279431 : && ((code == NE && (c1 & c2) != c2)
6919 2279351 : || (code == LTU && c1 < c2)
6920 2279351 : || (code == LEU && c1 <= c2)))
6921 2283575 : || ((op0code == IOR
6922 4224 : && ((code == NE && (c1 & c2) != c1)
6923 4164 : || (code == GTU && c1 > c2)
6924 4164 : || (code == GEU && c1 >= c2)))))
6925 140 : return const_true_rtx;
6926 : }
6927 :
6928 : /* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped. */
6929 83752919 : if ((code == EQ || code == NE)
6930 62138575 : && GET_CODE (op0) == BSWAP
6931 316 : && CONST_SCALAR_INT_P (op1))
6932 85 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6933 : simplify_gen_unary (BSWAP, cmp_mode,
6934 85 : op1, cmp_mode));
6935 :
6936 : /* (eq/ne (bswap x) (bswap y)) simplifies to (eq/ne x y). */
6937 62138490 : if ((code == EQ || code == NE)
6938 62138490 : && GET_CODE (op0) == BSWAP
6939 231 : && GET_CODE (op1) == BSWAP)
6940 18 : return simplify_gen_relational (code, mode, cmp_mode,
6941 18 : XEXP (op0, 0), XEXP (op1, 0));
6942 :
6943 83752816 : if (op0code == POPCOUNT && op1 == const0_rtx)
6944 0 : switch (code)
6945 : {
6946 0 : case EQ:
6947 0 : case LE:
6948 0 : case LEU:
6949 : /* (eq (popcount x) (const_int 0)) -> (eq x (const_int 0)). */
6950 0 : return simplify_gen_relational (EQ, mode, GET_MODE (XEXP (op0, 0)),
6951 : XEXP (op0, 0),
6952 0 : CONST0_RTX (GET_MODE (XEXP (op0, 0))));
6953 :
6954 0 : case NE:
6955 0 : case GT:
6956 0 : case GTU:
6957 : /* (ne (popcount x) (const_int 0)) -> (ne x (const_int 0)). */
6958 0 : return simplify_gen_relational (NE, mode, GET_MODE (XEXP (op0, 0)),
6959 : XEXP (op0, 0),
6960 0 : CONST0_RTX (GET_MODE (XEXP (op0, 0))));
6961 :
6962 : default:
6963 : break;
6964 : }
6965 :
6966 : /* (ne:SI (subreg:QI (ashift:SI x 7) 0) 0) -> (and:SI x 1). */
6967 83752816 : if (code == NE
6968 33428707 : && op1 == const0_rtx
6969 17347939 : && (op0code == TRUNCATE
6970 153163 : || (partial_subreg_p (op0)
6971 152439 : && subreg_lowpart_p (op0)))
6972 129338 : && SCALAR_INT_MODE_P (mode)
6973 83752816 : && STORE_FLAG_VALUE == 1)
6974 : {
6975 33411 : rtx tmp = XEXP (op0, 0);
6976 33411 : if (GET_CODE (tmp) == ASHIFT
6977 2442 : && GET_MODE (tmp) == mode
6978 229 : && CONST_INT_P (XEXP (tmp, 1))
6979 229 : && is_int_mode (GET_MODE (op0), &int_mode)
6980 33640 : && INTVAL (XEXP (tmp, 1)) == GET_MODE_PRECISION (int_mode) - 1)
6981 229 : return simplify_gen_binary (AND, mode, XEXP (tmp, 0), const1_rtx);
6982 : }
6983 :
6984 : /* For two unsigned booleans A and B:
6985 :
6986 : A > B == ~B & A
6987 : A >= B == ~B | A
6988 : A < B == ~A & B
6989 : A <= B == ~A | B
6990 : A == B == ~A ^ B (== ~B ^ A)
6991 : A != B == A ^ B
6992 :
6993 : For signed comparisons, we have to take STORE_FLAG_VALUE into account,
6994 : with the rules above applying for positive STORE_FLAG_VALUE and with
6995 : the relations reversed for negative STORE_FLAG_VALUE. */
6996 83752587 : if (is_a<scalar_int_mode> (cmp_mode)
6997 81013652 : && COMPARISON_P (op0)
6998 83865367 : && COMPARISON_P (op1))
6999 : {
7000 10035 : rtx t = NULL_RTX;
7001 10035 : if (code == GTU || code == (STORE_FLAG_VALUE > 0 ? GT : LT))
7002 755 : t = simplify_logical_relational_operation (AND, mode, op1, op0, true);
7003 : else if (code == GEU || code == (STORE_FLAG_VALUE > 0 ? GE : LE))
7004 720 : t = simplify_logical_relational_operation (IOR, mode, op1, op0, true);
7005 : else if (code == LTU || code == (STORE_FLAG_VALUE > 0 ? LT : GT))
7006 720 : t = simplify_logical_relational_operation (AND, mode, op0, op1, true);
7007 : else if (code == LEU || code == (STORE_FLAG_VALUE > 0 ? LE : GE))
7008 720 : t = simplify_logical_relational_operation (IOR, mode, op0, op1, true);
7009 : else if (code == EQ)
7010 3174 : t = simplify_logical_relational_operation (XOR, mode, op0, op1, true);
7011 : else if (code == NE)
7012 3946 : t = simplify_logical_relational_operation (XOR, mode, op0, op1);
7013 10035 : if (t)
7014 : return t;
7015 : }
7016 :
7017 : return NULL_RTX;
7018 : }
7019 :
7020 : enum
7021 : {
7022 : CMP_EQ = 1,
7023 : CMP_LT = 2,
7024 : CMP_GT = 4,
7025 : CMP_LTU = 8,
7026 : CMP_GTU = 16
7027 : };
7028 :
7029 :
7030 : /* Convert the known results for EQ, LT, GT, LTU, GTU contained in
7031 : KNOWN_RESULT to a CONST_INT, based on the requested comparison CODE
7032 : For KNOWN_RESULT to make sense it should be either CMP_EQ, or the
7033 : logical OR of one of (CMP_LT, CMP_GT) and one of (CMP_LTU, CMP_GTU).
7034 : For floating-point comparisons, assume that the operands were ordered. */
7035 :
7036 : static rtx
7037 716950 : comparison_result (enum rtx_code code, int known_results)
7038 : {
7039 716950 : switch (code)
7040 : {
7041 132075 : case EQ:
7042 132075 : case UNEQ:
7043 132075 : return (known_results & CMP_EQ) ? const_true_rtx : const0_rtx;
7044 446759 : case NE:
7045 446759 : case LTGT:
7046 446759 : return (known_results & CMP_EQ) ? const0_rtx : const_true_rtx;
7047 :
7048 9427 : case LT:
7049 9427 : case UNLT:
7050 9427 : return (known_results & CMP_LT) ? const_true_rtx : const0_rtx;
7051 8685 : case GE:
7052 8685 : case UNGE:
7053 8685 : return (known_results & CMP_LT) ? const0_rtx : const_true_rtx;
7054 :
7055 12712 : case GT:
7056 12712 : case UNGT:
7057 12712 : return (known_results & CMP_GT) ? const_true_rtx : const0_rtx;
7058 14896 : case LE:
7059 14896 : case UNLE:
7060 14896 : return (known_results & CMP_GT) ? const0_rtx : const_true_rtx;
7061 :
7062 24009 : case LTU:
7063 24009 : return (known_results & CMP_LTU) ? const_true_rtx : const0_rtx;
7064 8851 : case GEU:
7065 8851 : return (known_results & CMP_LTU) ? const0_rtx : const_true_rtx;
7066 :
7067 49276 : case GTU:
7068 49276 : return (known_results & CMP_GTU) ? const_true_rtx : const0_rtx;
7069 10194 : case LEU:
7070 10194 : return (known_results & CMP_GTU) ? const0_rtx : const_true_rtx;
7071 :
7072 0 : case ORDERED:
7073 0 : return const_true_rtx;
7074 66 : case UNORDERED:
7075 66 : return const0_rtx;
7076 0 : default:
7077 0 : gcc_unreachable ();
7078 : }
7079 : }
7080 :
7081 : /* Check if the given comparison (done in the given MODE) is actually
7082 : a tautology or a contradiction. If the mode is VOIDmode, the
7083 : comparison is done in "infinite precision". If no simplification
7084 : is possible, this function returns zero. Otherwise, it returns
7085 : either const_true_rtx or const0_rtx. */
7086 :
7087 : rtx
7088 131101682 : simplify_const_relational_operation (enum rtx_code code,
7089 : machine_mode mode,
7090 : rtx op0, rtx op1)
7091 : {
7092 138089899 : rtx tem;
7093 138089899 : rtx trueop0;
7094 138089899 : rtx trueop1;
7095 :
7096 138089899 : gcc_assert (mode != VOIDmode
7097 : || (GET_MODE (op0) == VOIDmode
7098 : && GET_MODE (op1) == VOIDmode));
7099 :
7100 : /* We only handle MODE_CC comparisons that are COMPARE against zero. */
7101 138089899 : if (GET_MODE_CLASS (mode) == MODE_CC
7102 44948131 : && (op1 != const0_rtx
7103 44948131 : || GET_CODE (op0) != COMPARE))
7104 : return NULL_RTX;
7105 :
7106 : /* If op0 is a compare, extract the comparison arguments from it. */
7107 107367967 : if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
7108 : {
7109 14226199 : op1 = XEXP (op0, 1);
7110 14226199 : op0 = XEXP (op0, 0);
7111 :
7112 14226199 : if (GET_MODE (op0) != VOIDmode)
7113 14078069 : mode = GET_MODE (op0);
7114 148130 : else if (GET_MODE (op1) != VOIDmode)
7115 115718 : mode = GET_MODE (op1);
7116 : else
7117 : return 0;
7118 : }
7119 :
7120 : /* We can't simplify MODE_CC values since we don't know what the
7121 : actual comparison is. */
7122 107335555 : if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
7123 : return 0;
7124 :
7125 : /* Make sure the constant is second. */
7126 107335555 : if (swap_commutative_operands_p (op0, op1))
7127 : {
7128 3114694 : std::swap (op0, op1);
7129 3114694 : code = swap_condition (code);
7130 : }
7131 :
7132 107335555 : trueop0 = avoid_constant_pool_reference (op0);
7133 107335555 : trueop1 = avoid_constant_pool_reference (op1);
7134 :
7135 : /* For integer comparisons of A and B maybe we can simplify A - B and can
7136 : then simplify a comparison of that with zero. If A and B are both either
7137 : a register or a CONST_INT, this can't help; testing for these cases will
7138 : prevent infinite recursion here and speed things up.
7139 :
7140 : We can only do this for EQ and NE comparisons as otherwise we may
7141 : lose or introduce overflow which we cannot disregard as undefined as
7142 : we do not know the signedness of the operation on either the left or
7143 : the right hand side of the comparison. */
7144 :
7145 107335555 : if (INTEGRAL_MODE_P (mode)
7146 104649385 : && trueop1 != CONST0_RTX (mode)
7147 53958960 : && (code == EQ || code == NE)
7148 34194968 : && ! ((REG_P (op0)
7149 9981127 : || CONST_SCALAR_INT_P (trueop0)
7150 9953184 : || CONST_VECTOR_P (trueop0))
7151 24241804 : && (REG_P (op1)
7152 14521748 : || CONST_SCALAR_INT_P (trueop1)
7153 3438313 : || CONST_VECTOR_P (trueop1)))
7154 13388501 : && (tem = simplify_binary_operation (MINUS, mode, op0, op1)) != 0
7155 : /* We cannot do this if tem is a nonzero address. */
7156 6988219 : && ! nonzero_address_p (tem))
7157 6988217 : return simplify_const_relational_operation (signed_condition (code),
7158 6988217 : mode, tem, CONST0_RTX (mode));
7159 :
7160 100347338 : if (! HONOR_NANS (mode) && code == ORDERED)
7161 0 : return const_true_rtx;
7162 :
7163 100347338 : if (! HONOR_NANS (mode) && code == UNORDERED)
7164 8 : return const0_rtx;
7165 :
7166 : /* For modes without NaNs, if the two operands are equal, we know the
7167 : result except if they have side-effects. Even with NaNs we know
7168 : the result of unordered comparisons and, if signaling NaNs are
7169 : irrelevant, also the result of LT/GT/LTGT. */
7170 100347330 : if ((! HONOR_NANS (trueop0)
7171 2196813 : || code == UNEQ || code == UNLE || code == UNGE
7172 : || ((code == LT || code == GT || code == LTGT)
7173 902547 : && ! HONOR_SNANS (trueop0)))
7174 99162958 : && rtx_equal_p (trueop0, trueop1)
7175 100858053 : && ! side_effects_p (trueop0))
7176 510642 : return comparison_result (code, CMP_EQ);
7177 :
7178 : /* If the operands are floating-point constants, see if we can fold
7179 : the result. */
7180 99836688 : if (CONST_DOUBLE_AS_FLOAT_P (trueop0)
7181 1495 : && CONST_DOUBLE_AS_FLOAT_P (trueop1)
7182 1495 : && SCALAR_FLOAT_MODE_P (GET_MODE (trueop0)))
7183 : {
7184 1495 : const REAL_VALUE_TYPE *d0 = CONST_DOUBLE_REAL_VALUE (trueop0);
7185 1495 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
7186 :
7187 : /* Comparisons are unordered iff at least one of the values is NaN. */
7188 1495 : if (REAL_VALUE_ISNAN (*d0) || REAL_VALUE_ISNAN (*d1))
7189 174 : switch (code)
7190 : {
7191 0 : case UNEQ:
7192 0 : case UNLT:
7193 0 : case UNGT:
7194 0 : case UNLE:
7195 0 : case UNGE:
7196 0 : case NE:
7197 0 : case UNORDERED:
7198 0 : return const_true_rtx;
7199 174 : case EQ:
7200 174 : case LT:
7201 174 : case GT:
7202 174 : case LE:
7203 174 : case GE:
7204 174 : case LTGT:
7205 174 : case ORDERED:
7206 174 : return const0_rtx;
7207 : default:
7208 : return 0;
7209 : }
7210 :
7211 1480 : return comparison_result (code,
7212 1480 : (real_equal (d0, d1) ? CMP_EQ :
7213 1480 : real_less (d0, d1) ? CMP_LT : CMP_GT));
7214 : }
7215 :
7216 : /* Otherwise, see if the operands are both integers. */
7217 99835193 : if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
7218 96692214 : && CONST_SCALAR_INT_P (trueop0) && CONST_SCALAR_INT_P (trueop1))
7219 : {
7220 : /* It would be nice if we really had a mode here. However, the
7221 : largest int representable on the target is as good as
7222 : infinite. */
7223 204987 : machine_mode cmode = (mode == VOIDmode) ? MAX_MODE_INT : mode;
7224 204987 : rtx_mode_t ptrueop0 = rtx_mode_t (trueop0, cmode);
7225 204987 : rtx_mode_t ptrueop1 = rtx_mode_t (trueop1, cmode);
7226 :
7227 204987 : if (wi::eq_p (ptrueop0, ptrueop1))
7228 0 : return comparison_result (code, CMP_EQ);
7229 : else
7230 : {
7231 204987 : int cr = wi::lts_p (ptrueop0, ptrueop1) ? CMP_LT : CMP_GT;
7232 204987 : cr |= wi::ltu_p (ptrueop0, ptrueop1) ? CMP_LTU : CMP_GTU;
7233 204987 : return comparison_result (code, cr);
7234 : }
7235 : }
7236 :
7237 : /* Optimize comparisons with upper and lower bounds. */
7238 99630206 : scalar_int_mode int_mode;
7239 99630206 : if (CONST_INT_P (trueop1)
7240 69501346 : && is_a <scalar_int_mode> (mode, &int_mode)
7241 69501346 : && HWI_COMPUTABLE_MODE_P (int_mode)
7242 168677774 : && !side_effects_p (trueop0))
7243 : {
7244 68897141 : int sign;
7245 68897141 : unsigned HOST_WIDE_INT nonzero = nonzero_bits (trueop0, int_mode);
7246 68897141 : HOST_WIDE_INT val = INTVAL (trueop1);
7247 68897141 : HOST_WIDE_INT mmin, mmax;
7248 :
7249 68897141 : if (code == GEU
7250 68897141 : || code == LEU
7251 65615244 : || code == GTU
7252 65615244 : || code == LTU)
7253 : sign = 0;
7254 : else
7255 68897141 : sign = 1;
7256 :
7257 : /* Get a reduced range if the sign bit is zero. */
7258 68897141 : if (nonzero <= (GET_MODE_MASK (int_mode) >> 1))
7259 : {
7260 6142516 : mmin = 0;
7261 6142516 : mmax = nonzero;
7262 : }
7263 : else
7264 : {
7265 62754625 : rtx mmin_rtx, mmax_rtx;
7266 62754625 : get_mode_bounds (int_mode, sign, int_mode, &mmin_rtx, &mmax_rtx);
7267 :
7268 62754625 : mmin = INTVAL (mmin_rtx);
7269 62754625 : mmax = INTVAL (mmax_rtx);
7270 62754625 : if (sign)
7271 : {
7272 56654653 : unsigned int sign_copies
7273 56654653 : = num_sign_bit_copies (trueop0, int_mode);
7274 :
7275 56654653 : mmin >>= (sign_copies - 1);
7276 56654653 : mmax >>= (sign_copies - 1);
7277 : }
7278 : }
7279 :
7280 68897141 : switch (code)
7281 : {
7282 : /* x >= y is always true for y <= mmin, always false for y > mmax. */
7283 536630 : case GEU:
7284 536630 : if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
7285 6043 : return const_true_rtx;
7286 530587 : if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
7287 40 : return const0_rtx;
7288 : break;
7289 961808 : case GE:
7290 961808 : if (val <= mmin)
7291 2079 : return const_true_rtx;
7292 959729 : if (val > mmax)
7293 0 : return const0_rtx;
7294 : break;
7295 :
7296 : /* x <= y is always true for y >= mmax, always false for y < mmin. */
7297 2745267 : case LEU:
7298 2745267 : if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
7299 15319 : return const_true_rtx;
7300 2729948 : if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
7301 0 : return const0_rtx;
7302 : break;
7303 2459513 : case LE:
7304 2459513 : if (val >= mmax)
7305 464 : return const_true_rtx;
7306 2459049 : if (val < mmin)
7307 0 : return const0_rtx;
7308 : break;
7309 :
7310 24971021 : case EQ:
7311 : /* x == y is always false for y out of range. */
7312 24971021 : if (val < mmin || val > mmax)
7313 443 : return const0_rtx;
7314 : break;
7315 :
7316 : /* x > y is always false for y >= mmax, always true for y < mmin. */
7317 2436729 : case GTU:
7318 2436729 : if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
7319 39283 : return const0_rtx;
7320 2397446 : if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
7321 0 : return const_true_rtx;
7322 : break;
7323 1825836 : case GT:
7324 1825836 : if (val >= mmax)
7325 329 : return const0_rtx;
7326 1825507 : if (val < mmin)
7327 2 : return const_true_rtx;
7328 : break;
7329 :
7330 : /* x < y is always false for y <= mmin, always true for y > mmax. */
7331 836513 : case LTU:
7332 836513 : if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
7333 3054 : return const0_rtx;
7334 833459 : if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
7335 75867 : return const_true_rtx;
7336 : break;
7337 1126893 : case LT:
7338 1126893 : if (val <= mmin)
7339 2330 : return const0_rtx;
7340 1124563 : if (val > mmax)
7341 3271 : return const_true_rtx;
7342 : break;
7343 :
7344 30996931 : case NE:
7345 : /* x != y is always true for y out of range. */
7346 30996931 : if (val < mmin || val > mmax)
7347 120 : return const_true_rtx;
7348 : break;
7349 :
7350 : default:
7351 : break;
7352 : }
7353 : }
7354 :
7355 : /* Optimize integer comparisons with zero. */
7356 99481562 : if (is_a <scalar_int_mode> (mode, &int_mode)
7357 96381664 : && trueop1 == const0_rtx
7358 49957941 : && !side_effects_p (trueop0))
7359 : {
7360 : /* Some addresses are known to be nonzero. We don't know
7361 : their sign, but equality comparisons are known. */
7362 49805438 : if (nonzero_address_p (trueop0))
7363 : {
7364 540 : if (code == EQ || code == LEU)
7365 281 : return const0_rtx;
7366 259 : if (code == NE || code == GTU)
7367 259 : return const_true_rtx;
7368 : }
7369 :
7370 : /* See if the first operand is an IOR with a constant. If so, we
7371 : may be able to determine the result of this comparison. */
7372 49804898 : if (GET_CODE (op0) == IOR)
7373 : {
7374 690355 : rtx inner_const = avoid_constant_pool_reference (XEXP (op0, 1));
7375 690355 : if (CONST_INT_P (inner_const) && inner_const != const0_rtx)
7376 : {
7377 288 : int sign_bitnum = GET_MODE_PRECISION (int_mode) - 1;
7378 576 : int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
7379 288 : && (UINTVAL (inner_const)
7380 288 : & (HOST_WIDE_INT_1U
7381 : << sign_bitnum)));
7382 :
7383 288 : switch (code)
7384 : {
7385 : case EQ:
7386 : case LEU:
7387 : return const0_rtx;
7388 4 : case NE:
7389 4 : case GTU:
7390 4 : return const_true_rtx;
7391 70 : case LT:
7392 70 : case LE:
7393 70 : if (has_sign)
7394 2 : return const_true_rtx;
7395 : break;
7396 208 : case GT:
7397 208 : case GE:
7398 208 : if (has_sign)
7399 : return const0_rtx;
7400 : break;
7401 : default:
7402 : break;
7403 : }
7404 : }
7405 : }
7406 : }
7407 :
7408 : /* Optimize comparison of ABS with zero. */
7409 50303441 : if (trueop1 == CONST0_RTX (mode) && !side_effects_p (trueop0)
7410 149631443 : && (GET_CODE (trueop0) == ABS
7411 50150042 : || (GET_CODE (trueop0) == FLOAT_EXTEND
7412 98 : && GET_CODE (XEXP (trueop0, 0)) == ABS)))
7413 : {
7414 583 : switch (code)
7415 : {
7416 60 : case LT:
7417 : /* Optimize abs(x) < 0.0. */
7418 60 : if (!INTEGRAL_MODE_P (mode) && !HONOR_SNANS (mode))
7419 0 : return const0_rtx;
7420 : break;
7421 :
7422 42 : case GE:
7423 : /* Optimize abs(x) >= 0.0. */
7424 42 : if (!INTEGRAL_MODE_P (mode) && !HONOR_NANS (mode))
7425 0 : return const_true_rtx;
7426 : break;
7427 :
7428 0 : case UNGE:
7429 : /* Optimize ! (abs(x) < 0.0). */
7430 0 : return const_true_rtx;
7431 :
7432 : default:
7433 : break;
7434 : }
7435 : }
7436 :
7437 : return 0;
7438 : }
7439 :
7440 : /* Recognize expressions of the form (X CMP 0) ? VAL : OP (X)
7441 : where OP is CLZ or CTZ and VAL is the value from CLZ_DEFINED_VALUE_AT_ZERO
7442 : or CTZ_DEFINED_VALUE_AT_ZERO respectively and return OP (X) if the expression
7443 : can be simplified to that or NULL_RTX if not.
7444 : Assume X is compared against zero with CMP_CODE and the true
7445 : arm is TRUE_VAL and the false arm is FALSE_VAL. */
7446 :
7447 : rtx
7448 31189898 : simplify_context::simplify_cond_clz_ctz (rtx x, rtx_code cmp_code,
7449 : rtx true_val, rtx false_val)
7450 : {
7451 31189898 : if (cmp_code != EQ && cmp_code != NE)
7452 : return NULL_RTX;
7453 :
7454 : /* Result on X == 0 and X !=0 respectively. */
7455 22422639 : rtx on_zero, on_nonzero;
7456 22422639 : if (cmp_code == EQ)
7457 : {
7458 : on_zero = true_val;
7459 : on_nonzero = false_val;
7460 : }
7461 : else
7462 : {
7463 12272675 : on_zero = false_val;
7464 12272675 : on_nonzero = true_val;
7465 : }
7466 :
7467 22422639 : rtx_code op_code = GET_CODE (on_nonzero);
7468 22422639 : if ((op_code != CLZ && op_code != CTZ)
7469 2012 : || !rtx_equal_p (XEXP (on_nonzero, 0), x)
7470 22423687 : || !CONST_INT_P (on_zero))
7471 22422342 : return NULL_RTX;
7472 :
7473 297 : HOST_WIDE_INT op_val;
7474 297 : scalar_int_mode mode ATTRIBUTE_UNUSED
7475 297 : = as_a <scalar_int_mode> (GET_MODE (XEXP (on_nonzero, 0)));
7476 0 : if (((op_code == CLZ && CLZ_DEFINED_VALUE_AT_ZERO (mode, op_val))
7477 594 : || (op_code == CTZ && CTZ_DEFINED_VALUE_AT_ZERO (mode, op_val)))
7478 321 : && op_val == INTVAL (on_zero))
7479 : return on_nonzero;
7480 :
7481 : return NULL_RTX;
7482 : }
7483 :
7484 : /* Try to simplify X given that it appears within operand OP of a
7485 : VEC_MERGE operation whose mask is MASK. X need not use the same
7486 : vector mode as the VEC_MERGE, but it must have the same number of
7487 : elements.
7488 :
7489 : Return the simplified X on success, otherwise return NULL_RTX. */
7490 :
7491 : rtx
7492 1671609 : simplify_context::simplify_merge_mask (rtx x, rtx mask, int op)
7493 : {
7494 1671609 : gcc_assert (VECTOR_MODE_P (GET_MODE (x)));
7495 3343218 : poly_uint64 nunits = GET_MODE_NUNITS (GET_MODE (x));
7496 1671609 : if (GET_CODE (x) == VEC_MERGE && rtx_equal_p (XEXP (x, 2), mask))
7497 : {
7498 5491 : if (side_effects_p (XEXP (x, 1 - op)))
7499 : return NULL_RTX;
7500 :
7501 5267 : return XEXP (x, op);
7502 : }
7503 1666118 : if (UNARY_P (x)
7504 206325 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
7505 1723826 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits))
7506 : {
7507 24247 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
7508 24247 : if (top0)
7509 448 : return simplify_gen_unary (GET_CODE (x), GET_MODE (x), top0,
7510 448 : GET_MODE (XEXP (x, 0)));
7511 : }
7512 1665670 : if (BINARY_P (x)
7513 207135 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
7514 413636 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
7515 181430 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
7516 1953976 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits))
7517 : {
7518 144153 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
7519 144153 : rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
7520 144153 : if (top0 || top1)
7521 : {
7522 952 : if (COMPARISON_P (x))
7523 0 : return simplify_gen_relational (GET_CODE (x), GET_MODE (x),
7524 0 : GET_MODE (XEXP (x, 0)) != VOIDmode
7525 : ? GET_MODE (XEXP (x, 0))
7526 0 : : GET_MODE (XEXP (x, 1)),
7527 : top0 ? top0 : XEXP (x, 0),
7528 0 : top1 ? top1 : XEXP (x, 1));
7529 : else
7530 952 : return simplify_gen_binary (GET_CODE (x), GET_MODE (x),
7531 : top0 ? top0 : XEXP (x, 0),
7532 952 : top1 ? top1 : XEXP (x, 1));
7533 : }
7534 : }
7535 1664718 : if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY
7536 34928 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
7537 69856 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
7538 34928 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
7539 69856 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits)
7540 34928 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 2)))
7541 1681338 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 2))), nunits))
7542 : {
7543 8310 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
7544 8310 : rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
7545 8310 : rtx top2 = simplify_merge_mask (XEXP (x, 2), mask, op);
7546 8310 : if (top0 || top1 || top2)
7547 448 : return simplify_gen_ternary (GET_CODE (x), GET_MODE (x),
7548 448 : GET_MODE (XEXP (x, 0)),
7549 : top0 ? top0 : XEXP (x, 0),
7550 : top1 ? top1 : XEXP (x, 1),
7551 448 : top2 ? top2 : XEXP (x, 2));
7552 : }
7553 : return NULL_RTX;
7554 : }
7555 :
7556 :
7557 : /* Simplify CODE, an operation with result mode MODE and three operands,
7558 : OP0, OP1, and OP2. OP0_MODE was the mode of OP0 before it became
7559 : a constant. Return 0 if no simplifications is possible. */
7560 :
7561 : rtx
7562 43091582 : simplify_context::simplify_ternary_operation (rtx_code code, machine_mode mode,
7563 : machine_mode op0_mode,
7564 : rtx op0, rtx op1, rtx op2)
7565 : {
7566 43091582 : bool any_change = false;
7567 43091582 : rtx tem, trueop2;
7568 43091582 : scalar_int_mode int_mode, int_op0_mode;
7569 43091582 : unsigned int n_elts;
7570 :
7571 43091582 : switch (code)
7572 : {
7573 338109 : case FMA:
7574 : /* Simplify negations around the multiplication. */
7575 : /* -a * -b + c => a * b + c. */
7576 338109 : if (GET_CODE (op0) == NEG)
7577 : {
7578 82383 : tem = simplify_unary_operation (NEG, mode, op1, mode);
7579 82383 : if (tem)
7580 271 : op1 = tem, op0 = XEXP (op0, 0), any_change = true;
7581 : }
7582 255726 : else if (GET_CODE (op1) == NEG)
7583 : {
7584 1066 : tem = simplify_unary_operation (NEG, mode, op0, mode);
7585 1066 : if (tem)
7586 0 : op0 = tem, op1 = XEXP (op1, 0), any_change = true;
7587 : }
7588 :
7589 : /* Canonicalize the two multiplication operands. */
7590 : /* a * -b + c => -b * a + c. */
7591 338109 : if (swap_commutative_operands_p (op0, op1))
7592 : std::swap (op0, op1), any_change = true;
7593 :
7594 308887 : if (any_change)
7595 29484 : return gen_rtx_FMA (mode, op0, op1, op2);
7596 : return NULL_RTX;
7597 :
7598 636030 : case SIGN_EXTRACT:
7599 636030 : case ZERO_EXTRACT:
7600 636030 : if (CONST_INT_P (op0)
7601 17090 : && CONST_INT_P (op1)
7602 17090 : && CONST_INT_P (op2)
7603 43091614 : && is_a <scalar_int_mode> (mode, &int_mode)
7604 32 : && INTVAL (op1) + INTVAL (op2) <= GET_MODE_PRECISION (int_mode)
7605 636062 : && HWI_COMPUTABLE_MODE_P (int_mode))
7606 : {
7607 : /* Extracting a bit-field from a constant */
7608 32 : unsigned HOST_WIDE_INT val = UINTVAL (op0);
7609 32 : HOST_WIDE_INT op1val = INTVAL (op1);
7610 32 : HOST_WIDE_INT op2val = INTVAL (op2);
7611 32 : if (!BITS_BIG_ENDIAN)
7612 32 : val >>= op2val;
7613 : else if (is_a <scalar_int_mode> (op0_mode, &int_op0_mode))
7614 : val >>= GET_MODE_PRECISION (int_op0_mode) - op2val - op1val;
7615 : else
7616 : /* Not enough information to calculate the bit position. */
7617 : break;
7618 :
7619 32 : if (HOST_BITS_PER_WIDE_INT != op1val)
7620 : {
7621 : /* First zero-extend. */
7622 29 : val &= (HOST_WIDE_INT_1U << op1val) - 1;
7623 : /* If desired, propagate sign bit. */
7624 29 : if (code == SIGN_EXTRACT
7625 5 : && (val & (HOST_WIDE_INT_1U << (op1val - 1)))
7626 5 : != 0)
7627 2 : val |= ~ ((HOST_WIDE_INT_1U << op1val) - 1);
7628 : }
7629 :
7630 32 : return gen_int_mode (val, int_mode);
7631 : }
7632 : break;
7633 :
7634 41310833 : case IF_THEN_ELSE:
7635 41310833 : if (CONST_INT_P (op0))
7636 293904 : return op0 != const0_rtx ? op1 : op2;
7637 :
7638 : /* Convert c ? a : a into "a". */
7639 41111434 : if (rtx_equal_p (op1, op2) && ! side_effects_p (op0))
7640 : return op1;
7641 :
7642 : /* Convert a != b ? a : b into "a". */
7643 41108016 : if (GET_CODE (op0) == NE
7644 16061427 : && ! side_effects_p (op0)
7645 16012922 : && ! HONOR_NANS (mode)
7646 15822236 : && ! HONOR_SIGNED_ZEROS (mode)
7647 56930252 : && ((rtx_equal_p (XEXP (op0, 0), op1)
7648 119772 : && rtx_equal_p (XEXP (op0, 1), op2))
7649 15821895 : || (rtx_equal_p (XEXP (op0, 0), op2)
7650 4217 : && rtx_equal_p (XEXP (op0, 1), op1))))
7651 593 : return op1;
7652 :
7653 : /* Convert a == b ? a : b into "b". */
7654 41107423 : if (GET_CODE (op0) == EQ
7655 12720557 : && ! side_effects_p (op0)
7656 12701522 : && ! HONOR_NANS (mode)
7657 12675252 : && ! HONOR_SIGNED_ZEROS (mode)
7658 53782675 : && ((rtx_equal_p (XEXP (op0, 0), op1)
7659 15054 : && rtx_equal_p (XEXP (op0, 1), op2))
7660 12675241 : || (rtx_equal_p (XEXP (op0, 0), op2)
7661 7465 : && rtx_equal_p (XEXP (op0, 1), op1))))
7662 29 : return op2;
7663 :
7664 : /* Convert a != 0 ? -a : 0 into "-a". */
7665 41107394 : if (GET_CODE (op0) == NE
7666 16060834 : && ! side_effects_p (op0)
7667 16012329 : && ! HONOR_NANS (mode)
7668 15821643 : && ! HONOR_SIGNED_ZEROS (mode)
7669 15821643 : && XEXP (op0, 1) == CONST0_RTX (mode)
7670 12081810 : && op2 == CONST0_RTX (mode)
7671 178522 : && GET_CODE (op1) == NEG
7672 41107452 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0)))
7673 : return op1;
7674 :
7675 : /* Convert a == 0 ? 0 : -a into "-a". */
7676 41107385 : if (GET_CODE (op0) == EQ
7677 12720528 : && ! side_effects_p (op0)
7678 12701493 : && ! HONOR_NANS (mode)
7679 12675223 : && ! HONOR_SIGNED_ZEROS (mode)
7680 12675223 : && op1 == CONST0_RTX (mode)
7681 31401 : && XEXP (op0, 1) == CONST0_RTX (mode)
7682 13712 : && GET_CODE (op2) == NEG
7683 41107391 : && rtx_equal_p (XEXP (op0, 0), XEXP (op2, 0)))
7684 : return op2;
7685 :
7686 : /* Convert (!c) != {0,...,0} ? a : b into
7687 : c != {0,...,0} ? b : a for vector modes. */
7688 41107379 : if (VECTOR_MODE_P (GET_MODE (op1))
7689 14808 : && GET_CODE (op0) == NE
7690 471 : && GET_CODE (XEXP (op0, 0)) == NOT
7691 0 : && GET_CODE (XEXP (op0, 1)) == CONST_VECTOR)
7692 : {
7693 0 : rtx cv = XEXP (op0, 1);
7694 0 : int nunits;
7695 0 : bool ok = true;
7696 0 : if (!CONST_VECTOR_NUNITS (cv).is_constant (&nunits))
7697 : ok = false;
7698 : else
7699 0 : for (int i = 0; i < nunits; ++i)
7700 0 : if (CONST_VECTOR_ELT (cv, i) != const0_rtx)
7701 : {
7702 : ok = false;
7703 : break;
7704 : }
7705 0 : if (ok)
7706 : {
7707 0 : rtx new_op0 = gen_rtx_NE (GET_MODE (op0),
7708 : XEXP (XEXP (op0, 0), 0),
7709 : XEXP (op0, 1));
7710 0 : rtx retval = gen_rtx_IF_THEN_ELSE (mode, new_op0, op2, op1);
7711 0 : return retval;
7712 : }
7713 : }
7714 :
7715 : /* Convert x == 0 ? N : clz (x) into clz (x) when
7716 : CLZ_DEFINED_VALUE_AT_ZERO is defined to N for the mode of x.
7717 : Similarly for ctz (x). */
7718 41106386 : if (COMPARISON_P (op0) && !side_effects_p (op0)
7719 82113230 : && XEXP (op0, 1) == const0_rtx)
7720 : {
7721 31189898 : rtx simplified
7722 31189898 : = simplify_cond_clz_ctz (XEXP (op0, 0), GET_CODE (op0),
7723 : op1, op2);
7724 31189898 : if (simplified)
7725 : return simplified;
7726 : }
7727 :
7728 41107379 : if (COMPARISON_P (op0) && ! side_effects_p (op0))
7729 : {
7730 82106424 : machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
7731 41005851 : ? GET_MODE (XEXP (op0, 1))
7732 : : GET_MODE (XEXP (op0, 0)));
7733 41005851 : rtx temp;
7734 :
7735 : /* Look for happy constants in op1 and op2. */
7736 41005851 : if (CONST_INT_P (op1) && CONST_INT_P (op2))
7737 : {
7738 216043 : HOST_WIDE_INT t = INTVAL (op1);
7739 216043 : HOST_WIDE_INT f = INTVAL (op2);
7740 :
7741 216043 : if (t == STORE_FLAG_VALUE && f == 0)
7742 53064 : code = GET_CODE (op0);
7743 162979 : else if (t == 0 && f == STORE_FLAG_VALUE)
7744 : {
7745 31671 : enum rtx_code tmp;
7746 31671 : tmp = reversed_comparison_code (op0, NULL);
7747 31671 : if (tmp == UNKNOWN)
7748 : break;
7749 : code = tmp;
7750 : }
7751 : else
7752 : break;
7753 :
7754 79352 : return simplify_gen_relational (code, mode, cmp_mode,
7755 79352 : XEXP (op0, 0), XEXP (op0, 1));
7756 : }
7757 :
7758 40789808 : temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
7759 : cmp_mode, XEXP (op0, 0),
7760 : XEXP (op0, 1));
7761 :
7762 : /* See if any simplifications were possible. */
7763 40789808 : if (temp)
7764 : {
7765 7018 : if (CONST_INT_P (temp))
7766 872 : return temp == const0_rtx ? op2 : op1;
7767 6191 : else if (temp)
7768 6191 : return gen_rtx_IF_THEN_ELSE (mode, temp, op1, op2);
7769 : }
7770 : }
7771 : break;
7772 :
7773 806610 : case VEC_MERGE:
7774 806610 : gcc_assert (GET_MODE (op0) == mode);
7775 806610 : gcc_assert (GET_MODE (op1) == mode);
7776 806610 : gcc_assert (VECTOR_MODE_P (mode));
7777 806610 : trueop2 = avoid_constant_pool_reference (op2);
7778 806610 : if (CONST_INT_P (trueop2)
7779 1292478 : && GET_MODE_NUNITS (mode).is_constant (&n_elts))
7780 : {
7781 485868 : unsigned HOST_WIDE_INT sel = UINTVAL (trueop2);
7782 485868 : unsigned HOST_WIDE_INT mask;
7783 485868 : if (n_elts == HOST_BITS_PER_WIDE_INT)
7784 : mask = -1;
7785 : else
7786 483411 : mask = (HOST_WIDE_INT_1U << n_elts) - 1;
7787 :
7788 485868 : if (!(sel & mask) && !side_effects_p (op0))
7789 : return op1;
7790 485431 : if ((sel & mask) == mask && !side_effects_p (op1))
7791 : return op0;
7792 :
7793 474677 : rtx trueop0 = avoid_constant_pool_reference (op0);
7794 474677 : rtx trueop1 = avoid_constant_pool_reference (op1);
7795 474677 : if (GET_CODE (trueop0) == CONST_VECTOR
7796 10131 : && GET_CODE (trueop1) == CONST_VECTOR)
7797 : {
7798 5639 : rtvec v = rtvec_alloc (n_elts);
7799 5639 : unsigned int i;
7800 :
7801 59296 : for (i = 0; i < n_elts; i++)
7802 48018 : RTVEC_ELT (v, i) = ((sel & (HOST_WIDE_INT_1U << i))
7803 48018 : ? CONST_VECTOR_ELT (trueop0, i)
7804 27585 : : CONST_VECTOR_ELT (trueop1, i));
7805 5639 : return gen_rtx_CONST_VECTOR (mode, v);
7806 : }
7807 :
7808 469038 : if (swap_commutative_operands_p (op0, op1)
7809 : /* Two operands have same precedence, then first bit of mask
7810 : select first operand. */
7811 469038 : || (!swap_commutative_operands_p (op1, op0) && !(sel & 1)))
7812 31814 : return simplify_gen_ternary (code, mode, mode, op1, op0,
7813 63628 : GEN_INT (~sel & mask));
7814 :
7815 : /* Replace (vec_merge (vec_merge a b m) c n) with (vec_merge b c n)
7816 : if no element from a appears in the result. */
7817 437224 : if (GET_CODE (op0) == VEC_MERGE)
7818 : {
7819 17230 : tem = avoid_constant_pool_reference (XEXP (op0, 2));
7820 17230 : if (CONST_INT_P (tem))
7821 : {
7822 1487 : unsigned HOST_WIDE_INT sel0 = UINTVAL (tem);
7823 1487 : if (!(sel & sel0 & mask) && !side_effects_p (XEXP (op0, 0)))
7824 104 : return simplify_gen_ternary (code, mode, mode,
7825 104 : XEXP (op0, 1), op1, op2);
7826 1383 : if (!(sel & ~sel0 & mask) && !side_effects_p (XEXP (op0, 1)))
7827 835 : return simplify_gen_ternary (code, mode, mode,
7828 835 : XEXP (op0, 0), op1, op2);
7829 :
7830 : /* Replace (vec_merge (vec_merge a b m) a n) with
7831 : (vec_merge a b (m|~n)). */
7832 548 : if (rtx_equal_p (XEXP (op0, 0), op1)
7833 548 : && ! side_effects_p (op1))
7834 19 : return simplify_gen_ternary (code, mode, mode,
7835 : op1, XEXP (op0, 1),
7836 38 : GEN_INT ((sel0 | ~sel) & mask));
7837 : /* Replace (vec_merge (vec_merge b a m) a n) with
7838 : (vec_merge b a (m&n)). */
7839 529 : if (rtx_equal_p (XEXP (op0, 1), op1)
7840 529 : && ! side_effects_p (op1))
7841 0 : return simplify_gen_ternary (code, mode, mode,
7842 : XEXP (op0, 0), op1,
7843 0 : GEN_INT (sel & sel0 & mask));
7844 : }
7845 : }
7846 436266 : if (GET_CODE (op1) == VEC_MERGE)
7847 : {
7848 588 : tem = avoid_constant_pool_reference (XEXP (op1, 2));
7849 588 : if (CONST_INT_P (tem))
7850 : {
7851 557 : unsigned HOST_WIDE_INT sel1 = UINTVAL (tem);
7852 557 : if (!(~sel & sel1 & mask) && !side_effects_p (XEXP (op1, 0)))
7853 526 : return simplify_gen_ternary (code, mode, mode,
7854 526 : op0, XEXP (op1, 1), op2);
7855 31 : if (!(~sel & ~sel1 & mask) && !side_effects_p (XEXP (op1, 1)))
7856 4 : return simplify_gen_ternary (code, mode, mode,
7857 4 : op0, XEXP (op1, 0), op2);
7858 :
7859 : /* Replace (vec_merge a (vec_merge a b m) n) with
7860 : (vec_merge a b (m|n)). */
7861 27 : if (rtx_equal_p (XEXP (op1, 0), op0)
7862 27 : && ! side_effects_p (op0))
7863 1 : return simplify_gen_ternary (code, mode, mode,
7864 : op0, XEXP (op1, 1),
7865 1 : GEN_INT ((sel | sel1) & mask));
7866 :
7867 : /* Replace (vec_merge a (vec_merge b a m) n) with
7868 : (vec_merge a b (~m|n)). */
7869 26 : if (rtx_equal_p (XEXP (op1, 1), op0)
7870 26 : && ! side_effects_p (op0))
7871 0 : return simplify_gen_ternary (code, mode, mode,
7872 : op0, XEXP (op1, 0),
7873 0 : GEN_INT ((sel | ~sel1) & mask));
7874 : }
7875 : }
7876 :
7877 : /* Replace (vec_merge (vec_duplicate (vec_select a parallel (i))) a 1 << i)
7878 : with a. */
7879 435735 : if (GET_CODE (op0) == VEC_DUPLICATE
7880 152853 : && GET_CODE (XEXP (op0, 0)) == VEC_SELECT
7881 734 : && GET_CODE (XEXP (XEXP (op0, 0), 1)) == PARALLEL
7882 437203 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (op0, 0))), 1))
7883 : {
7884 666 : tem = XVECEXP ((XEXP (XEXP (op0, 0), 1)), 0, 0);
7885 666 : if (CONST_INT_P (tem) && CONST_INT_P (op2))
7886 : {
7887 666 : if (XEXP (XEXP (op0, 0), 0) == op1
7888 2 : && UINTVAL (op2) == HOST_WIDE_INT_1U << UINTVAL (tem))
7889 : return op1;
7890 : }
7891 : }
7892 : /* Replace (vec_merge (vec_duplicate (X)) (const_vector [A, B])
7893 : (const_int N))
7894 : with (vec_concat (X) (B)) if N == 1 or
7895 : (vec_concat (A) (X)) if N == 2. */
7896 435733 : if (GET_CODE (op0) == VEC_DUPLICATE
7897 152851 : && GET_CODE (op1) == CONST_VECTOR
7898 162074 : && known_eq (CONST_VECTOR_NUNITS (op1), 2)
7899 2356 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7900 436911 : && IN_RANGE (sel, 1, 2))
7901 : {
7902 1176 : rtx newop0 = XEXP (op0, 0);
7903 1176 : rtx newop1 = CONST_VECTOR_ELT (op1, 2 - sel);
7904 1176 : if (sel == 2)
7905 123 : std::swap (newop0, newop1);
7906 1176 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7907 : }
7908 : /* Replace (vec_merge (vec_duplicate x) (vec_concat (y) (z)) (const_int N))
7909 : with (vec_concat x z) if N == 1, or (vec_concat y x) if N == 2.
7910 : Only applies for vectors of two elements. */
7911 434557 : if (GET_CODE (op0) == VEC_DUPLICATE
7912 151675 : && GET_CODE (op1) == VEC_CONCAT
7913 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7914 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
7915 434557 : && IN_RANGE (sel, 1, 2))
7916 : {
7917 0 : rtx newop0 = XEXP (op0, 0);
7918 0 : rtx newop1 = XEXP (op1, 2 - sel);
7919 0 : rtx otherop = XEXP (op1, sel - 1);
7920 0 : if (sel == 2)
7921 0 : std::swap (newop0, newop1);
7922 : /* Don't want to throw away the other part of the vec_concat if
7923 : it has side-effects. */
7924 0 : if (!side_effects_p (otherop))
7925 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7926 : }
7927 :
7928 : /* Replace:
7929 :
7930 : (vec_merge:outer (vec_duplicate:outer x:inner)
7931 : (subreg:outer y:inner 0)
7932 : (const_int N))
7933 :
7934 : with (vec_concat:outer x:inner y:inner) if N == 1,
7935 : or (vec_concat:outer y:inner x:inner) if N == 2.
7936 :
7937 : Implicitly, this means we have a paradoxical subreg, but such
7938 : a check is cheap, so make it anyway.
7939 :
7940 : Only applies for vectors of two elements. */
7941 434557 : if (GET_CODE (op0) == VEC_DUPLICATE
7942 151675 : && GET_CODE (op1) == SUBREG
7943 47892 : && GET_MODE (op1) == GET_MODE (op0)
7944 47892 : && GET_MODE (SUBREG_REG (op1)) == GET_MODE (XEXP (op0, 0))
7945 0 : && paradoxical_subreg_p (op1)
7946 0 : && subreg_lowpart_p (op1)
7947 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7948 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
7949 434557 : && IN_RANGE (sel, 1, 2))
7950 : {
7951 0 : rtx newop0 = XEXP (op0, 0);
7952 0 : rtx newop1 = SUBREG_REG (op1);
7953 0 : if (sel == 2)
7954 0 : std::swap (newop0, newop1);
7955 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7956 : }
7957 :
7958 : /* Same as above but with switched operands:
7959 : Replace (vec_merge:outer (subreg:outer x:inner 0)
7960 : (vec_duplicate:outer y:inner)
7961 : (const_int N))
7962 :
7963 : with (vec_concat:outer x:inner y:inner) if N == 1,
7964 : or (vec_concat:outer y:inner x:inner) if N == 2. */
7965 434557 : if (GET_CODE (op1) == VEC_DUPLICATE
7966 32084 : && GET_CODE (op0) == SUBREG
7967 28865 : && GET_MODE (op0) == GET_MODE (op1)
7968 28865 : && GET_MODE (SUBREG_REG (op0)) == GET_MODE (XEXP (op1, 0))
7969 0 : && paradoxical_subreg_p (op0)
7970 0 : && subreg_lowpart_p (op0)
7971 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
7972 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7973 434557 : && IN_RANGE (sel, 1, 2))
7974 : {
7975 0 : rtx newop0 = SUBREG_REG (op0);
7976 0 : rtx newop1 = XEXP (op1, 0);
7977 0 : if (sel == 2)
7978 0 : std::swap (newop0, newop1);
7979 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7980 : }
7981 :
7982 : /* Replace (vec_merge (vec_duplicate x) (vec_duplicate y)
7983 : (const_int n))
7984 : with (vec_concat x y) or (vec_concat y x) depending on value
7985 : of N. */
7986 434557 : if (GET_CODE (op0) == VEC_DUPLICATE
7987 151675 : && GET_CODE (op1) == VEC_DUPLICATE
7988 200 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7989 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
7990 434557 : && IN_RANGE (sel, 1, 2))
7991 : {
7992 0 : rtx newop0 = XEXP (op0, 0);
7993 0 : rtx newop1 = XEXP (op1, 0);
7994 0 : if (sel == 2)
7995 0 : std::swap (newop0, newop1);
7996 :
7997 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7998 : }
7999 : }
8000 :
8001 755299 : if (rtx_equal_p (op0, op1)
8002 755299 : && !side_effects_p (op2) && !side_effects_p (op1))
8003 : return op0;
8004 :
8005 755005 : if (!side_effects_p (op2))
8006 : {
8007 751327 : rtx top0
8008 751327 : = may_trap_p (op0) ? NULL_RTX : simplify_merge_mask (op0, op2, 0);
8009 751327 : rtx top1
8010 751327 : = may_trap_p (op1) ? NULL_RTX : simplify_merge_mask (op1, op2, 1);
8011 751327 : if (top0 || top1)
8012 998 : return simplify_gen_ternary (code, mode, mode,
8013 : top0 ? top0 : op0,
8014 819 : top1 ? top1 : op1, op2);
8015 : }
8016 :
8017 : break;
8018 :
8019 0 : default:
8020 0 : gcc_unreachable ();
8021 : }
8022 :
8023 : return 0;
8024 : }
8025 :
8026 : /* Try to calculate NUM_BYTES bytes of the target memory image of X,
8027 : starting at byte FIRST_BYTE. Return true on success and add the
8028 : bytes to BYTES, such that each byte has BITS_PER_UNIT bits and such
8029 : that the bytes follow target memory order. Leave BYTES unmodified
8030 : on failure.
8031 :
8032 : MODE is the mode of X. The caller must reserve NUM_BYTES bytes in
8033 : BYTES before calling this function. */
8034 :
8035 : bool
8036 13765440 : native_encode_rtx (machine_mode mode, rtx x, vec<target_unit> &bytes,
8037 : unsigned int first_byte, unsigned int num_bytes)
8038 : {
8039 : /* Check the mode is sensible. */
8040 13765440 : gcc_assert (GET_MODE (x) == VOIDmode
8041 : ? is_a <scalar_int_mode> (mode)
8042 : : mode == GET_MODE (x));
8043 :
8044 13765440 : if (GET_CODE (x) == CONST_VECTOR)
8045 : {
8046 : /* CONST_VECTOR_ELT follows target memory order, so no shuffling
8047 : is necessary. The only complication is that MODE_VECTOR_BOOL
8048 : vectors can have several elements per byte. */
8049 1117718 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
8050 : GET_MODE_NUNITS (mode));
8051 558859 : unsigned int elt = first_byte * BITS_PER_UNIT / elt_bits;
8052 558859 : if (elt_bits < BITS_PER_UNIT)
8053 : {
8054 : /* This is the only case in which elements can be smaller than
8055 : a byte. */
8056 0 : gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
8057 0 : auto mask = GET_MODE_MASK (GET_MODE_INNER (mode));
8058 0 : for (unsigned int i = 0; i < num_bytes; ++i)
8059 : {
8060 0 : target_unit value = 0;
8061 0 : for (unsigned int j = 0; j < BITS_PER_UNIT; j += elt_bits)
8062 : {
8063 0 : if (INTVAL (CONST_VECTOR_ELT (x, elt)))
8064 0 : value |= mask << j;
8065 0 : elt += 1;
8066 : }
8067 0 : bytes.quick_push (value);
8068 : }
8069 : return true;
8070 : }
8071 :
8072 558859 : unsigned int start = bytes.length ();
8073 558859 : unsigned int elt_bytes = GET_MODE_UNIT_SIZE (mode);
8074 : /* Make FIRST_BYTE relative to ELT. */
8075 558859 : first_byte %= elt_bytes;
8076 2793517 : while (num_bytes > 0)
8077 : {
8078 : /* Work out how many bytes we want from element ELT. */
8079 2234658 : unsigned int chunk_bytes = MIN (num_bytes, elt_bytes - first_byte);
8080 4469316 : if (!native_encode_rtx (GET_MODE_INNER (mode),
8081 : CONST_VECTOR_ELT (x, elt), bytes,
8082 : first_byte, chunk_bytes))
8083 : {
8084 0 : bytes.truncate (start);
8085 0 : return false;
8086 : }
8087 2234658 : elt += 1;
8088 2234658 : first_byte = 0;
8089 2234658 : num_bytes -= chunk_bytes;
8090 : }
8091 : return true;
8092 : }
8093 :
8094 : /* All subsequent cases are limited to scalars. */
8095 13206581 : scalar_mode smode;
8096 13237850 : if (!is_a <scalar_mode> (mode, &smode))
8097 : return false;
8098 :
8099 : /* Make sure that the region is in range. */
8100 13206581 : unsigned int end_byte = first_byte + num_bytes;
8101 13206581 : unsigned int mode_bytes = GET_MODE_SIZE (smode);
8102 13206581 : gcc_assert (end_byte <= mode_bytes);
8103 :
8104 13206581 : if (CONST_SCALAR_INT_P (x))
8105 : {
8106 : /* The target memory layout is affected by both BYTES_BIG_ENDIAN
8107 : and WORDS_BIG_ENDIAN. Use the subreg machinery to get the lsb
8108 : position of each byte. */
8109 12525732 : rtx_mode_t value (x, smode);
8110 12525732 : wide_int_ref value_wi (value);
8111 53496974 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
8112 : {
8113 : /* Always constant because the inputs are. */
8114 40971242 : unsigned int lsb
8115 40971242 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
8116 : /* Operate directly on the encoding rather than using
8117 : wi::extract_uhwi, so that we preserve the sign or zero
8118 : extension for modes that are not a whole number of bits in
8119 : size. (Zero extension is only used for the combination of
8120 : innermode == BImode && STORE_FLAG_VALUE == 1). */
8121 40971242 : unsigned int elt = lsb / HOST_BITS_PER_WIDE_INT;
8122 40971242 : unsigned int shift = lsb % HOST_BITS_PER_WIDE_INT;
8123 40971242 : unsigned HOST_WIDE_INT uhwi = value_wi.elt (elt);
8124 40971242 : bytes.quick_push (uhwi >> shift);
8125 : }
8126 12525732 : return true;
8127 : }
8128 :
8129 680849 : if (CONST_DOUBLE_P (x))
8130 : {
8131 : /* real_to_target produces an array of integers in target memory order.
8132 : All integers before the last one have 32 bits; the last one may
8133 : have 32 bits or fewer, depending on whether the mode bitsize
8134 : is divisible by 32. Each of these integers is then laid out
8135 : in target memory as any other integer would be. */
8136 649580 : long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
8137 649580 : real_to_target (el32, CONST_DOUBLE_REAL_VALUE (x), smode);
8138 :
8139 : /* The (maximum) number of target bytes per element of el32. */
8140 649580 : unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
8141 649580 : gcc_assert (bytes_per_el32 != 0);
8142 :
8143 : /* Build up the integers in a similar way to the CONST_SCALAR_INT_P
8144 : handling above. */
8145 4444379 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
8146 : {
8147 3794799 : unsigned int index = byte / bytes_per_el32;
8148 3794799 : unsigned int subbyte = byte % bytes_per_el32;
8149 3794799 : unsigned int int_bytes = MIN (bytes_per_el32,
8150 : mode_bytes - index * bytes_per_el32);
8151 : /* Always constant because the inputs are. */
8152 3794799 : unsigned int lsb
8153 3794799 : = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
8154 3794799 : bytes.quick_push ((unsigned long) el32[index] >> lsb);
8155 : }
8156 649580 : return true;
8157 : }
8158 :
8159 31269 : if (GET_CODE (x) == CONST_FIXED)
8160 : {
8161 0 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
8162 : {
8163 : /* Always constant because the inputs are. */
8164 0 : unsigned int lsb
8165 0 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
8166 0 : unsigned HOST_WIDE_INT piece = CONST_FIXED_VALUE_LOW (x);
8167 0 : if (lsb >= HOST_BITS_PER_WIDE_INT)
8168 : {
8169 0 : lsb -= HOST_BITS_PER_WIDE_INT;
8170 0 : piece = CONST_FIXED_VALUE_HIGH (x);
8171 : }
8172 0 : bytes.quick_push (piece >> lsb);
8173 : }
8174 : return true;
8175 : }
8176 :
8177 : return false;
8178 : }
8179 :
8180 : /* Read a vector of mode MODE from the target memory image given by BYTES,
8181 : starting at byte FIRST_BYTE. The vector is known to be encodable using
8182 : NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each,
8183 : and BYTES is known to have enough bytes to supply NPATTERNS *
8184 : NELTS_PER_PATTERN vector elements. Each element of BYTES contains
8185 : BITS_PER_UNIT bits and the bytes are in target memory order.
8186 :
8187 : Return the vector on success, otherwise return NULL_RTX. */
8188 :
8189 : rtx
8190 292848 : native_decode_vector_rtx (machine_mode mode, const vec<target_unit> &bytes,
8191 : unsigned int first_byte, unsigned int npatterns,
8192 : unsigned int nelts_per_pattern)
8193 : {
8194 292848 : rtx_vector_builder builder (mode, npatterns, nelts_per_pattern);
8195 :
8196 585696 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
8197 : GET_MODE_NUNITS (mode));
8198 292848 : if (elt_bits < BITS_PER_UNIT)
8199 : {
8200 : /* This is the only case in which elements can be smaller than a byte.
8201 : Element 0 is always in the lsb of the containing byte. */
8202 0 : gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
8203 0 : for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
8204 : {
8205 0 : unsigned int bit_index = first_byte * BITS_PER_UNIT + i * elt_bits;
8206 0 : unsigned int byte_index = bit_index / BITS_PER_UNIT;
8207 0 : unsigned int lsb = bit_index % BITS_PER_UNIT;
8208 0 : unsigned int value = bytes[byte_index] >> lsb;
8209 0 : builder.quick_push (gen_int_mode (value, GET_MODE_INNER (mode)));
8210 : }
8211 : }
8212 : else
8213 : {
8214 1187081 : for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
8215 : {
8216 1788466 : rtx x = native_decode_rtx (GET_MODE_INNER (mode), bytes, first_byte);
8217 894233 : if (!x)
8218 0 : return NULL_RTX;
8219 894233 : builder.quick_push (x);
8220 894233 : first_byte += elt_bits / BITS_PER_UNIT;
8221 : }
8222 : }
8223 292848 : return builder.build ();
8224 292848 : }
8225 :
8226 : /* Extract a PRECISION-bit integer from bytes [FIRST_BYTE, FIRST_BYTE + SIZE)
8227 : of target memory image BYTES. */
8228 :
8229 : wide_int
8230 11642413 : native_decode_int (const vec<target_unit> &bytes, unsigned int first_byte,
8231 : unsigned int size, unsigned int precision)
8232 : {
8233 : /* Pull the bytes msb first, so that we can use simple
8234 : shift-and-insert wide_int operations. */
8235 11642413 : wide_int result (wi::zero (precision));
8236 53657261 : for (unsigned int i = 0; i < size; ++i)
8237 : {
8238 42014848 : unsigned int lsb = (size - i - 1) * BITS_PER_UNIT;
8239 : /* Always constant because the inputs are. */
8240 42014848 : unsigned int subbyte
8241 42014848 : = subreg_size_offset_from_lsb (1, size, lsb).to_constant ();
8242 42014848 : result <<= BITS_PER_UNIT;
8243 42014848 : result |= bytes[first_byte + subbyte];
8244 : }
8245 11642413 : return result;
8246 : }
8247 :
8248 : /* Read an rtx of mode MODE from the target memory image given by BYTES,
8249 : starting at byte FIRST_BYTE. Each element of BYTES contains BITS_PER_UNIT
8250 : bits and the bytes are in target memory order. The image has enough
8251 : values to specify all bytes of MODE.
8252 :
8253 : Return the rtx on success, otherwise return NULL_RTX. */
8254 :
8255 : rtx
8256 11978598 : native_decode_rtx (machine_mode mode, const vec<target_unit> &bytes,
8257 : unsigned int first_byte)
8258 : {
8259 11978598 : if (VECTOR_MODE_P (mode))
8260 : {
8261 : /* If we know at compile time how many elements there are,
8262 : pull each element directly from BYTES. */
8263 91064 : unsigned int nelts;
8264 182128 : if (GET_MODE_NUNITS (mode).is_constant (&nelts))
8265 91064 : return native_decode_vector_rtx (mode, bytes, first_byte, nelts, 1);
8266 : return NULL_RTX;
8267 : }
8268 :
8269 11887534 : scalar_int_mode imode;
8270 11887534 : if (is_a <scalar_int_mode> (mode, &imode)
8271 11642413 : && GET_MODE_PRECISION (imode) <= MAX_BITSIZE_MODE_ANY_INT)
8272 : {
8273 11642413 : auto result = native_decode_int (bytes, first_byte,
8274 11642413 : GET_MODE_SIZE (imode),
8275 23284826 : GET_MODE_PRECISION (imode));
8276 11642413 : return immed_wide_int_const (result, imode);
8277 11642413 : }
8278 :
8279 245121 : scalar_float_mode fmode;
8280 245121 : if (is_a <scalar_float_mode> (mode, &fmode))
8281 : {
8282 : /* We need to build an array of integers in target memory order.
8283 : All integers before the last one have 32 bits; the last one may
8284 : have 32 bits or fewer, depending on whether the mode bitsize
8285 : is divisible by 32. */
8286 245091 : long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
8287 245091 : unsigned int num_el32 = CEIL (GET_MODE_BITSIZE (fmode), 32);
8288 245091 : memset (el32, 0, num_el32 * sizeof (long));
8289 :
8290 : /* The (maximum) number of target bytes per element of el32. */
8291 245091 : unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
8292 245091 : gcc_assert (bytes_per_el32 != 0);
8293 :
8294 245091 : unsigned int mode_bytes = GET_MODE_SIZE (fmode);
8295 1703235 : for (unsigned int byte = 0; byte < mode_bytes; ++byte)
8296 : {
8297 1458144 : unsigned int index = byte / bytes_per_el32;
8298 1458144 : unsigned int subbyte = byte % bytes_per_el32;
8299 1458144 : unsigned int int_bytes = MIN (bytes_per_el32,
8300 : mode_bytes - index * bytes_per_el32);
8301 : /* Always constant because the inputs are. */
8302 1458144 : unsigned int lsb
8303 1458144 : = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
8304 1458144 : el32[index] |= (unsigned long) bytes[first_byte + byte] << lsb;
8305 : }
8306 245091 : REAL_VALUE_TYPE r;
8307 245091 : real_from_target (&r, el32, fmode);
8308 245091 : return const_double_from_real_value (r, fmode);
8309 : }
8310 :
8311 30 : if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
8312 : {
8313 0 : scalar_mode smode = as_a <scalar_mode> (mode);
8314 0 : FIXED_VALUE_TYPE f;
8315 0 : f.data.low = 0;
8316 0 : f.data.high = 0;
8317 0 : f.mode = smode;
8318 :
8319 0 : unsigned int mode_bytes = GET_MODE_SIZE (smode);
8320 0 : for (unsigned int byte = 0; byte < mode_bytes; ++byte)
8321 : {
8322 : /* Always constant because the inputs are. */
8323 0 : unsigned int lsb
8324 0 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
8325 0 : unsigned HOST_WIDE_INT unit = bytes[first_byte + byte];
8326 0 : if (lsb >= HOST_BITS_PER_WIDE_INT)
8327 0 : f.data.high |= unit << (lsb - HOST_BITS_PER_WIDE_INT);
8328 : else
8329 0 : f.data.low |= unit << lsb;
8330 : }
8331 0 : return CONST_FIXED_FROM_FIXED_VALUE (f, mode);
8332 : }
8333 :
8334 : return NULL_RTX;
8335 : }
8336 :
8337 : /* Simplify a byte offset BYTE into CONST_VECTOR X. The main purpose
8338 : is to convert a runtime BYTE value into a constant one. */
8339 :
8340 : static poly_uint64
8341 348282 : simplify_const_vector_byte_offset (rtx x, poly_uint64 byte)
8342 : {
8343 : /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
8344 348282 : machine_mode mode = GET_MODE (x);
8345 696564 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
8346 : GET_MODE_NUNITS (mode));
8347 : /* The number of bits needed to encode one element from each pattern. */
8348 348282 : unsigned int sequence_bits = CONST_VECTOR_NPATTERNS (x) * elt_bits;
8349 :
8350 : /* Identify the start point in terms of a sequence number and a byte offset
8351 : within that sequence. */
8352 348282 : poly_uint64 first_sequence;
8353 348282 : unsigned HOST_WIDE_INT subbit;
8354 348282 : if (can_div_trunc_p (byte * BITS_PER_UNIT, sequence_bits,
8355 : &first_sequence, &subbit))
8356 : {
8357 348282 : unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
8358 348282 : if (nelts_per_pattern == 1)
8359 : /* This is a duplicated vector, so the value of FIRST_SEQUENCE
8360 : doesn't matter. */
8361 265789 : byte = subbit / BITS_PER_UNIT;
8362 82493 : else if (nelts_per_pattern == 2 && known_gt (first_sequence, 0U))
8363 : {
8364 : /* The subreg drops the first element from each pattern and
8365 : only uses the second element. Find the first sequence
8366 : that starts on a byte boundary. */
8367 5568 : subbit += least_common_multiple (sequence_bits, BITS_PER_UNIT);
8368 5568 : byte = subbit / BITS_PER_UNIT;
8369 : }
8370 : }
8371 348282 : return byte;
8372 : }
8373 :
8374 : /* Subroutine of simplify_subreg in which:
8375 :
8376 : - X is known to be a CONST_VECTOR
8377 : - OUTERMODE is known to be a vector mode
8378 :
8379 : Try to handle the subreg by operating on the CONST_VECTOR encoding
8380 : rather than on each individual element of the CONST_VECTOR.
8381 :
8382 : Return the simplified subreg on success, otherwise return NULL_RTX. */
8383 :
8384 : static rtx
8385 209709 : simplify_const_vector_subreg (machine_mode outermode, rtx x,
8386 : machine_mode innermode, unsigned int first_byte)
8387 : {
8388 : /* Paradoxical subregs of vectors have dubious semantics. */
8389 209709 : if (paradoxical_subreg_p (outermode, innermode))
8390 : return NULL_RTX;
8391 :
8392 : /* We can only preserve the semantics of a stepped pattern if the new
8393 : vector element is the same as the original one. */
8394 209563 : if (CONST_VECTOR_STEPPED_P (x)
8395 230345 : && GET_MODE_INNER (outermode) != GET_MODE_INNER (innermode))
8396 : return NULL_RTX;
8397 :
8398 : /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
8399 201784 : unsigned int x_elt_bits
8400 201784 : = vector_element_size (GET_MODE_PRECISION (innermode),
8401 : GET_MODE_NUNITS (innermode));
8402 201784 : unsigned int out_elt_bits
8403 201784 : = vector_element_size (GET_MODE_PRECISION (outermode),
8404 : GET_MODE_NUNITS (outermode));
8405 :
8406 : /* The number of bits needed to encode one element from every pattern
8407 : of the original vector. */
8408 201784 : unsigned int x_sequence_bits = CONST_VECTOR_NPATTERNS (x) * x_elt_bits;
8409 :
8410 : /* The number of bits needed to encode one element from every pattern
8411 : of the result. */
8412 201784 : unsigned int out_sequence_bits
8413 201784 : = least_common_multiple (x_sequence_bits, out_elt_bits);
8414 :
8415 : /* Work out the number of interleaved patterns in the output vector
8416 : and the number of encoded elements per pattern. */
8417 201784 : unsigned int out_npatterns = out_sequence_bits / out_elt_bits;
8418 201784 : unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
8419 :
8420 : /* The encoding scheme requires the number of elements to be a multiple
8421 : of the number of patterns, so that each pattern appears at least once
8422 : and so that the same number of elements appear from each pattern. */
8423 403568 : bool ok_p = multiple_p (GET_MODE_NUNITS (outermode), out_npatterns);
8424 201784 : unsigned int const_nunits;
8425 403568 : if (GET_MODE_NUNITS (outermode).is_constant (&const_nunits)
8426 201784 : && (!ok_p || out_npatterns * nelts_per_pattern > const_nunits))
8427 : {
8428 : /* Either the encoding is invalid, or applying it would give us
8429 : more elements than we need. Just encode each element directly. */
8430 : out_npatterns = const_nunits;
8431 : nelts_per_pattern = 1;
8432 : }
8433 : else if (!ok_p)
8434 : return NULL_RTX;
8435 :
8436 : /* Get enough bytes of X to form the new encoding. */
8437 201784 : unsigned int buffer_bits = out_npatterns * nelts_per_pattern * out_elt_bits;
8438 201784 : unsigned int buffer_bytes = CEIL (buffer_bits, BITS_PER_UNIT);
8439 201784 : auto_vec<target_unit, 128> buffer (buffer_bytes);
8440 201784 : if (!native_encode_rtx (innermode, x, buffer, first_byte, buffer_bytes))
8441 : return NULL_RTX;
8442 :
8443 : /* Re-encode the bytes as OUTERMODE. */
8444 201784 : return native_decode_vector_rtx (outermode, buffer, 0, out_npatterns,
8445 201784 : nelts_per_pattern);
8446 201784 : }
8447 :
8448 : /* Try to simplify a subreg of a constant by encoding the subreg region
8449 : as a sequence of target bytes and reading them back in the new mode.
8450 : Return the new value on success, otherwise return null.
8451 :
8452 : The subreg has outer mode OUTERMODE, inner mode INNERMODE, inner value X
8453 : and byte offset FIRST_BYTE. */
8454 :
8455 : static rtx
8456 10796899 : simplify_immed_subreg (fixed_size_mode outermode, rtx x,
8457 : machine_mode innermode, unsigned int first_byte)
8458 : {
8459 10796899 : unsigned int buffer_bytes = GET_MODE_SIZE (outermode);
8460 10796899 : auto_vec<target_unit, 128> buffer (buffer_bytes);
8461 :
8462 : /* Some ports misuse CCmode. */
8463 10796899 : if (GET_MODE_CLASS (outermode) == MODE_CC && CONST_INT_P (x))
8464 : return x;
8465 :
8466 : /* Paradoxical subregs read undefined values for bytes outside of the
8467 : inner value. However, we have traditionally always sign-extended
8468 : integer constants and zero-extended others. */
8469 10794883 : unsigned int inner_bytes = buffer_bytes;
8470 10794883 : if (paradoxical_subreg_p (outermode, innermode))
8471 : {
8472 961950 : if (!GET_MODE_SIZE (innermode).is_constant (&inner_bytes))
8473 0 : return NULL_RTX;
8474 :
8475 480975 : target_unit filler = 0;
8476 480975 : if (CONST_SCALAR_INT_P (x) && wi::neg_p (rtx_mode_t (x, innermode)))
8477 45523 : filler = -1;
8478 :
8479 : /* Add any leading bytes due to big-endian layout. The number of
8480 : bytes must be constant because both modes have constant size. */
8481 480975 : unsigned int leading_bytes
8482 480975 : = -byte_lowpart_offset (outermode, innermode).to_constant ();
8483 480975 : for (unsigned int i = 0; i < leading_bytes; ++i)
8484 0 : buffer.quick_push (filler);
8485 :
8486 480975 : if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
8487 0 : return NULL_RTX;
8488 :
8489 : /* Add any trailing bytes due to little-endian layout. */
8490 6294300 : while (buffer.length () < buffer_bytes)
8491 2666175 : buffer.quick_push (filler);
8492 : }
8493 10313908 : else if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
8494 : return NULL_RTX;
8495 10794883 : rtx ret = native_decode_rtx (outermode, buffer, 0);
8496 10794883 : if (ret && FLOAT_MODE_P (outermode))
8497 : {
8498 129436 : auto_vec<target_unit, 128> buffer2 (buffer_bytes);
8499 129436 : if (!native_encode_rtx (outermode, ret, buffer2, 0, buffer_bytes))
8500 : return NULL_RTX;
8501 1424871 : for (unsigned int i = 0; i < buffer_bytes; ++i)
8502 1295470 : if (buffer[i] != buffer2[i])
8503 : return NULL_RTX;
8504 129436 : }
8505 : return ret;
8506 10796899 : }
8507 :
8508 : /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
8509 : Return 0 if no simplifications are possible. */
8510 : rtx
8511 73096073 : simplify_context::simplify_subreg (machine_mode outermode, rtx op,
8512 : machine_mode innermode, poly_uint64 byte)
8513 : {
8514 : /* Little bit of sanity checking. */
8515 73096073 : gcc_assert (innermode != VOIDmode);
8516 73096073 : gcc_assert (outermode != VOIDmode);
8517 73096073 : gcc_assert (innermode != BLKmode);
8518 73096073 : gcc_assert (outermode != BLKmode);
8519 :
8520 73096073 : gcc_assert (GET_MODE (op) == innermode
8521 : || GET_MODE (op) == VOIDmode);
8522 :
8523 146192146 : poly_uint64 outersize = GET_MODE_SIZE (outermode);
8524 73096073 : if (!multiple_p (byte, outersize))
8525 : return NULL_RTX;
8526 :
8527 146192106 : poly_uint64 innersize = GET_MODE_SIZE (innermode);
8528 73096053 : if (maybe_ge (byte, innersize))
8529 : return NULL_RTX;
8530 :
8531 73096053 : if (outermode == innermode && known_eq (byte, 0U))
8532 4528849 : return op;
8533 :
8534 68567204 : if (GET_CODE (op) == CONST_VECTOR)
8535 348282 : byte = simplify_const_vector_byte_offset (op, byte);
8536 :
8537 137134408 : if (multiple_p (byte, GET_MODE_UNIT_SIZE (innermode)))
8538 : {
8539 62768441 : rtx elt;
8540 :
8541 53893600 : if (VECTOR_MODE_P (outermode)
8542 26624523 : && GET_MODE_INNER (outermode) == GET_MODE_INNER (innermode)
8543 64494362 : && vec_duplicate_p (op, &elt))
8544 11871 : return gen_vec_duplicate (outermode, elt);
8545 :
8546 62764570 : if (outermode == GET_MODE_INNER (innermode)
8547 62764570 : && vec_duplicate_p (op, &elt))
8548 8000 : return elt;
8549 : }
8550 :
8551 68555333 : if (CONST_SCALAR_INT_P (op)
8552 57955746 : || CONST_DOUBLE_AS_FLOAT_P (op)
8553 57898349 : || CONST_FIXED_P (op)
8554 57898349 : || GET_CODE (op) == CONST_VECTOR)
8555 : {
8556 10998683 : unsigned HOST_WIDE_INT cbyte;
8557 10998683 : if (byte.is_constant (&cbyte))
8558 : {
8559 10998683 : if (GET_CODE (op) == CONST_VECTOR && VECTOR_MODE_P (outermode))
8560 : {
8561 209709 : rtx tmp = simplify_const_vector_subreg (outermode, op,
8562 : innermode, cbyte);
8563 209709 : if (tmp)
8564 10998683 : return tmp;
8565 : }
8566 :
8567 10796899 : fixed_size_mode fs_outermode;
8568 10796899 : if (is_a <fixed_size_mode> (outermode, &fs_outermode))
8569 10796899 : return simplify_immed_subreg (fs_outermode, op, innermode, cbyte);
8570 : }
8571 : }
8572 :
8573 : /* Changing mode twice with SUBREG => just change it once,
8574 : or not at all if changing back op starting mode. */
8575 57556650 : if (GET_CODE (op) == SUBREG)
8576 : {
8577 1312826 : machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
8578 2625652 : poly_uint64 innermostsize = GET_MODE_SIZE (innermostmode);
8579 1312826 : rtx newx;
8580 :
8581 : /* Make sure that the relationship between the two subregs is
8582 : known at compile time. */
8583 1312826 : if (!ordered_p (outersize, innermostsize))
8584 : return NULL_RTX;
8585 :
8586 1312826 : if (outermode == innermostmode
8587 664625 : && known_eq (byte, subreg_lowpart_offset (outermode, innermode))
8588 1977444 : && known_eq (SUBREG_BYTE (op),
8589 : subreg_lowpart_offset (innermode, innermostmode)))
8590 664618 : return SUBREG_REG (op);
8591 :
8592 : /* Work out the memory offset of the final OUTERMODE value relative
8593 : to the inner value of OP. */
8594 648208 : poly_int64 mem_offset = subreg_memory_offset (outermode,
8595 : innermode, byte);
8596 648208 : poly_int64 op_mem_offset = subreg_memory_offset (op);
8597 648208 : poly_int64 final_offset = mem_offset + op_mem_offset;
8598 :
8599 : /* See whether resulting subreg will be paradoxical. */
8600 648208 : if (!paradoxical_subreg_p (outermode, innermostmode))
8601 : {
8602 : /* Bail out in case resulting subreg would be incorrect. */
8603 1054074 : if (maybe_lt (final_offset, 0)
8604 1054059 : || maybe_ge (poly_uint64 (final_offset), innermostsize)
8605 1054067 : || !multiple_p (final_offset, outersize))
8606 15 : return NULL_RTX;
8607 : }
8608 : else
8609 : {
8610 121171 : poly_int64 required_offset = subreg_memory_offset (outermode,
8611 : innermostmode, 0);
8612 121171 : if (maybe_ne (final_offset, required_offset))
8613 0 : return NULL_RTX;
8614 : /* Paradoxical subregs always have byte offset 0. */
8615 121171 : final_offset = 0;
8616 : }
8617 :
8618 : /* Recurse for further possible simplifications. */
8619 648193 : newx = simplify_subreg (outermode, SUBREG_REG (op), innermostmode,
8620 648193 : final_offset);
8621 648193 : if (newx)
8622 : return newx;
8623 647815 : if (validate_subreg (outermode, innermostmode,
8624 647815 : SUBREG_REG (op), final_offset))
8625 : {
8626 593247 : newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
8627 593247 : if (SUBREG_PROMOTED_VAR_P (op)
8628 799 : && SUBREG_PROMOTED_SIGN (op) >= 0
8629 799 : && GET_MODE_CLASS (outermode) == MODE_INT
8630 795 : && known_ge (outersize, innersize)
8631 394 : && known_le (outersize, innermostsize)
8632 593257 : && subreg_lowpart_p (newx))
8633 : {
8634 10 : SUBREG_PROMOTED_VAR_P (newx) = 1;
8635 10 : SUBREG_PROMOTED_SET (newx, SUBREG_PROMOTED_GET (op));
8636 : }
8637 593247 : return newx;
8638 : }
8639 : return NULL_RTX;
8640 : }
8641 :
8642 : /* SUBREG of a hard register => just change the register number
8643 : and/or mode. If the hard register is not valid in that mode,
8644 : suppress this simplification. If the hard register is the stack,
8645 : frame, or argument pointer, leave this as a SUBREG. */
8646 :
8647 56243824 : if (REG_P (op) && HARD_REGISTER_P (op))
8648 : {
8649 10893498 : unsigned int regno, final_regno;
8650 :
8651 10893498 : regno = REGNO (op);
8652 10893498 : final_regno = simplify_subreg_regno (regno, innermode, byte, outermode);
8653 10893498 : if (HARD_REGISTER_NUM_P (final_regno))
8654 : {
8655 10867187 : rtx x = gen_rtx_REG_offset (op, outermode, final_regno,
8656 : subreg_memory_offset (outermode,
8657 : innermode, byte));
8658 :
8659 : /* Propagate original regno. We don't have any way to specify
8660 : the offset inside original regno, so do so only for lowpart.
8661 : The information is used only by alias analysis that cannot
8662 : grog partial register anyway. */
8663 :
8664 10867187 : if (known_eq (subreg_lowpart_offset (outermode, innermode), byte))
8665 8171083 : ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op);
8666 10867187 : return x;
8667 : }
8668 : }
8669 :
8670 : /* If we have a SUBREG of a register that we are replacing and we are
8671 : replacing it with a MEM, make a new MEM and try replacing the
8672 : SUBREG with it. Don't do this if the MEM has a mode-dependent address
8673 : or if we would be widening it. */
8674 :
8675 45376637 : if (MEM_P (op)
8676 1703307 : && ! mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op))
8677 : /* Allow splitting of volatile memory references in case we don't
8678 : have instruction to move the whole thing. */
8679 1703304 : && (! MEM_VOLATILE_P (op)
8680 45180 : || ! have_insn_for (SET, innermode))
8681 : && !(STRICT_ALIGNMENT && MEM_ALIGN (op) < GET_MODE_ALIGNMENT (outermode))
8682 47034761 : && known_le (outersize, innersize))
8683 816637 : return adjust_address_nv (op, outermode, byte);
8684 :
8685 : /* Handle complex or vector values represented as CONCAT or VEC_CONCAT
8686 : of two parts. */
8687 44560000 : if (GET_CODE (op) == CONCAT
8688 44560000 : || GET_CODE (op) == VEC_CONCAT)
8689 : {
8690 209515 : poly_uint64 final_offset;
8691 209515 : rtx part, res;
8692 :
8693 209515 : machine_mode part_mode = GET_MODE (XEXP (op, 0));
8694 209515 : if (part_mode == VOIDmode)
8695 11 : part_mode = GET_MODE_INNER (GET_MODE (op));
8696 419030 : poly_uint64 part_size = GET_MODE_SIZE (part_mode);
8697 209515 : if (known_lt (byte, part_size))
8698 : {
8699 207963 : part = XEXP (op, 0);
8700 207963 : final_offset = byte;
8701 : }
8702 1552 : else if (known_ge (byte, part_size))
8703 : {
8704 1552 : part = XEXP (op, 1);
8705 1552 : final_offset = byte - part_size;
8706 : }
8707 : else
8708 : return NULL_RTX;
8709 :
8710 209515 : if (maybe_gt (final_offset + outersize, part_size))
8711 : return NULL_RTX;
8712 :
8713 128710 : part_mode = GET_MODE (part);
8714 128710 : if (part_mode == VOIDmode)
8715 0 : part_mode = GET_MODE_INNER (GET_MODE (op));
8716 128710 : res = simplify_subreg (outermode, part, part_mode, final_offset);
8717 128710 : if (res)
8718 : return res;
8719 297 : if (GET_MODE (part) != VOIDmode
8720 297 : && validate_subreg (outermode, part_mode, part, final_offset))
8721 297 : return gen_rtx_SUBREG (outermode, part, final_offset);
8722 0 : return NULL_RTX;
8723 : }
8724 :
8725 : /* Simplify
8726 : (subreg (vec_merge (X)
8727 : (vector)
8728 : (const_int ((1 << N) | M)))
8729 : (N * sizeof (outermode)))
8730 : to
8731 : (subreg (X) (N * sizeof (outermode)))
8732 : */
8733 44350485 : unsigned int idx;
8734 88700970 : if (constant_multiple_p (byte, GET_MODE_SIZE (outermode), &idx)
8735 44350485 : && idx < HOST_BITS_PER_WIDE_INT
8736 44350485 : && GET_CODE (op) == VEC_MERGE
8737 658868 : && GET_MODE_INNER (innermode) == outermode
8738 4867 : && CONST_INT_P (XEXP (op, 2))
8739 44354770 : && (UINTVAL (XEXP (op, 2)) & (HOST_WIDE_INT_1U << idx)) != 0)
8740 4276 : return simplify_gen_subreg (outermode, XEXP (op, 0), innermode, byte);
8741 :
8742 : /* A SUBREG resulting from a zero extension may fold to zero if
8743 : it extracts higher bits that the ZERO_EXTEND's source bits. */
8744 44346209 : if (GET_CODE (op) == ZERO_EXTEND && SCALAR_INT_MODE_P (innermode))
8745 : {
8746 226635 : poly_uint64 bitpos = subreg_lsb_1 (outermode, innermode, byte);
8747 226635 : if (known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (XEXP (op, 0)))))
8748 55249 : return CONST0_RTX (outermode);
8749 : }
8750 :
8751 : /* Optimize SUBREGS of scalar integral ASHIFT by a valid constant. */
8752 44290960 : if (GET_CODE (op) == ASHIFT
8753 981056 : && SCALAR_INT_MODE_P (innermode)
8754 953226 : && CONST_INT_P (XEXP (op, 1))
8755 868793 : && INTVAL (XEXP (op, 1)) > 0
8756 46140759 : && known_gt (GET_MODE_BITSIZE (innermode), INTVAL (XEXP (op, 1))))
8757 : {
8758 868743 : HOST_WIDE_INT val = INTVAL (XEXP (op, 1));
8759 : /* A lowpart SUBREG of a ASHIFT by a constant may fold to zero. */
8760 868743 : if (known_eq (subreg_lowpart_offset (outermode, innermode), byte)
8761 1700603 : && known_le (GET_MODE_BITSIZE (outermode), val))
8762 193013 : return CONST0_RTX (outermode);
8763 : /* Optimize the highpart SUBREG of a suitable ASHIFT (ZERO_EXTEND). */
8764 710001 : if (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
8765 35034 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == outermode
8766 69754 : && known_eq (GET_MODE_BITSIZE (outermode), val)
8767 68542 : && known_eq (GET_MODE_BITSIZE (innermode), 2 * val)
8768 745035 : && known_eq (subreg_highpart_offset (outermode, innermode), byte))
8769 34271 : return XEXP (XEXP (op, 0), 0);
8770 : }
8771 :
8772 45681014 : auto distribute_subreg = [&](rtx op)
8773 : {
8774 1583067 : return simplify_subreg (outermode, op, innermode, byte);
8775 44097947 : };
8776 :
8777 : /* Try distributing the subreg through logic operations, if that
8778 : leads to all subexpressions being simplified. For example,
8779 : distributing the outer subreg in:
8780 :
8781 : (subreg:SI (not:QI (subreg:QI (reg:SI X) <lowpart>)) 0)
8782 :
8783 : gives:
8784 :
8785 : (not:SI (reg:SI X))
8786 :
8787 : This should be a win if the outermode is word_mode, since logical
8788 : operations on word_mode should (a) be no more expensive than logical
8789 : operations on subword modes and (b) are likely to be cheaper than
8790 : logical operations on multiword modes.
8791 :
8792 : Otherwise, handle the case where the subreg is non-narrowing and does
8793 : not change the number of words. The non-narrowing condition ensures
8794 : that we don't convert word_mode operations to subword operations. */
8795 44097947 : scalar_int_mode int_outermode, int_innermode;
8796 44097947 : if (is_a <scalar_int_mode> (outermode, &int_outermode)
8797 37090662 : && is_a <scalar_int_mode> (innermode, &int_innermode)
8798 79691185 : && (outermode == word_mode
8799 21770850 : || ((GET_MODE_PRECISION (int_outermode)
8800 21770850 : >= GET_MODE_PRECISION (int_innermode))
8801 4522890 : && (CEIL (GET_MODE_SIZE (int_outermode), UNITS_PER_WORD)
8802 4436114 : <= CEIL (GET_MODE_SIZE (int_innermode), UNITS_PER_WORD)))))
8803 18198018 : switch (GET_CODE (op))
8804 : {
8805 33571 : case NOT:
8806 33571 : if (rtx op0 = distribute_subreg (XEXP (op, 0)))
8807 3155 : return simplify_gen_unary (GET_CODE (op), outermode, op0, outermode);
8808 : break;
8809 :
8810 468162 : case AND:
8811 468162 : case IOR:
8812 468162 : case XOR:
8813 468162 : if (rtx op0 = distribute_subreg (XEXP (op, 0)))
8814 204683 : if (rtx op1 = distribute_subreg (XEXP (op, 1)))
8815 199873 : return simplify_gen_binary (GET_CODE (op), outermode, op0, op1);
8816 : break;
8817 :
8818 : default:
8819 : break;
8820 : }
8821 :
8822 43894919 : if (is_a <scalar_int_mode> (outermode, &int_outermode)
8823 36887634 : && is_a <scalar_int_mode> (innermode, &int_innermode)
8824 80782553 : && known_eq (byte, subreg_lowpart_offset (int_outermode, int_innermode)))
8825 : {
8826 : /* Handle polynomial integers. The upper bits of a paradoxical
8827 : subreg are undefined, so this is safe regardless of whether
8828 : we're truncating or extending. */
8829 33257659 : if (CONST_POLY_INT_P (op))
8830 : {
8831 : poly_wide_int val
8832 : = poly_wide_int::from (const_poly_int_value (op),
8833 : GET_MODE_PRECISION (int_outermode),
8834 : SIGNED);
8835 : return immed_wide_int_const (val, int_outermode);
8836 : }
8837 :
8838 33257659 : if (GET_MODE_PRECISION (int_outermode)
8839 33257659 : < GET_MODE_PRECISION (int_innermode))
8840 : {
8841 20522644 : rtx tem = simplify_truncation (int_outermode, op, int_innermode);
8842 20522644 : if (tem)
8843 : return tem;
8844 : }
8845 : }
8846 :
8847 : /* If the outer mode is not integral, try taking a subreg with the equivalent
8848 : integer outer mode and then bitcasting the result.
8849 : Other simplifications rely on integer to integer subregs and we'd
8850 : potentially miss out on optimizations otherwise. */
8851 84743648 : if (known_gt (GET_MODE_SIZE (innermode),
8852 : GET_MODE_SIZE (outermode))
8853 22480254 : && SCALAR_INT_MODE_P (innermode)
8854 21215731 : && !SCALAR_INT_MODE_P (outermode)
8855 65019340 : && int_mode_for_size (GET_MODE_BITSIZE (outermode),
8856 83631 : 0).exists (&int_outermode))
8857 : {
8858 83631 : rtx tem = simplify_subreg (int_outermode, op, innermode, byte);
8859 83631 : if (tem)
8860 1997 : return lowpart_subreg (outermode, tem, int_outermode);
8861 : }
8862 :
8863 : /* If OP is a vector comparison and the subreg is not changing the
8864 : number of elements or the size of the elements, change the result
8865 : of the comparison to the new mode. */
8866 42369827 : if (COMPARISON_P (op)
8867 299161 : && VECTOR_MODE_P (outermode)
8868 212334 : && VECTOR_MODE_P (innermode)
8869 636978 : && known_eq (GET_MODE_NUNITS (outermode), GET_MODE_NUNITS (innermode))
8870 42770507 : && known_eq (GET_MODE_UNIT_SIZE (outermode),
8871 : GET_MODE_UNIT_SIZE (innermode)))
8872 133216 : return simplify_gen_relational (GET_CODE (op), outermode, innermode,
8873 133216 : XEXP (op, 0), XEXP (op, 1));
8874 :
8875 : /* Distribute non-paradoxical subregs through logic ops in cases where
8876 : one term disappears.
8877 :
8878 : (subreg:M1 (and:M2 X C1)) -> (subreg:M1 X)
8879 : (subreg:M1 (ior:M2 X C1)) -> (subreg:M1 C1)
8880 : (subreg:M1 (xor:M2 X C1)) -> (subreg:M1 (not:M2 X))
8881 :
8882 : if M2 is no smaller than M1 and (subreg:M1 C1) is all-ones.
8883 :
8884 : (subreg:M1 (and:M2 X C2)) -> (subreg:M1 C2)
8885 : (subreg:M1 (ior/xor:M2 X C2)) -> (subreg:M1 X)
8886 :
8887 : if M2 is no smaller than M1 and (subreg:M1 C2) is zero. */
8888 42236611 : if (known_ge (innersize, outersize)
8889 28943570 : && GET_MODE_CLASS (outermode) == GET_MODE_CLASS (innermode)
8890 26618973 : && (GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR)
8891 43909983 : && CONSTANT_P (XEXP (op, 1)))
8892 : {
8893 869451 : rtx op1_subreg = distribute_subreg (XEXP (op, 1));
8894 869451 : if (op1_subreg == CONSTM1_RTX (outermode))
8895 : {
8896 120163 : if (GET_CODE (op) == IOR)
8897 : return op1_subreg;
8898 119929 : rtx op0 = XEXP (op, 0);
8899 119929 : if (GET_CODE (op) == XOR)
8900 909 : op0 = simplify_gen_unary (NOT, innermode, op0, innermode);
8901 119929 : return simplify_gen_subreg (outermode, op0, innermode, byte);
8902 : }
8903 :
8904 749288 : if (op1_subreg == CONST0_RTX (outermode))
8905 12210 : return (GET_CODE (op) == AND
8906 12210 : ? op1_subreg
8907 7200 : : distribute_subreg (XEXP (op, 0)));
8908 : }
8909 :
8910 : return NULL_RTX;
8911 : }
8912 :
8913 : /* Make a SUBREG operation or equivalent if it folds. */
8914 :
8915 : rtx
8916 44960588 : simplify_context::simplify_gen_subreg (machine_mode outermode, rtx op,
8917 : machine_mode innermode,
8918 : poly_uint64 byte)
8919 : {
8920 44960588 : rtx newx;
8921 :
8922 44960588 : newx = simplify_subreg (outermode, op, innermode, byte);
8923 44960588 : if (newx)
8924 : return newx;
8925 :
8926 21545117 : if (GET_CODE (op) == SUBREG
8927 21545117 : || GET_CODE (op) == CONCAT
8928 21513869 : || CONST_SCALAR_INT_P (op)
8929 21513843 : || CONST_DOUBLE_AS_FLOAT_P (op)
8930 21513843 : || CONST_FIXED_P (op)
8931 21513843 : || GET_CODE (op) == CONST_VECTOR)
8932 : return NULL_RTX;
8933 :
8934 21513833 : if (validate_subreg (outermode, innermode, op, byte))
8935 21481227 : return gen_rtx_SUBREG (outermode, op, byte);
8936 :
8937 : return NULL_RTX;
8938 : }
8939 :
8940 : /* Generates a subreg to get the least significant part of EXPR (in mode
8941 : INNER_MODE) to OUTER_MODE. */
8942 :
8943 : rtx
8944 33372771 : simplify_context::lowpart_subreg (machine_mode outer_mode, rtx expr,
8945 : machine_mode inner_mode)
8946 : {
8947 33372771 : return simplify_gen_subreg (outer_mode, expr, inner_mode,
8948 33372771 : subreg_lowpart_offset (outer_mode, inner_mode));
8949 : }
8950 :
8951 : /* Generate RTX to select element at INDEX out of vector OP. */
8952 :
8953 : rtx
8954 675835 : simplify_context::simplify_gen_vec_select (rtx op, unsigned int index)
8955 : {
8956 675835 : gcc_assert (VECTOR_MODE_P (GET_MODE (op)));
8957 :
8958 675835 : scalar_mode imode = GET_MODE_INNER (GET_MODE (op));
8959 :
8960 1351670 : if (known_eq (index * GET_MODE_SIZE (imode),
8961 : subreg_lowpart_offset (imode, GET_MODE (op))))
8962 : {
8963 675685 : rtx res = lowpart_subreg (imode, op, GET_MODE (op));
8964 675685 : if (res)
8965 : return res;
8966 : }
8967 :
8968 671 : rtx tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, GEN_INT (index)));
8969 671 : return gen_rtx_VEC_SELECT (imode, op, tmp);
8970 : }
8971 :
8972 :
8973 : /* Simplify X, an rtx expression.
8974 :
8975 : Return the simplified expression or NULL if no simplifications
8976 : were possible.
8977 :
8978 : This is the preferred entry point into the simplification routines;
8979 : however, we still allow passes to call the more specific routines.
8980 :
8981 : Right now GCC has three (yes, three) major bodies of RTL simplification
8982 : code that need to be unified.
8983 :
8984 : 1. fold_rtx in cse.cc. This code uses various CSE specific
8985 : information to aid in RTL simplification.
8986 :
8987 : 2. simplify_rtx in combine.cc. Similar to fold_rtx, except that
8988 : it uses combine specific information to aid in RTL
8989 : simplification.
8990 :
8991 : 3. The routines in this file.
8992 :
8993 :
8994 : Long term we want to only have one body of simplification code; to
8995 : get to that state I recommend the following steps:
8996 :
8997 : 1. Pour over fold_rtx & simplify_rtx and move any simplifications
8998 : which are not pass dependent state into these routines.
8999 :
9000 : 2. As code is moved by #1, change fold_rtx & simplify_rtx to
9001 : use this routine whenever possible.
9002 :
9003 : 3. Allow for pass dependent state to be provided to these
9004 : routines and add simplifications based on the pass dependent
9005 : state. Remove code from cse.cc & combine.cc that becomes
9006 : redundant/dead.
9007 :
9008 : It will take time, but ultimately the compiler will be easier to
9009 : maintain and improve. It's totally silly that when we add a
9010 : simplification that it needs to be added to 4 places (3 for RTL
9011 : simplification and 1 for tree simplification. */
9012 :
9013 : rtx
9014 47226308 : simplify_rtx (const_rtx x)
9015 : {
9016 47226308 : const enum rtx_code code = GET_CODE (x);
9017 47226308 : const machine_mode mode = GET_MODE (x);
9018 :
9019 47226308 : switch (GET_RTX_CLASS (code))
9020 : {
9021 763048 : case RTX_UNARY:
9022 1526096 : return simplify_unary_operation (code, mode,
9023 763048 : XEXP (x, 0), GET_MODE (XEXP (x, 0)));
9024 27023373 : case RTX_COMM_ARITH:
9025 27023373 : if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
9026 437201 : return simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
9027 :
9028 : /* Fall through. */
9029 :
9030 33082264 : case RTX_BIN_ARITH:
9031 33082264 : return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
9032 :
9033 106017 : case RTX_TERNARY:
9034 106017 : case RTX_BITFIELD_OPS:
9035 106017 : return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
9036 106017 : XEXP (x, 0), XEXP (x, 1),
9037 106017 : XEXP (x, 2));
9038 :
9039 225725 : case RTX_COMPARE:
9040 225725 : case RTX_COMM_COMPARE:
9041 225725 : return simplify_relational_operation (code, mode,
9042 225725 : ((GET_MODE (XEXP (x, 0))
9043 : != VOIDmode)
9044 : ? GET_MODE (XEXP (x, 0))
9045 301 : : GET_MODE (XEXP (x, 1))),
9046 225725 : XEXP (x, 0),
9047 451450 : XEXP (x, 1));
9048 :
9049 231100 : case RTX_EXTRA:
9050 231100 : if (code == SUBREG)
9051 2511 : return simplify_subreg (mode, SUBREG_REG (x),
9052 2511 : GET_MODE (SUBREG_REG (x)),
9053 2511 : SUBREG_BYTE (x));
9054 : break;
9055 :
9056 6634761 : case RTX_OBJ:
9057 6634761 : if (code == LO_SUM)
9058 : {
9059 : /* Convert (lo_sum (high FOO) FOO) to FOO. */
9060 0 : if (GET_CODE (XEXP (x, 0)) == HIGH
9061 0 : && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
9062 0 : return XEXP (x, 1);
9063 : }
9064 : break;
9065 :
9066 : default:
9067 : break;
9068 : }
9069 : return NULL;
9070 : }
9071 :
9072 : #if CHECKING_P
9073 :
9074 : namespace selftest {
9075 :
9076 : /* Make a unique pseudo REG of mode MODE for use by selftests. */
9077 :
9078 : static rtx
9079 2672 : make_test_reg (machine_mode mode)
9080 : {
9081 2672 : static int test_reg_num = LAST_VIRTUAL_REGISTER + 1;
9082 :
9083 2672 : return gen_rtx_REG (mode, test_reg_num++);
9084 : }
9085 :
9086 : static void
9087 40 : test_scalar_int_ops (machine_mode mode)
9088 : {
9089 40 : rtx op0 = make_test_reg (mode);
9090 40 : rtx op1 = make_test_reg (mode);
9091 40 : rtx six = GEN_INT (6);
9092 :
9093 40 : rtx neg_op0 = simplify_gen_unary (NEG, mode, op0, mode);
9094 40 : rtx not_op0 = simplify_gen_unary (NOT, mode, op0, mode);
9095 40 : rtx bswap_op0 = simplify_gen_unary (BSWAP, mode, op0, mode);
9096 :
9097 40 : rtx and_op0_op1 = simplify_gen_binary (AND, mode, op0, op1);
9098 40 : rtx ior_op0_op1 = simplify_gen_binary (IOR, mode, op0, op1);
9099 40 : rtx xor_op0_op1 = simplify_gen_binary (XOR, mode, op0, op1);
9100 :
9101 40 : rtx and_op0_6 = simplify_gen_binary (AND, mode, op0, six);
9102 40 : rtx and_op1_6 = simplify_gen_binary (AND, mode, op1, six);
9103 :
9104 : /* Test some binary identities. */
9105 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, op0, const0_rtx));
9106 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, const0_rtx, op0));
9107 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MINUS, mode, op0, const0_rtx));
9108 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, op0, const1_rtx));
9109 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, const1_rtx, op0));
9110 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (DIV, mode, op0, const1_rtx));
9111 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, constm1_rtx));
9112 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, constm1_rtx, op0));
9113 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, const0_rtx));
9114 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, const0_rtx, op0));
9115 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, op0, const0_rtx));
9116 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, const0_rtx, op0));
9117 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFT, mode, op0, const0_rtx));
9118 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATE, mode, op0, const0_rtx));
9119 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFTRT, mode, op0, const0_rtx));
9120 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (LSHIFTRT, mode, op0, const0_rtx));
9121 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATERT, mode, op0, const0_rtx));
9122 :
9123 : /* Test some self-inverse operations. */
9124 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (NEG, mode, neg_op0, mode));
9125 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (NOT, mode, not_op0, mode));
9126 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (BSWAP, mode, bswap_op0, mode));
9127 :
9128 : /* Test some reflexive operations. */
9129 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, op0));
9130 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, op0));
9131 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (SMIN, mode, op0, op0));
9132 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (SMAX, mode, op0, op0));
9133 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (UMIN, mode, op0, op0));
9134 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (UMAX, mode, op0, op0));
9135 :
9136 40 : ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (MINUS, mode, op0, op0));
9137 40 : ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (XOR, mode, op0, op0));
9138 :
9139 : /* Test simplify_distributive_operation. */
9140 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, xor_op0_op1, six),
9141 : simplify_gen_binary (XOR, mode, and_op0_6, and_op1_6));
9142 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, ior_op0_op1, six),
9143 : simplify_gen_binary (IOR, mode, and_op0_6, and_op1_6));
9144 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, and_op0_op1, six),
9145 : simplify_gen_binary (AND, mode, and_op0_6, and_op1_6));
9146 :
9147 : /* Test useless extensions are eliminated. */
9148 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (TRUNCATE, mode, op0, mode));
9149 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (ZERO_EXTEND, mode, op0, mode));
9150 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (SIGN_EXTEND, mode, op0, mode));
9151 40 : ASSERT_RTX_EQ (op0, lowpart_subreg (mode, op0, mode));
9152 40 : }
9153 :
9154 : /* Verify some simplifications of integer extension/truncation.
9155 : Machine mode BMODE is the guaranteed wider than SMODE. */
9156 :
9157 : static void
9158 24 : test_scalar_int_ext_ops (machine_mode bmode, machine_mode smode)
9159 : {
9160 24 : rtx sreg = make_test_reg (smode);
9161 :
9162 : /* Check truncation of extension. */
9163 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9164 : simplify_gen_unary (ZERO_EXTEND, bmode,
9165 : sreg, smode),
9166 : bmode),
9167 : sreg);
9168 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9169 : simplify_gen_unary (SIGN_EXTEND, bmode,
9170 : sreg, smode),
9171 : bmode),
9172 : sreg);
9173 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9174 : lowpart_subreg (bmode, sreg, smode),
9175 : bmode),
9176 : sreg);
9177 :
9178 : /* Test extensions, followed by logic ops, followed by truncations. */
9179 24 : rtx bsubreg = lowpart_subreg (bmode, sreg, smode);
9180 24 : rtx smask = gen_int_mode (GET_MODE_MASK (smode), bmode);
9181 24 : rtx inv_smask = gen_int_mode (~GET_MODE_MASK (smode), bmode);
9182 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9183 : simplify_gen_binary (AND, bmode,
9184 : bsubreg, smask),
9185 : bmode),
9186 : sreg);
9187 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9188 : simplify_gen_binary (AND, bmode,
9189 : bsubreg, inv_smask),
9190 : bmode),
9191 : const0_rtx);
9192 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9193 : simplify_gen_binary (IOR, bmode,
9194 : bsubreg, smask),
9195 : bmode),
9196 : constm1_rtx);
9197 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9198 : simplify_gen_binary (IOR, bmode,
9199 : bsubreg, inv_smask),
9200 : bmode),
9201 : sreg);
9202 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9203 : simplify_gen_binary (XOR, bmode,
9204 : bsubreg, smask),
9205 : bmode),
9206 : lowpart_subreg (smode,
9207 : gen_rtx_NOT (bmode, bsubreg),
9208 : bmode));
9209 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9210 : simplify_gen_binary (XOR, bmode,
9211 : bsubreg, inv_smask),
9212 : bmode),
9213 : sreg);
9214 :
9215 24 : if (known_le (GET_MODE_PRECISION (bmode), BITS_PER_WORD))
9216 : {
9217 24 : rtx breg1 = make_test_reg (bmode);
9218 24 : rtx breg2 = make_test_reg (bmode);
9219 24 : rtx ssubreg1 = lowpart_subreg (smode, breg1, bmode);
9220 24 : rtx ssubreg2 = lowpart_subreg (smode, breg2, bmode);
9221 24 : rtx not_1 = simplify_gen_unary (NOT, smode, ssubreg1, smode);
9222 24 : rtx and_12 = simplify_gen_binary (AND, smode, ssubreg1, ssubreg2);
9223 24 : rtx ior_12 = simplify_gen_binary (IOR, smode, ssubreg1, ssubreg2);
9224 24 : rtx xor_12 = simplify_gen_binary (XOR, smode, ssubreg1, ssubreg2);
9225 24 : rtx and_n12 = simplify_gen_binary (AND, smode, not_1, ssubreg2);
9226 24 : rtx ior_n12 = simplify_gen_binary (IOR, smode, not_1, ssubreg2);
9227 24 : rtx xor_12_c = simplify_gen_binary (XOR, smode, xor_12, const1_rtx);
9228 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, not_1, smode),
9229 : gen_rtx_NOT (bmode, breg1));
9230 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, and_12, smode),
9231 : gen_rtx_AND (bmode, breg1, breg2));
9232 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, ior_12, smode),
9233 : gen_rtx_IOR (bmode, breg1, breg2));
9234 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, xor_12, smode),
9235 : gen_rtx_XOR (bmode, breg1, breg2));
9236 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, and_n12, smode),
9237 : gen_rtx_AND (bmode, gen_rtx_NOT (bmode, breg1), breg2));
9238 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, ior_n12, smode),
9239 : gen_rtx_IOR (bmode, gen_rtx_NOT (bmode, breg1), breg2));
9240 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, xor_12_c, smode),
9241 : gen_rtx_XOR (bmode,
9242 : gen_rtx_XOR (bmode, breg1, breg2),
9243 : const1_rtx));
9244 : }
9245 24 : }
9246 :
9247 : /* Verify more simplifications of integer extension/truncation.
9248 : BMODE is wider than MMODE which is wider than SMODE. */
9249 :
9250 : static void
9251 16 : test_scalar_int_ext_ops2 (machine_mode bmode, machine_mode mmode,
9252 : machine_mode smode)
9253 : {
9254 16 : rtx breg = make_test_reg (bmode);
9255 16 : rtx mreg = make_test_reg (mmode);
9256 16 : rtx sreg = make_test_reg (smode);
9257 :
9258 : /* Check truncate of truncate. */
9259 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9260 : simplify_gen_unary (TRUNCATE, mmode,
9261 : breg, bmode),
9262 : mmode),
9263 : simplify_gen_unary (TRUNCATE, smode, breg, bmode));
9264 :
9265 : /* Check extension of extension. */
9266 16 : ASSERT_RTX_EQ (simplify_gen_unary (ZERO_EXTEND, bmode,
9267 : simplify_gen_unary (ZERO_EXTEND, mmode,
9268 : sreg, smode),
9269 : mmode),
9270 : simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
9271 16 : ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
9272 : simplify_gen_unary (SIGN_EXTEND, mmode,
9273 : sreg, smode),
9274 : mmode),
9275 : simplify_gen_unary (SIGN_EXTEND, bmode, sreg, smode));
9276 16 : ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
9277 : simplify_gen_unary (ZERO_EXTEND, mmode,
9278 : sreg, smode),
9279 : mmode),
9280 : simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
9281 :
9282 : /* Check truncation of extension. */
9283 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9284 : simplify_gen_unary (ZERO_EXTEND, bmode,
9285 : mreg, mmode),
9286 : bmode),
9287 : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
9288 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9289 : simplify_gen_unary (SIGN_EXTEND, bmode,
9290 : mreg, mmode),
9291 : bmode),
9292 : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
9293 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9294 : lowpart_subreg (bmode, mreg, mmode),
9295 : bmode),
9296 : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
9297 16 : }
9298 :
9299 : /* Test comparisons of comparisons, with the inner comparisons being
9300 : between values of mode MODE2 and producing results of mode MODE1,
9301 : and with the outer comparisons producing results of mode MODE0. */
9302 :
9303 : static void
9304 4 : test_comparisons (machine_mode mode0, machine_mode mode1, machine_mode mode2)
9305 : {
9306 4 : rtx reg0 = make_test_reg (mode2);
9307 4 : rtx reg1 = make_test_reg (mode2);
9308 :
9309 4 : static const rtx_code codes[] = {
9310 : EQ, NE, LT, LTU, LE, LEU, GE, GEU, GT, GTU
9311 : };
9312 4 : constexpr auto num_codes = ARRAY_SIZE (codes);
9313 4 : rtx cmps[num_codes];
9314 4 : rtx vals[] = { constm1_rtx, const0_rtx, const1_rtx };
9315 :
9316 44 : for (unsigned int i = 0; i < num_codes; ++i)
9317 40 : cmps[i] = gen_rtx_fmt_ee (codes[i], mode1, reg0, reg1);
9318 :
9319 44 : for (auto code : codes)
9320 440 : for (unsigned int i0 = 0; i0 < num_codes; ++i0)
9321 4400 : for (unsigned int i1 = 0; i1 < num_codes; ++i1)
9322 : {
9323 4000 : rtx cmp_res = simplify_relational_operation (code, mode0, mode1,
9324 : cmps[i0], cmps[i1]);
9325 4000 : if (i0 >= 2 && i1 >= 2 && (i0 ^ i1) & 1)
9326 1280 : ASSERT_TRUE (cmp_res == NULL_RTX);
9327 : else
9328 : {
9329 2720 : ASSERT_TRUE (cmp_res != NULL_RTX
9330 : && (CONSTANT_P (cmp_res)
9331 : || (COMPARISON_P (cmp_res)
9332 : && GET_MODE (cmp_res) == mode0
9333 : && REG_P (XEXP (cmp_res, 0))
9334 : && REG_P (XEXP (cmp_res, 1)))));
9335 10880 : for (rtx reg0_val : vals)
9336 32640 : for (rtx reg1_val : vals)
9337 : {
9338 24480 : rtx val0 = simplify_const_relational_operation
9339 24480 : (codes[i0], mode1, reg0_val, reg1_val);
9340 24480 : rtx val1 = simplify_const_relational_operation
9341 24480 : (codes[i1], mode1, reg0_val, reg1_val);
9342 24480 : rtx val = simplify_const_relational_operation
9343 24480 : (code, mode0, val0, val1);
9344 24480 : rtx folded = cmp_res;
9345 24480 : if (COMPARISON_P (cmp_res))
9346 16704 : folded = simplify_const_relational_operation
9347 16704 : (GET_CODE (cmp_res), mode0,
9348 16704 : XEXP (cmp_res, 0) == reg0 ? reg0_val : reg1_val,
9349 16704 : XEXP (cmp_res, 1) == reg0 ? reg0_val : reg1_val);
9350 24480 : ASSERT_RTX_EQ (val, folded);
9351 : }
9352 : }
9353 : }
9354 4 : }
9355 :
9356 :
9357 : /* Verify some simplifications involving scalar expressions. */
9358 :
9359 : static void
9360 4 : test_scalar_ops ()
9361 : {
9362 500 : for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
9363 : {
9364 496 : machine_mode mode = (machine_mode) i;
9365 496 : if (SCALAR_INT_MODE_P (mode) && mode != BImode)
9366 40 : test_scalar_int_ops (mode);
9367 : }
9368 :
9369 4 : test_scalar_int_ext_ops (HImode, QImode);
9370 4 : test_scalar_int_ext_ops (SImode, QImode);
9371 4 : test_scalar_int_ext_ops (SImode, HImode);
9372 4 : test_scalar_int_ext_ops (DImode, QImode);
9373 4 : test_scalar_int_ext_ops (DImode, HImode);
9374 4 : test_scalar_int_ext_ops (DImode, SImode);
9375 :
9376 4 : test_scalar_int_ext_ops2 (SImode, HImode, QImode);
9377 4 : test_scalar_int_ext_ops2 (DImode, HImode, QImode);
9378 4 : test_scalar_int_ext_ops2 (DImode, SImode, QImode);
9379 4 : test_scalar_int_ext_ops2 (DImode, SImode, HImode);
9380 :
9381 4 : test_comparisons (QImode, HImode, SImode);
9382 4 : }
9383 :
9384 : /* Test vector simplifications involving VEC_DUPLICATE in which the
9385 : operands and result have vector mode MODE. SCALAR_REG is a pseudo
9386 : register that holds one element of MODE. */
9387 :
9388 : static void
9389 224 : test_vector_ops_duplicate (machine_mode mode, rtx scalar_reg)
9390 : {
9391 224 : scalar_mode inner_mode = GET_MODE_INNER (mode);
9392 224 : rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
9393 448 : poly_uint64 nunits = GET_MODE_NUNITS (mode);
9394 224 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
9395 : {
9396 : /* Test some simple unary cases with VEC_DUPLICATE arguments. */
9397 124 : rtx not_scalar_reg = gen_rtx_NOT (inner_mode, scalar_reg);
9398 124 : rtx duplicate_not = gen_rtx_VEC_DUPLICATE (mode, not_scalar_reg);
9399 124 : ASSERT_RTX_EQ (duplicate,
9400 : simplify_unary_operation (NOT, mode,
9401 : duplicate_not, mode));
9402 :
9403 124 : rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
9404 124 : rtx duplicate_neg = gen_rtx_VEC_DUPLICATE (mode, neg_scalar_reg);
9405 124 : ASSERT_RTX_EQ (duplicate,
9406 : simplify_unary_operation (NEG, mode,
9407 : duplicate_neg, mode));
9408 :
9409 : /* Test some simple binary cases with VEC_DUPLICATE arguments. */
9410 124 : ASSERT_RTX_EQ (duplicate,
9411 : simplify_binary_operation (PLUS, mode, duplicate,
9412 : CONST0_RTX (mode)));
9413 :
9414 124 : ASSERT_RTX_EQ (duplicate,
9415 : simplify_binary_operation (MINUS, mode, duplicate,
9416 : CONST0_RTX (mode)));
9417 :
9418 124 : ASSERT_RTX_PTR_EQ (CONST0_RTX (mode),
9419 : simplify_binary_operation (MINUS, mode, duplicate,
9420 : duplicate));
9421 : }
9422 :
9423 : /* Test a scalar VEC_SELECT of a VEC_DUPLICATE. */
9424 224 : rtx zero_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const0_rtx));
9425 224 : ASSERT_RTX_PTR_EQ (scalar_reg,
9426 : simplify_binary_operation (VEC_SELECT, inner_mode,
9427 : duplicate, zero_par));
9428 :
9429 224 : unsigned HOST_WIDE_INT const_nunits;
9430 224 : if (nunits.is_constant (&const_nunits))
9431 : {
9432 : /* And again with the final element. */
9433 224 : rtx last_index = gen_int_mode (const_nunits - 1, word_mode);
9434 224 : rtx last_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, last_index));
9435 224 : ASSERT_RTX_PTR_EQ (scalar_reg,
9436 : simplify_binary_operation (VEC_SELECT, inner_mode,
9437 : duplicate, last_par));
9438 :
9439 : /* Test a scalar subreg of a VEC_MERGE of a VEC_DUPLICATE. */
9440 : /* Skip this test for vectors of booleans, because offset is in bytes,
9441 : while vec_merge indices are in elements (usually bits). */
9442 224 : if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
9443 : {
9444 224 : rtx vector_reg = make_test_reg (mode);
9445 3508 : for (unsigned HOST_WIDE_INT i = 0; i < const_nunits; i++)
9446 : {
9447 3288 : if (i >= HOST_BITS_PER_WIDE_INT)
9448 : break;
9449 3284 : rtx mask = GEN_INT ((HOST_WIDE_INT_1U << i) | (i + 1));
9450 3284 : rtx vm = gen_rtx_VEC_MERGE (mode, duplicate, vector_reg, mask);
9451 6568 : poly_uint64 offset = i * GET_MODE_SIZE (inner_mode);
9452 :
9453 3284 : ASSERT_RTX_EQ (scalar_reg,
9454 : simplify_gen_subreg (inner_mode, vm,
9455 : mode, offset));
9456 : }
9457 : }
9458 : }
9459 :
9460 : /* Test a scalar subreg of a VEC_DUPLICATE. */
9461 224 : poly_uint64 offset = subreg_lowpart_offset (inner_mode, mode);
9462 224 : ASSERT_RTX_EQ (scalar_reg,
9463 : simplify_gen_subreg (inner_mode, duplicate,
9464 : mode, offset));
9465 :
9466 224 : machine_mode narrower_mode;
9467 224 : if (maybe_ne (nunits, 2U)
9468 184 : && multiple_p (nunits, 2)
9469 396 : && mode_for_vector (inner_mode, 2).exists (&narrower_mode)
9470 396 : && VECTOR_MODE_P (narrower_mode))
9471 : {
9472 : /* Test VEC_DUPLICATE of a vector. */
9473 172 : rtx_vector_builder nbuilder (narrower_mode, 2, 1);
9474 172 : nbuilder.quick_push (const0_rtx);
9475 172 : nbuilder.quick_push (const1_rtx);
9476 172 : rtx_vector_builder builder (mode, 2, 1);
9477 172 : builder.quick_push (const0_rtx);
9478 172 : builder.quick_push (const1_rtx);
9479 172 : ASSERT_RTX_EQ (builder.build (),
9480 : simplify_unary_operation (VEC_DUPLICATE, mode,
9481 : nbuilder.build (),
9482 : narrower_mode));
9483 :
9484 : /* Test VEC_SELECT of a vector. */
9485 172 : rtx vec_par
9486 172 : = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, const1_rtx, const0_rtx));
9487 172 : rtx narrower_duplicate
9488 172 : = gen_rtx_VEC_DUPLICATE (narrower_mode, scalar_reg);
9489 172 : ASSERT_RTX_EQ (narrower_duplicate,
9490 : simplify_binary_operation (VEC_SELECT, narrower_mode,
9491 : duplicate, vec_par));
9492 :
9493 : /* Test a vector subreg of a VEC_DUPLICATE. */
9494 172 : poly_uint64 offset = subreg_lowpart_offset (narrower_mode, mode);
9495 172 : ASSERT_RTX_EQ (narrower_duplicate,
9496 : simplify_gen_subreg (narrower_mode, duplicate,
9497 : mode, offset));
9498 172 : }
9499 224 : }
9500 :
9501 : /* Test vector simplifications involving VEC_SERIES in which the
9502 : operands and result have vector mode MODE. SCALAR_REG is a pseudo
9503 : register that holds one element of MODE. */
9504 :
9505 : static void
9506 92 : test_vector_ops_series (machine_mode mode, rtx scalar_reg)
9507 : {
9508 : /* Test unary cases with VEC_SERIES arguments. */
9509 92 : scalar_mode inner_mode = GET_MODE_INNER (mode);
9510 92 : rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
9511 92 : rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
9512 92 : rtx series_0_r = gen_rtx_VEC_SERIES (mode, const0_rtx, scalar_reg);
9513 92 : rtx series_0_nr = gen_rtx_VEC_SERIES (mode, const0_rtx, neg_scalar_reg);
9514 92 : rtx series_nr_1 = gen_rtx_VEC_SERIES (mode, neg_scalar_reg, const1_rtx);
9515 92 : rtx series_r_m1 = gen_rtx_VEC_SERIES (mode, scalar_reg, constm1_rtx);
9516 92 : rtx series_r_r = gen_rtx_VEC_SERIES (mode, scalar_reg, scalar_reg);
9517 92 : rtx series_nr_nr = gen_rtx_VEC_SERIES (mode, neg_scalar_reg,
9518 : neg_scalar_reg);
9519 92 : ASSERT_RTX_EQ (series_0_r,
9520 : simplify_unary_operation (NEG, mode, series_0_nr, mode));
9521 92 : ASSERT_RTX_EQ (series_r_m1,
9522 : simplify_unary_operation (NEG, mode, series_nr_1, mode));
9523 92 : ASSERT_RTX_EQ (series_r_r,
9524 : simplify_unary_operation (NEG, mode, series_nr_nr, mode));
9525 :
9526 : /* Test that a VEC_SERIES with a zero step is simplified away. */
9527 92 : ASSERT_RTX_EQ (duplicate,
9528 : simplify_binary_operation (VEC_SERIES, mode,
9529 : scalar_reg, const0_rtx));
9530 :
9531 : /* Test PLUS and MINUS with VEC_SERIES. */
9532 92 : rtx series_0_1 = gen_const_vec_series (mode, const0_rtx, const1_rtx);
9533 92 : rtx series_0_m1 = gen_const_vec_series (mode, const0_rtx, constm1_rtx);
9534 92 : rtx series_r_1 = gen_rtx_VEC_SERIES (mode, scalar_reg, const1_rtx);
9535 92 : ASSERT_RTX_EQ (series_r_r,
9536 : simplify_binary_operation (PLUS, mode, series_0_r,
9537 : duplicate));
9538 92 : ASSERT_RTX_EQ (series_r_1,
9539 : simplify_binary_operation (PLUS, mode, duplicate,
9540 : series_0_1));
9541 92 : ASSERT_RTX_EQ (series_r_m1,
9542 : simplify_binary_operation (PLUS, mode, duplicate,
9543 : series_0_m1));
9544 92 : ASSERT_RTX_EQ (series_0_r,
9545 : simplify_binary_operation (MINUS, mode, series_r_r,
9546 : duplicate));
9547 92 : ASSERT_RTX_EQ (series_r_m1,
9548 : simplify_binary_operation (MINUS, mode, duplicate,
9549 : series_0_1));
9550 92 : ASSERT_RTX_EQ (series_r_1,
9551 : simplify_binary_operation (MINUS, mode, duplicate,
9552 : series_0_m1));
9553 92 : ASSERT_RTX_EQ (series_0_m1,
9554 : simplify_binary_operation (VEC_SERIES, mode, const0_rtx,
9555 : constm1_rtx));
9556 :
9557 : /* Test NEG on constant vector series. */
9558 92 : ASSERT_RTX_EQ (series_0_m1,
9559 : simplify_unary_operation (NEG, mode, series_0_1, mode));
9560 92 : ASSERT_RTX_EQ (series_0_1,
9561 : simplify_unary_operation (NEG, mode, series_0_m1, mode));
9562 :
9563 : /* Test PLUS and MINUS on constant vector series. */
9564 92 : rtx scalar2 = gen_int_mode (2, inner_mode);
9565 92 : rtx scalar3 = gen_int_mode (3, inner_mode);
9566 92 : rtx series_1_1 = gen_const_vec_series (mode, const1_rtx, const1_rtx);
9567 92 : rtx series_0_2 = gen_const_vec_series (mode, const0_rtx, scalar2);
9568 92 : rtx series_1_3 = gen_const_vec_series (mode, const1_rtx, scalar3);
9569 92 : ASSERT_RTX_EQ (series_1_1,
9570 : simplify_binary_operation (PLUS, mode, series_0_1,
9571 : CONST1_RTX (mode)));
9572 92 : ASSERT_RTX_EQ (series_0_m1,
9573 : simplify_binary_operation (PLUS, mode, CONST0_RTX (mode),
9574 : series_0_m1));
9575 92 : ASSERT_RTX_EQ (series_1_3,
9576 : simplify_binary_operation (PLUS, mode, series_1_1,
9577 : series_0_2));
9578 92 : ASSERT_RTX_EQ (series_0_1,
9579 : simplify_binary_operation (MINUS, mode, series_1_1,
9580 : CONST1_RTX (mode)));
9581 92 : ASSERT_RTX_EQ (series_1_1,
9582 : simplify_binary_operation (MINUS, mode, CONST1_RTX (mode),
9583 : series_0_m1));
9584 92 : ASSERT_RTX_EQ (series_1_1,
9585 : simplify_binary_operation (MINUS, mode, series_1_3,
9586 : series_0_2));
9587 :
9588 : /* Test MULT between constant vectors. */
9589 92 : rtx vec2 = gen_const_vec_duplicate (mode, scalar2);
9590 92 : rtx vec3 = gen_const_vec_duplicate (mode, scalar3);
9591 92 : rtx scalar9 = gen_int_mode (9, inner_mode);
9592 92 : rtx series_3_9 = gen_const_vec_series (mode, scalar3, scalar9);
9593 92 : ASSERT_RTX_EQ (series_0_2,
9594 : simplify_binary_operation (MULT, mode, series_0_1, vec2));
9595 92 : ASSERT_RTX_EQ (series_3_9,
9596 : simplify_binary_operation (MULT, mode, vec3, series_1_3));
9597 92 : if (!GET_MODE_NUNITS (mode).is_constant ())
9598 : ASSERT_FALSE (simplify_binary_operation (MULT, mode, series_0_1,
9599 : series_0_1));
9600 :
9601 : /* Test ASHIFT between constant vectors. */
9602 92 : ASSERT_RTX_EQ (series_0_2,
9603 : simplify_binary_operation (ASHIFT, mode, series_0_1,
9604 : CONST1_RTX (mode)));
9605 92 : if (!GET_MODE_NUNITS (mode).is_constant ())
9606 : ASSERT_FALSE (simplify_binary_operation (ASHIFT, mode, CONST1_RTX (mode),
9607 : series_0_1));
9608 92 : }
9609 :
9610 : static rtx
9611 3136 : simplify_merge_mask (rtx x, rtx mask, int op)
9612 : {
9613 0 : return simplify_context ().simplify_merge_mask (x, mask, op);
9614 : }
9615 :
9616 : /* Verify simplify_merge_mask works correctly. */
9617 :
9618 : static void
9619 224 : test_vec_merge (machine_mode mode)
9620 : {
9621 224 : rtx op0 = make_test_reg (mode);
9622 224 : rtx op1 = make_test_reg (mode);
9623 224 : rtx op2 = make_test_reg (mode);
9624 224 : rtx op3 = make_test_reg (mode);
9625 224 : rtx op4 = make_test_reg (mode);
9626 224 : rtx op5 = make_test_reg (mode);
9627 224 : rtx mask1 = make_test_reg (SImode);
9628 224 : rtx mask2 = make_test_reg (SImode);
9629 224 : rtx vm1 = gen_rtx_VEC_MERGE (mode, op0, op1, mask1);
9630 224 : rtx vm2 = gen_rtx_VEC_MERGE (mode, op2, op3, mask1);
9631 224 : rtx vm3 = gen_rtx_VEC_MERGE (mode, op4, op5, mask1);
9632 :
9633 : /* Simple vec_merge. */
9634 224 : ASSERT_EQ (op0, simplify_merge_mask (vm1, mask1, 0));
9635 224 : ASSERT_EQ (op1, simplify_merge_mask (vm1, mask1, 1));
9636 224 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 0));
9637 224 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 1));
9638 :
9639 : /* Nested vec_merge.
9640 : It's tempting to make this simplify right down to opN, but we don't
9641 : because all the simplify_* functions assume that the operands have
9642 : already been simplified. */
9643 224 : rtx nvm = gen_rtx_VEC_MERGE (mode, vm1, vm2, mask1);
9644 224 : ASSERT_EQ (vm1, simplify_merge_mask (nvm, mask1, 0));
9645 224 : ASSERT_EQ (vm2, simplify_merge_mask (nvm, mask1, 1));
9646 :
9647 : /* Intermediate unary op. */
9648 224 : rtx unop = gen_rtx_NOT (mode, vm1);
9649 224 : ASSERT_RTX_EQ (gen_rtx_NOT (mode, op0),
9650 : simplify_merge_mask (unop, mask1, 0));
9651 224 : ASSERT_RTX_EQ (gen_rtx_NOT (mode, op1),
9652 : simplify_merge_mask (unop, mask1, 1));
9653 :
9654 : /* Intermediate binary op. */
9655 224 : rtx binop = gen_rtx_PLUS (mode, vm1, vm2);
9656 224 : ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op0, op2),
9657 : simplify_merge_mask (binop, mask1, 0));
9658 224 : ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op1, op3),
9659 : simplify_merge_mask (binop, mask1, 1));
9660 :
9661 : /* Intermediate ternary op. */
9662 224 : rtx tenop = gen_rtx_FMA (mode, vm1, vm2, vm3);
9663 224 : ASSERT_RTX_EQ (gen_rtx_FMA (mode, op0, op2, op4),
9664 : simplify_merge_mask (tenop, mask1, 0));
9665 224 : ASSERT_RTX_EQ (gen_rtx_FMA (mode, op1, op3, op5),
9666 : simplify_merge_mask (tenop, mask1, 1));
9667 :
9668 : /* Side effects. */
9669 224 : rtx badop0 = gen_rtx_PRE_INC (mode, op0);
9670 224 : rtx badvm = gen_rtx_VEC_MERGE (mode, badop0, op1, mask1);
9671 224 : ASSERT_EQ (badop0, simplify_merge_mask (badvm, mask1, 0));
9672 224 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (badvm, mask1, 1));
9673 :
9674 : /* Called indirectly. */
9675 224 : ASSERT_RTX_EQ (gen_rtx_VEC_MERGE (mode, op0, op3, mask1),
9676 : simplify_rtx (nvm));
9677 224 : }
9678 :
9679 : /* Test that vector rotate formation works at RTL level. Try various
9680 : combinations of (REG << C) [|,^,+] (REG >> (<bitwidth> - C)). */
9681 :
9682 : static void
9683 92 : test_vector_rotate (rtx reg)
9684 : {
9685 92 : machine_mode mode = GET_MODE (reg);
9686 92 : unsigned bitwidth = GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT;
9687 92 : rtx plus_rtx = gen_rtx_PLUS (mode, reg, reg);
9688 92 : rtx lshftrt_amnt = GEN_INT (bitwidth - 1);
9689 92 : lshftrt_amnt = gen_const_vec_duplicate (mode, lshftrt_amnt);
9690 92 : rtx lshiftrt_rtx = gen_rtx_LSHIFTRT (mode, reg, lshftrt_amnt);
9691 92 : rtx rotate_rtx = gen_rtx_ROTATE (mode, reg, CONST1_RTX (mode));
9692 : /* Test explicitly the case where ASHIFT (x, 1) is a PLUS (x, x). */
9693 92 : ASSERT_RTX_EQ (rotate_rtx,
9694 : simplify_rtx (gen_rtx_IOR (mode, plus_rtx, lshiftrt_rtx)));
9695 92 : ASSERT_RTX_EQ (rotate_rtx,
9696 : simplify_rtx (gen_rtx_XOR (mode, plus_rtx, lshiftrt_rtx)));
9697 92 : ASSERT_RTX_EQ (rotate_rtx,
9698 : simplify_rtx (gen_rtx_PLUS (mode, plus_rtx, lshiftrt_rtx)));
9699 :
9700 : /* Don't go through every possible rotate amount to save execution time.
9701 : Multiple of BITS_PER_UNIT amounts could conceivably be simplified to
9702 : other bswap operations sometimes. Go through just the odd amounts. */
9703 1380 : for (unsigned i = 3; i < bitwidth - 2; i += 2)
9704 : {
9705 1288 : rtx rot_amnt = gen_const_vec_duplicate (mode, GEN_INT (i));
9706 1288 : rtx ashift_rtx = gen_rtx_ASHIFT (mode, reg, rot_amnt);
9707 1288 : lshftrt_amnt = gen_const_vec_duplicate (mode, GEN_INT (bitwidth - i));
9708 1288 : lshiftrt_rtx = gen_rtx_LSHIFTRT (mode, reg, lshftrt_amnt);
9709 1288 : rotate_rtx = gen_rtx_ROTATE (mode, reg, rot_amnt);
9710 1288 : ASSERT_RTX_EQ (rotate_rtx,
9711 : simplify_rtx (gen_rtx_IOR (mode, ashift_rtx, lshiftrt_rtx)));
9712 1288 : ASSERT_RTX_EQ (rotate_rtx,
9713 : simplify_rtx (gen_rtx_XOR (mode, ashift_rtx, lshiftrt_rtx)));
9714 1288 : ASSERT_RTX_EQ (rotate_rtx,
9715 : simplify_rtx (gen_rtx_PLUS (mode, ashift_rtx, lshiftrt_rtx)));
9716 : }
9717 92 : }
9718 :
9719 : /* Test subregs of integer vector constant X, trying elements in
9720 : the range [ELT_BIAS, ELT_BIAS + constant_lower_bound (NELTS)),
9721 : where NELTS is the number of elements in X. Subregs involving
9722 : elements [ELT_BIAS, ELT_BIAS + FIRST_VALID) are expected to fail. */
9723 :
9724 : static void
9725 276 : test_vector_subregs_modes (rtx x, poly_uint64 elt_bias = 0,
9726 : unsigned int first_valid = 0)
9727 : {
9728 276 : machine_mode inner_mode = GET_MODE (x);
9729 276 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9730 :
9731 34500 : for (unsigned int modei = 0; modei < NUM_MACHINE_MODES; ++modei)
9732 : {
9733 34224 : machine_mode outer_mode = (machine_mode) modei;
9734 34224 : if (!VECTOR_MODE_P (outer_mode))
9735 18768 : continue;
9736 :
9737 15456 : unsigned int outer_nunits;
9738 15456 : if (GET_MODE_INNER (outer_mode) == int_mode
9739 1932 : && GET_MODE_NUNITS (outer_mode).is_constant (&outer_nunits)
9740 20412 : && multiple_p (GET_MODE_NUNITS (inner_mode), outer_nunits))
9741 : {
9742 : /* Test subregs in which the outer mode is a smaller,
9743 : constant-sized vector of the same element type. */
9744 1092 : unsigned int limit
9745 1092 : = constant_lower_bound (GET_MODE_NUNITS (inner_mode));
9746 8028 : for (unsigned int elt = 0; elt < limit; elt += outer_nunits)
9747 : {
9748 6936 : rtx expected = NULL_RTX;
9749 6936 : if (elt >= first_valid)
9750 : {
9751 6936 : rtx_vector_builder builder (outer_mode, outer_nunits, 1);
9752 39768 : for (unsigned int i = 0; i < outer_nunits; ++i)
9753 32832 : builder.quick_push (CONST_VECTOR_ELT (x, elt + i));
9754 6936 : expected = builder.build ();
9755 6936 : }
9756 13872 : poly_uint64 byte = (elt_bias + elt) * GET_MODE_SIZE (int_mode);
9757 6936 : ASSERT_RTX_EQ (expected,
9758 : simplify_subreg (outer_mode, x,
9759 : inner_mode, byte));
9760 : }
9761 : }
9762 28728 : else if (known_eq (GET_MODE_SIZE (outer_mode),
9763 : GET_MODE_SIZE (inner_mode))
9764 2040 : && known_eq (elt_bias, 0U)
9765 2040 : && (GET_MODE_CLASS (outer_mode) != MODE_VECTOR_BOOL
9766 0 : || known_eq (GET_MODE_BITSIZE (outer_mode),
9767 : GET_MODE_NUNITS (outer_mode)))
9768 2040 : && (!FLOAT_MODE_P (outer_mode)
9769 15876 : || (FLOAT_MODE_FORMAT (outer_mode)->ieee_bits
9770 1104 : == GET_MODE_UNIT_PRECISION (outer_mode)))
9771 14364 : && (GET_MODE_SIZE (inner_mode).is_constant ()
9772 : || !CONST_VECTOR_STEPPED_P (x)))
9773 : {
9774 : /* Try converting to OUTER_MODE and back. */
9775 1800 : rtx outer_x = simplify_subreg (outer_mode, x, inner_mode, 0);
9776 1800 : ASSERT_TRUE (outer_x != NULL_RTX);
9777 1800 : ASSERT_RTX_EQ (x, simplify_subreg (inner_mode, outer_x,
9778 : outer_mode, 0));
9779 : }
9780 : }
9781 :
9782 276 : if (BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
9783 : {
9784 : /* Test each byte in the element range. */
9785 276 : unsigned int limit
9786 276 : = constant_lower_bound (GET_MODE_SIZE (inner_mode));
9787 14604 : for (unsigned int i = 0; i < limit; ++i)
9788 : {
9789 14328 : unsigned int elt = i / GET_MODE_SIZE (int_mode);
9790 14328 : rtx expected = NULL_RTX;
9791 14328 : if (elt >= first_valid)
9792 : {
9793 14328 : unsigned int byte_shift = i % GET_MODE_SIZE (int_mode);
9794 14328 : if (BYTES_BIG_ENDIAN)
9795 : byte_shift = GET_MODE_SIZE (int_mode) - byte_shift - 1;
9796 14328 : rtx_mode_t vec_elt (CONST_VECTOR_ELT (x, elt), int_mode);
9797 14328 : wide_int shifted_elt
9798 14328 : = wi::lrshift (vec_elt, byte_shift * BITS_PER_UNIT);
9799 14328 : expected = immed_wide_int_const (shifted_elt, QImode);
9800 14328 : }
9801 28656 : poly_uint64 byte = elt_bias * GET_MODE_SIZE (int_mode) + i;
9802 14328 : ASSERT_RTX_EQ (expected,
9803 : simplify_subreg (QImode, x, inner_mode, byte));
9804 : }
9805 : }
9806 276 : }
9807 :
9808 : /* Test constant subregs of integer vector mode INNER_MODE, using 1
9809 : element per pattern. */
9810 :
9811 : static void
9812 92 : test_vector_subregs_repeating (machine_mode inner_mode)
9813 : {
9814 184 : poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
9815 92 : unsigned int min_nunits = constant_lower_bound (nunits);
9816 92 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9817 92 : unsigned int count = gcd (min_nunits, 8);
9818 :
9819 92 : rtx_vector_builder builder (inner_mode, count, 1);
9820 684 : for (unsigned int i = 0; i < count; ++i)
9821 592 : builder.quick_push (gen_int_mode (8 - i, int_mode));
9822 92 : rtx x = builder.build ();
9823 :
9824 92 : test_vector_subregs_modes (x);
9825 92 : if (!nunits.is_constant ())
9826 : test_vector_subregs_modes (x, nunits - min_nunits);
9827 92 : }
9828 :
9829 : /* Test constant subregs of integer vector mode INNER_MODE, using 2
9830 : elements per pattern. */
9831 :
9832 : static void
9833 92 : test_vector_subregs_fore_back (machine_mode inner_mode)
9834 : {
9835 184 : poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
9836 92 : unsigned int min_nunits = constant_lower_bound (nunits);
9837 92 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9838 92 : unsigned int count = gcd (min_nunits, 4);
9839 :
9840 92 : rtx_vector_builder builder (inner_mode, count, 2);
9841 444 : for (unsigned int i = 0; i < count; ++i)
9842 352 : builder.quick_push (gen_int_mode (i, int_mode));
9843 444 : for (unsigned int i = 0; i < count; ++i)
9844 352 : builder.quick_push (gen_int_mode (-1 - (int) i, int_mode));
9845 92 : rtx x = builder.build ();
9846 :
9847 92 : test_vector_subregs_modes (x);
9848 92 : if (!nunits.is_constant ())
9849 : test_vector_subregs_modes (x, nunits - min_nunits, count);
9850 92 : }
9851 :
9852 : /* Test constant subregs of integer vector mode INNER_MODE, using 3
9853 : elements per pattern. */
9854 :
9855 : static void
9856 92 : test_vector_subregs_stepped (machine_mode inner_mode)
9857 : {
9858 : /* Build { 0, 1, 2, 3, ... }. */
9859 92 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9860 92 : rtx_vector_builder builder (inner_mode, 1, 3);
9861 368 : for (unsigned int i = 0; i < 3; ++i)
9862 276 : builder.quick_push (gen_int_mode (i, int_mode));
9863 92 : rtx x = builder.build ();
9864 :
9865 92 : test_vector_subregs_modes (x);
9866 92 : }
9867 :
9868 : /* Test constant subregs of integer vector mode INNER_MODE. */
9869 :
9870 : static void
9871 92 : test_vector_subregs (machine_mode inner_mode)
9872 : {
9873 92 : test_vector_subregs_repeating (inner_mode);
9874 92 : test_vector_subregs_fore_back (inner_mode);
9875 92 : test_vector_subregs_stepped (inner_mode);
9876 92 : }
9877 :
9878 : /* Verify some simplifications involving vectors. */
9879 :
9880 : static void
9881 4 : test_vector_ops ()
9882 : {
9883 500 : for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
9884 : {
9885 496 : machine_mode mode = (machine_mode) i;
9886 496 : if (VECTOR_MODE_P (mode))
9887 : {
9888 448 : rtx scalar_reg = make_test_reg (GET_MODE_INNER (mode));
9889 224 : test_vector_ops_duplicate (mode, scalar_reg);
9890 224 : rtx vector_reg = make_test_reg (mode);
9891 224 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
9892 348 : && maybe_gt (GET_MODE_NUNITS (mode), 2))
9893 : {
9894 92 : test_vector_ops_series (mode, scalar_reg);
9895 92 : test_vector_subregs (mode);
9896 92 : test_vector_rotate (vector_reg);
9897 : }
9898 224 : test_vec_merge (mode);
9899 : }
9900 : }
9901 4 : }
9902 :
9903 : template<unsigned int N>
9904 : struct simplify_const_poly_int_tests
9905 : {
9906 : static void run ();
9907 : };
9908 :
9909 : template<>
9910 : struct simplify_const_poly_int_tests<1>
9911 : {
9912 : static void run () {}
9913 : };
9914 :
9915 : /* Test various CONST_POLY_INT properties. */
9916 :
9917 : template<unsigned int N>
9918 : void
9919 : simplify_const_poly_int_tests<N>::run ()
9920 : {
9921 : using poly_int64 = poly_int<N, HOST_WIDE_INT>;
9922 : rtx x1 = gen_int_mode (poly_int64 (1, 1), QImode);
9923 : rtx x2 = gen_int_mode (poly_int64 (-80, 127), QImode);
9924 : rtx x3 = gen_int_mode (poly_int64 (-79, -128), QImode);
9925 : rtx x4 = gen_int_mode (poly_int64 (5, 4), QImode);
9926 : rtx x5 = gen_int_mode (poly_int64 (30, 24), QImode);
9927 : rtx x6 = gen_int_mode (poly_int64 (20, 16), QImode);
9928 : rtx x7 = gen_int_mode (poly_int64 (7, 4), QImode);
9929 : rtx x8 = gen_int_mode (poly_int64 (30, 24), HImode);
9930 : rtx x9 = gen_int_mode (poly_int64 (-30, -24), HImode);
9931 : rtx x10 = gen_int_mode (poly_int64 (-31, -24), HImode);
9932 : rtx two = GEN_INT (2);
9933 : rtx six = GEN_INT (6);
9934 : poly_uint64 offset = subreg_lowpart_offset (QImode, HImode);
9935 :
9936 : /* These tests only try limited operation combinations. Fuller arithmetic
9937 : testing is done directly on poly_ints. */
9938 : ASSERT_EQ (simplify_unary_operation (NEG, HImode, x8, HImode), x9);
9939 : ASSERT_EQ (simplify_unary_operation (NOT, HImode, x8, HImode), x10);
9940 : ASSERT_EQ (simplify_unary_operation (TRUNCATE, QImode, x8, HImode), x5);
9941 : ASSERT_EQ (simplify_binary_operation (PLUS, QImode, x1, x2), x3);
9942 : ASSERT_EQ (simplify_binary_operation (MINUS, QImode, x3, x1), x2);
9943 : ASSERT_EQ (simplify_binary_operation (MULT, QImode, x4, six), x5);
9944 : ASSERT_EQ (simplify_binary_operation (MULT, QImode, six, x4), x5);
9945 : ASSERT_EQ (simplify_binary_operation (ASHIFT, QImode, x4, two), x6);
9946 : ASSERT_EQ (simplify_binary_operation (IOR, QImode, x4, two), x7);
9947 : ASSERT_EQ (simplify_subreg (HImode, x5, QImode, 0), x8);
9948 : ASSERT_EQ (simplify_subreg (QImode, x8, HImode, offset), x5);
9949 : }
9950 :
9951 : /* Run all of the selftests within this file. */
9952 :
9953 : void
9954 4 : simplify_rtx_cc_tests ()
9955 : {
9956 4 : test_scalar_ops ();
9957 4 : test_vector_ops ();
9958 4 : simplify_const_poly_int_tests<NUM_POLY_INT_COEFFS>::run ();
9959 4 : }
9960 :
9961 : } // namespace selftest
9962 :
9963 : #endif /* CHECKING_P */
|