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 9279549 : neg_poly_int_rtx (machine_mode mode, const_rtx i)
56 : {
57 9279549 : 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 6298465 : mode_signbit_p (machine_mode mode, const_rtx x)
65 : {
66 6298465 : unsigned HOST_WIDE_INT val;
67 6298465 : unsigned int width;
68 6298465 : scalar_int_mode int_mode;
69 :
70 6298465 : if (!is_int_mode (mode, &int_mode))
71 : return false;
72 :
73 6298457 : width = GET_MODE_PRECISION (int_mode);
74 6298457 : if (width == 0)
75 : return false;
76 :
77 6298457 : if (width <= HOST_BITS_PER_WIDE_INT
78 6296924 : && CONST_INT_P (x))
79 6151417 : val = INTVAL (x);
80 : #if TARGET_SUPPORTS_WIDE_INT
81 147040 : 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 6151417 : if (width < HOST_BITS_PER_WIDE_INT)
109 5573363 : val &= (HOST_WIDE_INT_1U << width) - 1;
110 6151840 : 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 3840615 : val_signbit_p (machine_mode mode, unsigned HOST_WIDE_INT val)
119 : {
120 3840615 : unsigned int width;
121 3840615 : scalar_int_mode int_mode;
122 :
123 3840615 : if (!is_int_mode (mode, &int_mode))
124 : return false;
125 :
126 3840579 : width = GET_MODE_PRECISION (int_mode);
127 3840579 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
128 : return false;
129 :
130 3835661 : val &= GET_MODE_MASK (int_mode);
131 3835661 : 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 2697946 : val_signbit_known_set_p (machine_mode mode, unsigned HOST_WIDE_INT val)
138 : {
139 2697946 : unsigned int width;
140 :
141 2697946 : scalar_int_mode int_mode;
142 2697946 : if (!is_int_mode (mode, &int_mode))
143 : return false;
144 :
145 2635996 : width = GET_MODE_PRECISION (int_mode);
146 2635996 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
147 : return false;
148 :
149 2635996 : val &= HOST_WIDE_INT_1U << (width - 1);
150 2635996 : 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 7898286 : val_signbit_known_clear_p (machine_mode mode, unsigned HOST_WIDE_INT val)
157 : {
158 7898286 : unsigned int width;
159 :
160 7898286 : scalar_int_mode int_mode;
161 7898286 : if (!is_int_mode (mode, &int_mode))
162 : return false;
163 :
164 7535067 : width = GET_MODE_PRECISION (int_mode);
165 7535067 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
166 : return false;
167 :
168 7424474 : val &= HOST_WIDE_INT_1U << (width - 1);
169 7424474 : 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 123490602 : simplify_context::simplify_gen_binary (rtx_code code, machine_mode mode,
177 : rtx op0, rtx op1)
178 : {
179 123490602 : rtx tem;
180 :
181 : /* If this simplifies, do it. */
182 123490602 : tem = simplify_binary_operation (code, mode, op0, op1);
183 123490602 : if (tem)
184 : return tem;
185 :
186 : /* Put complex operands first and constants second if commutative. */
187 78641212 : if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
188 78641212 : && swap_commutative_operands_p (op0, op1))
189 : std::swap (op0, op1);
190 :
191 78641212 : 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 2826279200 : avoid_constant_pool_reference (rtx x)
198 : {
199 2826279200 : rtx c, tmp, addr;
200 2826279200 : machine_mode cmode;
201 2826279200 : poly_int64 offset = 0;
202 :
203 2826279200 : switch (GET_CODE (x))
204 : {
205 271286103 : case MEM:
206 271286103 : break;
207 :
208 915913 : case FLOAT_EXTEND:
209 : /* Handle float extensions of constant pool references. */
210 915913 : tmp = XEXP (x, 0);
211 915913 : c = avoid_constant_pool_reference (tmp);
212 915913 : if (c != tmp && CONST_DOUBLE_AS_FLOAT_P (c))
213 125077 : return const_double_from_real_value (*CONST_DOUBLE_REAL_VALUE (c),
214 125077 : GET_MODE (x));
215 : return x;
216 :
217 : default:
218 : return x;
219 : }
220 :
221 271286103 : if (GET_MODE (x) == BLKmode)
222 : return x;
223 :
224 267186314 : addr = XEXP (x, 0);
225 :
226 : /* Call target hook to avoid the effects of -fpic etc.... */
227 267186314 : addr = targetm.delegitimize_address (addr);
228 :
229 : /* Split the address into a base and integer offset. */
230 267186314 : addr = strip_offset (addr, &offset);
231 :
232 267186314 : 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 267186314 : if (GET_CODE (addr) == SYMBOL_REF
238 267186314 : && CONSTANT_POOL_ADDRESS_P (addr))
239 : {
240 5454155 : c = get_pool_constant (addr);
241 5454155 : 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 5454155 : if (known_eq (offset, 0) && cmode == GET_MODE (x))
247 : return c;
248 45870 : else if (known_in_range_p (offset, 0, GET_MODE_SIZE (cmode)))
249 : {
250 15290 : rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset);
251 15290 : if (tem && CONSTANT_P (tem))
252 15173 : 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 3574865152 : 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 3574865152 : if (MEM_P (x)
269 63177807 : && MEM_EXPR (x)
270 3614132219 : && MEM_OFFSET_KNOWN_P (x))
271 : {
272 36196256 : tree decl = MEM_EXPR (x);
273 36196256 : machine_mode mode = GET_MODE (x);
274 36196256 : poly_int64 offset = 0;
275 :
276 36196256 : switch (TREE_CODE (decl))
277 : {
278 : default:
279 : decl = NULL;
280 : break;
281 :
282 : case VAR_DECL:
283 : break;
284 :
285 10309648 : case ARRAY_REF:
286 10309648 : case ARRAY_RANGE_REF:
287 10309648 : case COMPONENT_REF:
288 10309648 : case BIT_FIELD_REF:
289 10309648 : case REALPART_EXPR:
290 10309648 : case IMAGPART_EXPR:
291 10309648 : case VIEW_CONVERT_EXPR:
292 10309648 : {
293 10309648 : poly_int64 bitsize, bitpos, bytepos, toffset_val = 0;
294 10309648 : tree toffset;
295 10309648 : int unsignedp, reversep, volatilep = 0;
296 :
297 10309648 : decl
298 10309648 : = get_inner_reference (decl, &bitsize, &bitpos, &toffset, &mode,
299 : &unsignedp, &reversep, &volatilep);
300 20619296 : if (maybe_ne (bitsize, GET_MODE_BITSIZE (mode))
301 10602172 : || !multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
302 20178486 : || (toffset && !poly_int_tree_p (toffset, &toffset_val)))
303 : decl = NULL;
304 : else
305 9576314 : offset += bytepos + toffset_val;
306 10309648 : break;
307 : }
308 : }
309 :
310 733334 : if (decl
311 21281339 : && mode == GET_MODE (x)
312 21008727 : && VAR_P (decl)
313 13637213 : && (TREE_STATIC (decl)
314 12403815 : || DECL_THREAD_LOCAL_P (decl))
315 1270358 : && DECL_RTL_SET_P (decl)
316 10846222 : && MEM_P (DECL_RTL (decl)))
317 : {
318 1269908 : rtx newx;
319 :
320 1269908 : offset += MEM_OFFSET (x);
321 :
322 1269908 : newx = DECL_RTL (decl);
323 :
324 1269908 : if (MEM_P (newx))
325 : {
326 1269908 : rtx n = XEXP (newx, 0), o = XEXP (x, 0);
327 1269908 : 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 1269908 : n = strip_offset (n, &n_offset);
336 1269908 : o = strip_offset (o, &o_offset);
337 2511938 : if (!(known_eq (o_offset, n_offset + offset)
338 1242030 : && rtx_equal_p (o, n)))
339 212855 : 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 3574865152 : 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 7245283 : simplify_context::simplify_gen_unary (rtx_code code, machine_mode mode, rtx op,
355 : machine_mode op_mode)
356 : {
357 7245283 : rtx tem;
358 :
359 : /* If this simplifies, use it. */
360 7245283 : if ((tem = simplify_unary_operation (code, mode, op, op_mode)) != 0)
361 : return tem;
362 :
363 2502702 : return gen_rtx_fmt_e (code, mode, op);
364 : }
365 :
366 : /* Likewise for ternary operations. */
367 :
368 : rtx
369 2972109 : 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 2972109 : rtx tem;
374 :
375 : /* If this simplifies, use it. */
376 2972109 : if ((tem = simplify_ternary_operation (code, mode, op0_mode,
377 : op0, op1, op2)) != 0)
378 : return tem;
379 :
380 2718149 : 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 22942341 : simplify_context::simplify_gen_relational (rtx_code code, machine_mode mode,
388 : machine_mode cmp_mode,
389 : rtx op0, rtx op1)
390 : {
391 22942341 : rtx tem;
392 :
393 22942341 : if ((tem = simplify_relational_operation (code, mode, cmp_mode,
394 : op0, op1)) != 0)
395 : return tem;
396 :
397 20239514 : 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 514079731 : simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
407 : rtx (*fn) (rtx, const_rtx, void *), void *data)
408 : {
409 514079731 : enum rtx_code code = GET_CODE (x);
410 514079731 : machine_mode mode = GET_MODE (x);
411 514079731 : machine_mode op_mode;
412 514079731 : const char *fmt;
413 514079731 : rtx op0, op1, op2, newx, op;
414 514079731 : rtvec vec, newvec;
415 514079731 : int i, j;
416 :
417 514079731 : if (UNLIKELY (fn != NULL))
418 : {
419 448720594 : newx = fn (x, old_rtx, data);
420 448720594 : if (newx)
421 : return newx;
422 : }
423 65359137 : else if (rtx_equal_p (x, old_rtx))
424 5737561 : return copy_rtx ((rtx) data);
425 :
426 405802591 : switch (GET_RTX_CLASS (code))
427 : {
428 2083538 : case RTX_UNARY:
429 2083538 : op0 = XEXP (x, 0);
430 2083538 : op_mode = GET_MODE (op0);
431 2083538 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
432 2083538 : if (op0 == XEXP (x, 0))
433 : return x;
434 663609 : return simplify_gen_unary (code, mode, op0, op_mode);
435 :
436 77365228 : case RTX_BIN_ARITH:
437 77365228 : case RTX_COMM_ARITH:
438 77365228 : op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
439 77365228 : op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
440 77365228 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
441 : return x;
442 23907847 : return simplify_gen_binary (code, mode, op0, op1);
443 :
444 10190371 : case RTX_COMPARE:
445 10190371 : case RTX_COMM_COMPARE:
446 10190371 : op0 = XEXP (x, 0);
447 10190371 : op1 = XEXP (x, 1);
448 10190371 : op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
449 10190371 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
450 10190371 : op1 = simplify_replace_fn_rtx (op1, old_rtx, fn, data);
451 10190371 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
452 : return x;
453 2811430 : return simplify_gen_relational (code, mode, op_mode, op0, op1);
454 :
455 6427762 : case RTX_TERNARY:
456 6427762 : case RTX_BITFIELD_OPS:
457 6427762 : op0 = XEXP (x, 0);
458 6427762 : op_mode = GET_MODE (op0);
459 6427762 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
460 6427762 : op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
461 6427762 : op2 = simplify_replace_fn_rtx (XEXP (x, 2), old_rtx, fn, data);
462 6427762 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2))
463 : return x;
464 2203835 : if (op_mode == VOIDmode)
465 2180289 : op_mode = GET_MODE (op0);
466 2203835 : return simplify_gen_ternary (code, mode, op_mode, op0, op1, op2);
467 :
468 92621824 : case RTX_EXTRA:
469 92621824 : if (code == SUBREG)
470 : {
471 621401 : op0 = simplify_replace_fn_rtx (SUBREG_REG (x), old_rtx, fn, data);
472 621401 : if (op0 == SUBREG_REG (x))
473 : return x;
474 135354 : op0 = simplify_gen_subreg (GET_MODE (x), op0,
475 67677 : GET_MODE (SUBREG_REG (x)),
476 67677 : SUBREG_BYTE (x));
477 67677 : return op0 ? op0 : x;
478 : }
479 : break;
480 :
481 64408528 : case RTX_OBJ:
482 64408528 : if (code == MEM)
483 : {
484 10970712 : op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
485 10970712 : if (op0 == XEXP (x, 0))
486 : return x;
487 162457 : return replace_equiv_address_nv (x, op0);
488 : }
489 53437816 : 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 298143579 : newx = x;
515 298143579 : fmt = GET_RTX_FORMAT (code);
516 644123877 : for (i = 0; fmt[i]; i++)
517 345980298 : switch (fmt[i])
518 : {
519 3279932 : case 'E':
520 3279932 : vec = XVEC (x, i);
521 3279932 : newvec = XVEC (newx, i);
522 13656800 : for (j = 0; j < GET_NUM_ELEM (vec); j++)
523 : {
524 10376868 : op = simplify_replace_fn_rtx (RTVEC_ELT (vec, j),
525 : old_rtx, fn, data);
526 10376868 : if (op != RTVEC_ELT (vec, j))
527 : {
528 356974 : if (newvec == vec)
529 : {
530 342340 : newvec = shallow_copy_rtvec (vec);
531 342340 : if (x == newx)
532 342340 : newx = shallow_copy_rtx (x);
533 342340 : XVEC (newx, i) = newvec;
534 : }
535 356974 : RTVEC_ELT (newvec, j) = op;
536 : }
537 : }
538 : break;
539 :
540 83790690 : case 'e':
541 83790690 : if (XEXP (x, i))
542 : {
543 83790640 : op = simplify_replace_fn_rtx (XEXP (x, i), old_rtx, fn, data);
544 83790640 : if (op != XEXP (x, i))
545 : {
546 4778196 : if (x == newx)
547 4774976 : newx = shallow_copy_rtx (x);
548 4778196 : 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 13293928 : simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx)
561 : {
562 13293928 : 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 23648811 : simplify_context::simplify_truncation (machine_mode mode, rtx op,
614 : machine_mode op_mode)
615 : {
616 23648811 : unsigned int precision = GET_MODE_UNIT_PRECISION (mode);
617 23648811 : unsigned int op_precision = GET_MODE_UNIT_PRECISION (op_mode);
618 23648811 : scalar_int_mode int_mode, int_op_mode, subreg_mode;
619 :
620 23648811 : gcc_assert (precision <= op_precision);
621 :
622 : /* Optimize truncations of zero and sign extended values. */
623 23648811 : if (GET_CODE (op) == ZERO_EXTEND
624 23648811 : || 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 375556 : machine_mode origmode = GET_MODE (XEXP (op, 0));
633 375556 : if (mode == origmode)
634 : return XEXP (op, 0);
635 27468 : else if (precision <= GET_MODE_UNIT_PRECISION (origmode))
636 10827 : return simplify_gen_unary (TRUNCATE, mode,
637 10827 : XEXP (op, 0), origmode);
638 : else
639 2907 : return simplify_gen_unary (GET_CODE (op), mode,
640 2907 : 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 23273255 : if (1
647 : && (!WORD_REGISTER_OPERATIONS || precision >= BITS_PER_WORD)
648 : && (GET_CODE (op) == PLUS
649 : || GET_CODE (op) == MINUS
650 23273255 : || GET_CODE (op) == MULT))
651 : {
652 1413740 : rtx op0 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0), op_mode);
653 1413740 : if (op0)
654 : {
655 1413740 : rtx op1 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 1), op_mode);
656 1413740 : if (op1)
657 1413740 : 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 21859515 : if ((GET_CODE (op) == LSHIFTRT
665 21859515 : || 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 1925515 : && 2 * precision <= op_precision
671 1925515 : && CONST_INT_P (XEXP (op, 1))
672 1824411 : && 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 21859491 : if ((GET_CODE (op) == LSHIFTRT
682 : || GET_CODE (op) == ASHIFTRT)
683 1925491 : && CONST_INT_P (XEXP (op, 1))
684 1824387 : && GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
685 924 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
686 924 : && UINTVAL (XEXP (op, 1)) < precision)
687 907 : return simplify_gen_binary (LSHIFTRT, mode,
688 907 : 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 21858584 : if (GET_CODE (op) == ASHIFT
694 841123 : && CONST_INT_P (XEXP (op, 1))
695 781330 : && (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
696 781330 : || GET_CODE (XEXP (op, 0)) == SIGN_EXTEND)
697 638 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
698 628 : && UINTVAL (XEXP (op, 1)) < precision)
699 583 : return simplify_gen_binary (ASHIFT, mode,
700 583 : 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 21858001 : if (GET_CODE (op) == AND
706 799740 : && (GET_CODE (XEXP (op, 0)) == LSHIFTRT
707 799740 : || GET_CODE (XEXP (op, 0)) == ASHIFTRT)
708 47916 : && CONST_INT_P (XEXP (XEXP (op, 0), 1))
709 47811 : && CONST_INT_P (XEXP (op, 1)))
710 : {
711 47778 : rtx op0 = (XEXP (XEXP (op, 0), 0));
712 47778 : rtx shift_op = XEXP (XEXP (op, 0), 1);
713 47778 : rtx mask_op = XEXP (op, 1);
714 47778 : unsigned HOST_WIDE_INT shift = UINTVAL (shift_op);
715 47778 : unsigned HOST_WIDE_INT mask = UINTVAL (mask_op);
716 :
717 47778 : if (shift < precision
718 : /* If doing this transform works for an X with all bits set,
719 : it works for any X. */
720 31636 : && ((GET_MODE_MASK (mode) >> shift) & mask)
721 31636 : == ((GET_MODE_MASK (op_mode) >> shift) & mask)
722 6839 : && (op0 = simplify_gen_unary (TRUNCATE, mode, op0, op_mode))
723 54617 : && (op0 = simplify_gen_binary (LSHIFTRT, mode, op0, shift_op)))
724 : {
725 6839 : mask_op = GEN_INT (trunc_int_for_mode (mask, mode));
726 6839 : return simplify_gen_binary (AND, mode, op0, mask_op);
727 : }
728 : }
729 :
730 : /* Turn (truncate:M1 (*_extract:M2 (reg:M3) (len) (pos))) into
731 : (*_extract:M1 (truncate:M1 (reg:M3)) (len) (pos')) if possible. */
732 21851162 : if ((GET_CODE (op) == ZERO_EXTRACT || GET_CODE (op) == SIGN_EXTRACT)
733 1141892 : && precision <= GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (op, 0)))
734 569162 : && CONST_INT_P (XEXP (op, 1))
735 22420324 : && CONST_INT_P (XEXP (op, 2)))
736 : {
737 533833 : rtx op0 = XEXP (op, 0);
738 533833 : unsigned HOST_WIDE_INT len = UINTVAL (XEXP (op, 1));
739 533833 : unsigned HOST_WIDE_INT pos = UINTVAL (XEXP (op, 2));
740 533833 : if (BITS_BIG_ENDIAN && pos >= op_precision - precision)
741 : {
742 : if (GET_MODE (op0) != mode)
743 : op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
744 : if (op0)
745 : {
746 : pos -= op_precision - precision;
747 : return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
748 : XEXP (op, 1), GEN_INT (pos));
749 : }
750 : }
751 533833 : else if (!BITS_BIG_ENDIAN && precision >= len + pos)
752 : {
753 182261 : if (GET_MODE (op0) != mode)
754 138281 : op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
755 138281 : if (op0)
756 182261 : return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
757 182261 : XEXP (op, 1), XEXP (op, 2));
758 : }
759 : }
760 :
761 : /* Recognize a word extraction from a multi-word subreg. */
762 21668901 : if ((GET_CODE (op) == LSHIFTRT
763 21668901 : || GET_CODE (op) == ASHIFTRT)
764 1924584 : && SCALAR_INT_MODE_P (mode)
765 1921367 : && SCALAR_INT_MODE_P (op_mode)
766 2059159 : && precision >= BITS_PER_WORD
767 61695 : && 2 * precision <= op_precision
768 61695 : && CONST_INT_P (XEXP (op, 1))
769 52210 : && (INTVAL (XEXP (op, 1)) & (precision - 1)) == 0
770 1766 : && UINTVAL (XEXP (op, 1)) < op_precision)
771 : {
772 1766 : poly_int64 byte = subreg_lowpart_offset (mode, op_mode);
773 1766 : int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
774 1766 : return simplify_gen_subreg (mode, XEXP (op, 0), op_mode,
775 : (WORDS_BIG_ENDIAN
776 1766 : ? byte - shifted_bytes
777 1766 : : 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 21667135 : if ((GET_CODE (op) == LSHIFTRT
784 : || GET_CODE (op) == ASHIFTRT)
785 1919601 : && is_a <scalar_int_mode> (mode, &int_mode)
786 21666463 : && is_a <scalar_int_mode> (op_mode, &int_op_mode)
787 1919601 : && MEM_P (XEXP (op, 0))
788 11321 : && CONST_INT_P (XEXP (op, 1))
789 20866 : && INTVAL (XEXP (op, 1)) % GET_MODE_BITSIZE (int_mode) == 0
790 715 : && INTVAL (XEXP (op, 1)) > 0
791 1430 : && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (int_op_mode)
792 715 : && ! mode_dependent_address_p (XEXP (XEXP (op, 0), 0),
793 715 : MEM_ADDR_SPACE (XEXP (op, 0)))
794 715 : && ! MEM_VOLATILE_P (XEXP (op, 0))
795 21667135 : && (GET_MODE_SIZE (int_mode) >= UNITS_PER_WORD
796 : || WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN))
797 : {
798 672 : poly_int64 byte = subreg_lowpart_offset (int_mode, int_op_mode);
799 672 : int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
800 672 : 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 21666463 : if ((GET_CODE (op) == ABS
809 21666463 : || GET_CODE (op) == NEG)
810 21304 : && (GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
811 21304 : || 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 21666462 : if (GET_CODE (op) == SUBREG
818 21667012 : && is_a <scalar_int_mode> (mode, &int_mode)
819 120600 : && SCALAR_INT_MODE_P (op_mode)
820 120600 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &subreg_mode)
821 21786568 : && subreg_lowpart_p (op))
822 : {
823 : /* (truncate:A (subreg:B (truncate:C X) 0)) is (truncate:A X). */
824 120086 : 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 120086 : if (is_a <scalar_int_mode> (op_mode, &int_op_mode))
841 : {
842 120086 : unsigned int int_op_prec = GET_MODE_PRECISION (int_op_mode);
843 120086 : unsigned int subreg_prec = GET_MODE_PRECISION (subreg_mode);
844 120086 : if (int_op_prec > subreg_prec)
845 : {
846 89574 : if (int_mode == subreg_mode)
847 : return SUBREG_REG (op);
848 63 : if (GET_MODE_PRECISION (int_mode) < subreg_prec)
849 27 : return simplify_gen_unary (TRUNCATE, int_mode,
850 27 : SUBREG_REG (op), subreg_mode);
851 : }
852 : /* Simplification of (truncate:A (subreg:B X:C 0)) where
853 : A is narrower than B and B is narrower than C. */
854 30512 : else if (int_op_prec < subreg_prec
855 30512 : && GET_MODE_PRECISION (int_mode) < int_op_prec)
856 30512 : return simplify_gen_unary (TRUNCATE, int_mode,
857 30512 : SUBREG_REG (op), subreg_mode);
858 : }
859 : }
860 :
861 : /* (truncate:A (truncate:B X)) is (truncate:A X). */
862 21546412 : 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 21546412 : if (GET_CODE (op) == IOR
869 35200 : && SCALAR_INT_MODE_P (mode)
870 35200 : && SCALAR_INT_MODE_P (op_mode)
871 35200 : && CONST_INT_P (XEXP (op, 1))
872 21554889 : && 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 30124506 : simplify_context::simplify_unary_operation (rtx_code code, machine_mode mode,
883 : rtx op, machine_mode op_mode)
884 : {
885 30124506 : rtx trueop, tem;
886 :
887 30124506 : trueop = avoid_constant_pool_reference (op);
888 :
889 30124506 : tem = simplify_const_unary_operation (code, mode, trueop, op_mode);
890 30124506 : if (tem)
891 : return tem;
892 :
893 24649531 : 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 2797 : exact_int_to_float_conversion_p (const_rtx op)
901 : {
902 2797 : 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 2797 : if (op0_mode == VOIDmode)
906 : return false;
907 5592 : int out_bits = significand_size (GET_MODE_INNER (GET_MODE (op)));
908 2796 : int in_prec = GET_MODE_UNIT_PRECISION (op0_mode);
909 2796 : int in_bits = in_prec;
910 2796 : if (HWI_COMPUTABLE_MODE_P (op0_mode))
911 : {
912 2706 : unsigned HOST_WIDE_INT nonzero = nonzero_bits (XEXP (op, 0), op0_mode);
913 2706 : if (GET_CODE (op) == FLOAT)
914 2585 : 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 2706 : in_bits -= wi::ctz (wi::uhwi (nonzero, in_prec));
920 : }
921 2796 : 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 24649531 : simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
928 : rtx op)
929 : {
930 24649531 : enum rtx_code reversed;
931 24649531 : rtx temp, elt, base, step;
932 24649531 : scalar_int_mode inner, int_mode, op_mode, op0_mode;
933 :
934 24649531 : switch (code)
935 : {
936 2415723 : case NOT:
937 : /* (not (not X)) == X. */
938 2415723 : if (GET_CODE (op) == NOT)
939 3169 : 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 2412554 : if (COMPARISON_P (op)
944 17236 : && ((SCALAR_INT_MODE_P (mode) && STORE_FLAG_VALUE == -1)
945 : #ifdef VECTOR_STORE_FLAG_VALUE
946 17236 : || (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
947 : && VECTOR_STORE_FLAG_VALUE (mode) == constm1_rtx)
948 : #endif
949 11932 : || mode == BImode)
950 2417858 : && ((reversed = reversed_comparison_code (op, NULL)) != UNKNOWN))
951 5133 : return simplify_gen_relational (reversed, mode, VOIDmode,
952 5133 : 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 2407421 : if (GET_CODE (op) == NEG
957 76461 : && 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 2407427 : && ((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 2407415 : if (GET_CODE (op) == PLUS
975 285120 : && XEXP (op, 1) == constm1_rtx)
976 4647 : 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 2402768 : if (GET_CODE (op) == NEG && CONSTM1_RTX (mode))
982 76452 : return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
983 76452 : CONSTM1_RTX (mode));
984 :
985 : /* (not (xor X C)) for C constant is (xor X D) with D = ~C. */
986 2326316 : if (GET_CODE (op) == XOR
987 18668 : && CONST_INT_P (XEXP (op, 1))
988 2330860 : && (temp = simplify_unary_operation (NOT, mode,
989 : XEXP (op, 1), mode)) != 0)
990 4544 : 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 2321772 : if (GET_CODE (op) == PLUS
994 280473 : && CONST_INT_P (XEXP (op, 1))
995 164949 : && mode_signbit_p (mode, XEXP (op, 1))
996 2325658 : && (temp = simplify_unary_operation (NOT, mode,
997 : XEXP (op, 1), mode)) != 0)
998 3886 : 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 2317886 : if (GET_CODE (op) == ASHIFT
1007 31832 : && XEXP (op, 0) == const1_rtx)
1008 : {
1009 1143 : temp = simplify_gen_unary (NOT, mode, const1_rtx, mode);
1010 1143 : 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 2316743 : 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 2316743 : if (partial_subreg_p (op)
1026 605892 : && subreg_lowpart_p (op)
1027 605580 : && GET_CODE (SUBREG_REG (op)) == ASHIFT
1028 623764 : && XEXP (SUBREG_REG (op), 0) == const1_rtx)
1029 : {
1030 147 : machine_mode inner_mode = GET_MODE (SUBREG_REG (op));
1031 147 : rtx x;
1032 :
1033 147 : x = gen_rtx_ROTATE (inner_mode,
1034 : simplify_gen_unary (NOT, inner_mode, const1_rtx,
1035 : inner_mode),
1036 : XEXP (SUBREG_REG (op), 1));
1037 147 : temp = rtl_hooks.gen_lowpart_no_emit (mode, x);
1038 147 : if (temp)
1039 : return temp;
1040 : }
1041 :
1042 : /* Apply De Morgan's laws to reduce number of patterns for machines
1043 : with negating logical insns (and-not, nand, etc.). If result has
1044 : only one NOT, put it first, since that is how the patterns are
1045 : coded. */
1046 2316596 : if (GET_CODE (op) == IOR || GET_CODE (op) == AND)
1047 : {
1048 14293 : rtx in1 = XEXP (op, 0), in2 = XEXP (op, 1);
1049 14293 : machine_mode op_mode;
1050 :
1051 14293 : op_mode = GET_MODE (in1);
1052 14293 : in1 = simplify_gen_unary (NOT, op_mode, in1, op_mode);
1053 :
1054 14293 : op_mode = GET_MODE (in2);
1055 14293 : if (op_mode == VOIDmode)
1056 5686 : op_mode = mode;
1057 14293 : in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode);
1058 :
1059 14293 : if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT)
1060 : std::swap (in1, in2);
1061 :
1062 28586 : 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 2302303 : 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 1816595 : case NEG:
1075 : /* (neg (neg X)) == X. */
1076 1816595 : if (GET_CODE (op) == NEG)
1077 6887 : 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 1809708 : if (GET_CODE (op) == IF_THEN_ELSE)
1083 : {
1084 3355 : rtx cond = XEXP (op, 0);
1085 3355 : rtx true_rtx = XEXP (op, 1);
1086 3355 : rtx false_rtx = XEXP (op, 2);
1087 :
1088 3355 : if ((GET_CODE (true_rtx) == NEG
1089 0 : && rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
1090 3355 : || (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 1809708 : if (GET_CODE (op) == PLUS
1107 143595 : && XEXP (op, 1) == const1_rtx)
1108 57266 : return simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1109 :
1110 : /* Similarly, (neg (not X)) is (plus X 1). */
1111 1752442 : if (GET_CODE (op) == NOT)
1112 264 : return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
1113 264 : 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 1752178 : if (GET_CODE (op) == MINUS
1121 25049 : && !HONOR_SIGNED_ZEROS (mode)
1122 1775837 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1123 23659 : return simplify_gen_binary (MINUS, mode, XEXP (op, 1), XEXP (op, 0));
1124 :
1125 1728519 : if (GET_CODE (op) == PLUS
1126 86329 : && !HONOR_SIGNED_ZEROS (mode)
1127 1814372 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1128 : {
1129 : /* (neg (plus A C)) is simplified to (minus -C A). */
1130 85853 : if (CONST_SCALAR_INT_P (XEXP (op, 1))
1131 5166 : || CONST_DOUBLE_AS_FLOAT_P (XEXP (op, 1)))
1132 : {
1133 80687 : temp = simplify_unary_operation (NEG, mode, XEXP (op, 1), mode);
1134 80687 : if (temp)
1135 80687 : 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 5166 : temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
1140 5166 : 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 1642666 : if (GET_CODE (op) == MULT
1146 1642666 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1147 : {
1148 24901 : temp = simplify_gen_unary (NEG, mode, XEXP (op, 1), mode);
1149 24901 : 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 1617765 : if (GET_CODE (op) == ASHIFT)
1156 : {
1157 50446 : temp = simplify_unary_operation (NEG, mode, XEXP (op, 0), mode);
1158 50446 : if (temp)
1159 10123 : 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 1607642 : if (GET_CODE (op) == ASHIFTRT
1165 30304 : && CONST_INT_P (XEXP (op, 1))
1166 1668142 : && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1167 776 : return simplify_gen_binary (LSHIFTRT, mode,
1168 776 : XEXP (op, 0), XEXP (op, 1));
1169 :
1170 : /* (neg (lshiftrt X C)) can be replaced by (ashiftrt X C) when
1171 : C is equal to the width of MODE minus 1. */
1172 1606866 : if (GET_CODE (op) == LSHIFTRT
1173 9242 : && CONST_INT_P (XEXP (op, 1))
1174 1625206 : && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1175 3619 : return simplify_gen_binary (ASHIFTRT, mode,
1176 3619 : 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 1603247 : if (GET_CODE (op) == XOR
1180 11009 : && XEXP (op, 1) == const1_rtx
1181 1603336 : && nonzero_bits (XEXP (op, 0), mode) == 1)
1182 34 : return plus_constant (mode, XEXP (op, 0), -1);
1183 :
1184 : /* (neg (lt x 0)) is (ashiftrt X C) if STORE_FLAG_VALUE is 1. */
1185 : /* (neg (lt x 0)) is (lshiftrt X C) if STORE_FLAG_VALUE is -1. */
1186 1603213 : if (GET_CODE (op) == LT
1187 3187 : && XEXP (op, 1) == const0_rtx
1188 1605567 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op, 0)), &inner))
1189 : {
1190 544 : int_mode = as_a <scalar_int_mode> (mode);
1191 544 : int isize = GET_MODE_PRECISION (inner);
1192 544 : if (STORE_FLAG_VALUE == 1)
1193 : {
1194 544 : temp = simplify_gen_binary (ASHIFTRT, inner, XEXP (op, 0),
1195 : gen_int_shift_amount (inner,
1196 544 : isize - 1));
1197 544 : if (int_mode == inner)
1198 : return temp;
1199 315 : if (GET_MODE_PRECISION (int_mode) > isize)
1200 187 : return simplify_gen_unary (SIGN_EXTEND, int_mode, temp, inner);
1201 128 : 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 1602669 : 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 2265282 : case TRUNCATE:
1234 : /* Don't optimize (lshiftrt (mult ...)) as it would interfere
1235 : with the umulXi3_highpart patterns. */
1236 2265282 : if (GET_CODE (op) == LSHIFTRT
1237 20045 : && GET_CODE (XEXP (op, 0)) == MULT)
1238 : break;
1239 :
1240 2258112 : 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 2258100 : if (GET_MODE (op) != VOIDmode)
1255 : {
1256 2258100 : temp = simplify_truncation (mode, op, GET_MODE (op));
1257 2258100 : 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 1955178 : if (known_eq (GET_MODE_NUNITS (mode), 1)
1264 1955178 : && (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op))
1265 0 : || truncated_to_mode (mode, op)))
1266 : {
1267 1942609 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1268 1942609 : 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 12743 : if (HWI_COMPUTABLE_MODE_P (mode)
1277 174 : && COMPARISON_P (op)
1278 0 : && (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0
1279 12743 : && 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 12743 : if (GET_CODE (op) == MEM
1289 286 : && !VECTOR_MODE_P (mode)
1290 170 : && !MEM_VOLATILE_P (op)
1291 12907 : && !mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op)))
1292 : {
1293 164 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1294 164 : if (temp)
1295 : return temp;
1296 : }
1297 :
1298 : /* Check for useless truncation. */
1299 12743 : if (GET_MODE (op) == mode)
1300 : return op;
1301 : break;
1302 :
1303 174484 : case FLOAT_TRUNCATE:
1304 : /* Check for useless truncation. */
1305 174484 : if (GET_MODE (op) == mode)
1306 : return op;
1307 :
1308 174484 : if (DECIMAL_FLOAT_MODE_P (mode))
1309 : break;
1310 :
1311 : /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF. */
1312 174330 : 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 174328 : if ((GET_CODE (op) == FLOAT_TRUNCATE
1326 145 : && flag_unsafe_math_optimizations)
1327 174324 : || 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 174321 : if ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1336 174321 : && (flag_unsafe_math_optimizations
1337 1413 : || exact_int_to_float_conversion_p (op)))
1338 1412 : return simplify_gen_unary (GET_CODE (op), mode,
1339 : XEXP (op, 0),
1340 1412 : 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 172909 : if ((GET_CODE (op) == ABS
1345 172909 : || GET_CODE (op) == NEG)
1346 210 : && GET_CODE (XEXP (op, 0)) == FLOAT_EXTEND
1347 28 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
1348 28 : return simplify_gen_unary (GET_CODE (op), mode,
1349 28 : XEXP (XEXP (op, 0), 0), mode);
1350 :
1351 : /* (float_truncate:SF (subreg:DF (float_truncate:SF X) 0))
1352 : is (float_truncate:SF x). */
1353 172881 : if (GET_CODE (op) == SUBREG
1354 307 : && subreg_lowpart_p (op)
1355 173185 : && GET_CODE (SUBREG_REG (op)) == FLOAT_TRUNCATE)
1356 : return SUBREG_REG (op);
1357 : break;
1358 :
1359 600785 : case FLOAT_EXTEND:
1360 : /* Check for useless extension. */
1361 600785 : if (GET_MODE (op) == mode)
1362 : return op;
1363 :
1364 600785 : 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 600682 : if (GET_CODE (op) == FLOAT_EXTEND
1373 600682 : || ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1374 1384 : && exact_int_to_float_conversion_p (op)))
1375 551 : return simplify_gen_unary (GET_CODE (op), mode,
1376 : XEXP (op, 0),
1377 551 : GET_MODE (XEXP (op, 0)));
1378 :
1379 : break;
1380 :
1381 332497 : case ABS:
1382 : /* (abs (neg <foo>)) -> (abs <foo>) */
1383 332497 : if (GET_CODE (op) == NEG)
1384 18 : return simplify_gen_unary (ABS, mode, XEXP (op, 0),
1385 18 : GET_MODE (XEXP (op, 0)));
1386 :
1387 : /* If the mode of the operand is VOIDmode (i.e. if it is ASM_OPERANDS),
1388 : do nothing. */
1389 332479 : if (GET_MODE (op) == VOIDmode)
1390 : break;
1391 :
1392 : /* If operand is something known to be positive, ignore the ABS. */
1393 332479 : 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 332333 : 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 332333 : && 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 332333 : if (is_a <scalar_int_mode> (mode, &int_mode)
1424 55220 : && (num_sign_bit_copies (op, int_mode)
1425 55220 : == GET_MODE_PRECISION (int_mode)))
1426 14 : return gen_rtx_NEG (int_mode, op);
1427 :
1428 : break;
1429 :
1430 0 : case FFS:
1431 : /* (ffs (*_extend <X>)) = (*_extend (ffs <X>)). */
1432 0 : if (GET_CODE (op) == SIGN_EXTEND
1433 0 : || GET_CODE (op) == ZERO_EXTEND)
1434 : {
1435 0 : temp = simplify_gen_unary (FFS, GET_MODE (XEXP (op, 0)),
1436 0 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1437 0 : return simplify_gen_unary (GET_CODE (op), mode, temp,
1438 0 : GET_MODE (temp));
1439 : }
1440 : break;
1441 :
1442 3441 : case POPCOUNT:
1443 3441 : switch (GET_CODE (op))
1444 : {
1445 0 : case BSWAP:
1446 0 : case BITREVERSE:
1447 : /* (popcount (bswap <X>)) = (popcount <X>). */
1448 0 : return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1449 0 : GET_MODE (XEXP (op, 0)));
1450 :
1451 44 : case ZERO_EXTEND:
1452 : /* (popcount (zero_extend <X>)) = (zero_extend (popcount <X>)). */
1453 88 : temp = simplify_gen_unary (POPCOUNT, GET_MODE (XEXP (op, 0)),
1454 44 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1455 44 : return simplify_gen_unary (ZERO_EXTEND, mode, temp,
1456 44 : GET_MODE (temp));
1457 :
1458 0 : case ROTATE:
1459 0 : case ROTATERT:
1460 : /* Rotations don't affect popcount. */
1461 0 : if (!side_effects_p (XEXP (op, 1)))
1462 0 : return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1463 0 : GET_MODE (XEXP (op, 0)));
1464 : break;
1465 :
1466 : default:
1467 : break;
1468 : }
1469 : break;
1470 :
1471 0 : case PARITY:
1472 0 : switch (GET_CODE (op))
1473 : {
1474 0 : case NOT:
1475 0 : case BSWAP:
1476 0 : case BITREVERSE:
1477 0 : return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1478 0 : GET_MODE (XEXP (op, 0)));
1479 :
1480 0 : case ZERO_EXTEND:
1481 0 : case SIGN_EXTEND:
1482 0 : temp = simplify_gen_unary (PARITY, GET_MODE (XEXP (op, 0)),
1483 0 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1484 0 : return simplify_gen_unary (GET_CODE (op), mode, temp,
1485 0 : GET_MODE (temp));
1486 :
1487 0 : case ROTATE:
1488 0 : case ROTATERT:
1489 : /* Rotations don't affect parity. */
1490 0 : if (!side_effects_p (XEXP (op, 1)))
1491 0 : return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1492 0 : GET_MODE (XEXP (op, 0)));
1493 : break;
1494 :
1495 : case PARITY:
1496 : /* (parity (parity x)) -> parity (x). */
1497 : return op;
1498 :
1499 : default:
1500 : break;
1501 : }
1502 : break;
1503 :
1504 31296 : case BSWAP:
1505 : /* (bswap (bswap x)) -> x. */
1506 31296 : if (GET_CODE (op) == BSWAP)
1507 184 : return XEXP (op, 0);
1508 : /* Canonicalize (bswap (bitreverse x)) as (bitreverse (bswap x)). */
1509 31112 : if (GET_CODE (op) == BITREVERSE)
1510 0 : return simplify_gen_unary (BITREVERSE, mode,
1511 : simplify_gen_unary (BSWAP, mode,
1512 : XEXP (op, 0), mode),
1513 0 : mode);
1514 : break;
1515 :
1516 0 : case BITREVERSE:
1517 : /* (bitreverse (bitreverse x)) -> x. */
1518 0 : if (GET_CODE (op) == BITREVERSE)
1519 0 : return XEXP (op, 0);
1520 : break;
1521 :
1522 957007 : case FLOAT:
1523 : /* (float (sign_extend <X>)) = (float <X>). */
1524 957007 : if (GET_CODE (op) == SIGN_EXTEND)
1525 9666 : return simplify_gen_unary (FLOAT, mode, XEXP (op, 0),
1526 9666 : GET_MODE (XEXP (op, 0)));
1527 : break;
1528 :
1529 3123829 : case SIGN_EXTEND:
1530 : /* Check for useless extension. */
1531 3123829 : if (GET_MODE (op) == mode)
1532 : return op;
1533 :
1534 : /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
1535 : becomes just the MINUS if its mode is MODE. This allows
1536 : folding switch statements on machines using casesi (such as
1537 : the VAX). */
1538 3123789 : if (GET_CODE (op) == TRUNCATE
1539 62 : && GET_MODE (XEXP (op, 0)) == mode
1540 62 : && GET_CODE (XEXP (op, 0)) == MINUS
1541 0 : && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
1542 0 : && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
1543 : return XEXP (op, 0);
1544 :
1545 : /* Extending a widening multiplication should be canonicalized to
1546 : a wider widening multiplication. */
1547 3123789 : if (GET_CODE (op) == MULT)
1548 : {
1549 67558 : rtx lhs = XEXP (op, 0);
1550 67558 : rtx rhs = XEXP (op, 1);
1551 67558 : enum rtx_code lcode = GET_CODE (lhs);
1552 67558 : enum rtx_code rcode = GET_CODE (rhs);
1553 :
1554 : /* Widening multiplies usually extend both operands, but sometimes
1555 : they use a shift to extract a portion of a register. */
1556 67558 : if ((lcode == SIGN_EXTEND
1557 67429 : || (lcode == ASHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1558 888 : && (rcode == SIGN_EXTEND
1559 868 : || (rcode == ASHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1560 : {
1561 105 : machine_mode lmode = GET_MODE (lhs);
1562 105 : machine_mode rmode = GET_MODE (rhs);
1563 105 : int bits;
1564 :
1565 105 : if (lcode == ASHIFTRT)
1566 : /* Number of bits not shifted off the end. */
1567 89 : bits = (GET_MODE_UNIT_PRECISION (lmode)
1568 89 : - INTVAL (XEXP (lhs, 1)));
1569 : else /* lcode == SIGN_EXTEND */
1570 : /* Size of inner mode. */
1571 32 : bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1572 :
1573 105 : if (rcode == ASHIFTRT)
1574 85 : bits += (GET_MODE_UNIT_PRECISION (rmode)
1575 85 : - INTVAL (XEXP (rhs, 1)));
1576 : else /* rcode == SIGN_EXTEND */
1577 40 : bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1578 :
1579 : /* We can only widen multiplies if the result is mathematiclly
1580 : equivalent. I.e. if overflow was impossible. */
1581 210 : if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1582 48 : return simplify_gen_binary
1583 48 : (MULT, mode,
1584 : simplify_gen_unary (SIGN_EXTEND, mode, lhs, lmode),
1585 48 : simplify_gen_unary (SIGN_EXTEND, mode, rhs, rmode));
1586 : }
1587 : }
1588 :
1589 : /* Check for a sign extension of a subreg of a promoted
1590 : variable, where the promotion is sign-extended, and the
1591 : target mode is the same as the variable's promotion. */
1592 3123741 : if (GET_CODE (op) == SUBREG
1593 214195 : && SUBREG_PROMOTED_VAR_P (op)
1594 3128882 : && SUBREG_PROMOTED_SIGNED_P (op))
1595 : {
1596 0 : rtx subreg = SUBREG_REG (op);
1597 0 : machine_mode subreg_mode = GET_MODE (subreg);
1598 0 : if (!paradoxical_subreg_p (mode, subreg_mode))
1599 : {
1600 0 : temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
1601 0 : if (temp)
1602 : {
1603 : /* Preserve SUBREG_PROMOTED_VAR_P. */
1604 0 : if (partial_subreg_p (temp))
1605 : {
1606 0 : SUBREG_PROMOTED_VAR_P (temp) = 1;
1607 0 : SUBREG_PROMOTED_SET (temp, SRP_SIGNED);
1608 : }
1609 : return temp;
1610 : }
1611 : }
1612 : else
1613 : /* Sign-extending a sign-extended subreg. */
1614 0 : return simplify_gen_unary (SIGN_EXTEND, mode,
1615 0 : subreg, subreg_mode);
1616 : }
1617 :
1618 : /* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
1619 : (sign_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1620 3123741 : if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND)
1621 : {
1622 20034 : gcc_assert (GET_MODE_UNIT_PRECISION (mode)
1623 : > GET_MODE_UNIT_PRECISION (GET_MODE (op)));
1624 6678 : return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0),
1625 6678 : GET_MODE (XEXP (op, 0)));
1626 : }
1627 :
1628 : /* (sign_extend:M (ashiftrt:N (ashift <X> (const_int I)) (const_int I)))
1629 : is (sign_extend:M (subreg:O <X>)) if there is mode with
1630 : GET_MODE_BITSIZE (N) - I bits.
1631 : (sign_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1632 : is similarly (zero_extend:M (subreg:O <X>)). */
1633 3117063 : if ((GET_CODE (op) == ASHIFTRT || GET_CODE (op) == LSHIFTRT)
1634 90203 : && GET_CODE (XEXP (op, 0)) == ASHIFT
1635 3119685 : && is_a <scalar_int_mode> (mode, &int_mode)
1636 5241 : && CONST_INT_P (XEXP (op, 1))
1637 5241 : && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1638 3122175 : && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1639 5112 : GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1640 : {
1641 5112 : scalar_int_mode tmode;
1642 5112 : gcc_assert (GET_MODE_PRECISION (int_mode)
1643 : > GET_MODE_PRECISION (op_mode));
1644 5112 : if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1645 7605 : - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1646 : {
1647 2619 : rtx inner =
1648 2619 : rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1649 2619 : if (inner)
1650 2619 : return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
1651 : ? SIGN_EXTEND : ZERO_EXTEND,
1652 2619 : int_mode, inner, tmode);
1653 : }
1654 : }
1655 :
1656 : /* (sign_extend:M (lshiftrt:N <X> (const_int I))) is better as
1657 : (zero_extend:M (lshiftrt:N <X> (const_int I))) if I is not 0. */
1658 3114444 : if (GET_CODE (op) == LSHIFTRT
1659 167 : && CONST_INT_P (XEXP (op, 1))
1660 167 : && XEXP (op, 1) != const0_rtx)
1661 167 : return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1662 :
1663 : /* (sign_extend:M (truncate:N (lshiftrt:O <X> (const_int I)))) where
1664 : I is GET_MODE_PRECISION(O) - GET_MODE_PRECISION(N), simplifies to
1665 : (ashiftrt:M <X> (const_int I)) if modes M and O are the same, and
1666 : (truncate:M (ashiftrt:O <X> (const_int I))) if M is narrower than
1667 : O, and (sign_extend:M (ashiftrt:O <X> (const_int I))) if M is
1668 : wider than O. */
1669 3114277 : if (GET_CODE (op) == TRUNCATE
1670 62 : && GET_CODE (XEXP (op, 0)) == LSHIFTRT
1671 0 : && CONST_INT_P (XEXP (XEXP (op, 0), 1)))
1672 : {
1673 0 : scalar_int_mode m_mode, n_mode, o_mode;
1674 0 : rtx old_shift = XEXP (op, 0);
1675 0 : if (is_a <scalar_int_mode> (mode, &m_mode)
1676 0 : && is_a <scalar_int_mode> (GET_MODE (op), &n_mode)
1677 0 : && is_a <scalar_int_mode> (GET_MODE (old_shift), &o_mode)
1678 0 : && GET_MODE_PRECISION (o_mode) - GET_MODE_PRECISION (n_mode)
1679 0 : == INTVAL (XEXP (old_shift, 1)))
1680 : {
1681 0 : rtx new_shift = simplify_gen_binary (ASHIFTRT,
1682 : GET_MODE (old_shift),
1683 : XEXP (old_shift, 0),
1684 : XEXP (old_shift, 1));
1685 0 : if (GET_MODE_PRECISION (m_mode) > GET_MODE_PRECISION (o_mode))
1686 0 : return simplify_gen_unary (SIGN_EXTEND, mode, new_shift,
1687 0 : GET_MODE (new_shift));
1688 0 : if (mode != GET_MODE (new_shift))
1689 0 : return simplify_gen_unary (TRUNCATE, mode, new_shift,
1690 0 : GET_MODE (new_shift));
1691 : return new_shift;
1692 : }
1693 : }
1694 :
1695 : /* We can canonicalize SIGN_EXTEND (op) as ZERO_EXTEND (op) when
1696 : we know the sign bit of OP must be clear. */
1697 3114277 : if (val_signbit_known_clear_p (GET_MODE (op),
1698 3114277 : nonzero_bits (op, GET_MODE (op))))
1699 39596 : return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1700 :
1701 : /* (sign_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1702 3074681 : if (GET_CODE (op) == SUBREG
1703 213911 : && subreg_lowpart_p (op)
1704 213799 : && GET_MODE (SUBREG_REG (op)) == mode
1705 3257015 : && is_a <scalar_int_mode> (mode, &int_mode)
1706 189112 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1707 189112 : && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
1708 187319 : && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
1709 3262000 : && (nonzero_bits (SUBREG_REG (op), mode)
1710 187319 : & ~(GET_MODE_MASK (op_mode) >> 1)) == 0)
1711 6778 : return SUBREG_REG (op);
1712 :
1713 : #if defined(POINTERS_EXTEND_UNSIGNED)
1714 : /* As we do not know which address space the pointer is referring to,
1715 : we can do this only if the target does not support different pointer
1716 : or address modes depending on the address space. */
1717 3067903 : if (target_default_pointer_address_modes_p ()
1718 : && ! POINTERS_EXTEND_UNSIGNED
1719 : && mode == Pmode && GET_MODE (op) == ptr_mode
1720 : && (CONSTANT_P (op)
1721 : || (GET_CODE (op) == SUBREG
1722 : && REG_P (SUBREG_REG (op))
1723 : && REG_POINTER (SUBREG_REG (op))
1724 : && GET_MODE (SUBREG_REG (op)) == Pmode))
1725 : && !targetm.have_ptr_extend ())
1726 : {
1727 : temp
1728 : = convert_memory_address_addr_space_1 (Pmode, op,
1729 : ADDR_SPACE_GENERIC, false,
1730 : true);
1731 : if (temp)
1732 : return temp;
1733 : }
1734 : #endif
1735 : break;
1736 :
1737 11751895 : case ZERO_EXTEND:
1738 : /* Check for useless extension. */
1739 11751895 : if (GET_MODE (op) == mode)
1740 : return op;
1741 :
1742 : /* (zero_extend:SI (and:QI X (const))) -> (and:SI (lowpart:SI X) const)
1743 : where const does not sign bit set. */
1744 11751853 : if (GET_CODE (op) == AND
1745 122106 : && CONST_INT_P (XEXP (op, 1))
1746 93515 : && INTVAL (XEXP (op, 1)) > 0)
1747 : {
1748 85485 : rtx tem = rtl_hooks.gen_lowpart_no_emit (mode, XEXP (op, 0));
1749 85485 : if (tem)
1750 69166 : return simplify_gen_binary (AND, mode, tem, XEXP (op, 1));
1751 : }
1752 :
1753 : /* Check for a zero extension of a subreg of a promoted
1754 : variable, where the promotion is zero-extended, and the
1755 : target mode is the same as the variable's promotion. */
1756 11682687 : if (GET_CODE (op) == SUBREG
1757 1696663 : && SUBREG_PROMOTED_VAR_P (op)
1758 11683112 : && SUBREG_PROMOTED_UNSIGNED_P (op))
1759 : {
1760 425 : rtx subreg = SUBREG_REG (op);
1761 425 : machine_mode subreg_mode = GET_MODE (subreg);
1762 425 : if (!paradoxical_subreg_p (mode, subreg_mode))
1763 : {
1764 271 : temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
1765 271 : if (temp)
1766 : {
1767 : /* Preserve SUBREG_PROMOTED_VAR_P. */
1768 271 : if (partial_subreg_p (temp))
1769 : {
1770 129 : SUBREG_PROMOTED_VAR_P (temp) = 1;
1771 129 : SUBREG_PROMOTED_SET (temp, SRP_UNSIGNED);
1772 : }
1773 : return temp;
1774 : }
1775 : }
1776 : else
1777 : /* Zero-extending a zero-extended subreg. */
1778 154 : return simplify_gen_unary (ZERO_EXTEND, mode,
1779 154 : subreg, subreg_mode);
1780 : }
1781 :
1782 : /* Extending a widening multiplication should be canonicalized to
1783 : a wider widening multiplication. */
1784 11682262 : if (GET_CODE (op) == MULT)
1785 : {
1786 185134 : rtx lhs = XEXP (op, 0);
1787 185134 : rtx rhs = XEXP (op, 1);
1788 185134 : enum rtx_code lcode = GET_CODE (lhs);
1789 185134 : enum rtx_code rcode = GET_CODE (rhs);
1790 :
1791 : /* Widening multiplies usually extend both operands, but sometimes
1792 : they use a shift to extract a portion of a register. */
1793 185134 : if ((lcode == ZERO_EXTEND
1794 184499 : || (lcode == LSHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1795 833 : && (rcode == ZERO_EXTEND
1796 783 : || (rcode == LSHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1797 : {
1798 62 : machine_mode lmode = GET_MODE (lhs);
1799 62 : machine_mode rmode = GET_MODE (rhs);
1800 62 : int bits;
1801 :
1802 62 : if (lcode == LSHIFTRT)
1803 : /* Number of bits not shifted off the end. */
1804 12 : bits = (GET_MODE_UNIT_PRECISION (lmode)
1805 12 : - INTVAL (XEXP (lhs, 1)));
1806 : else /* lcode == ZERO_EXTEND */
1807 : /* Size of inner mode. */
1808 100 : bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1809 :
1810 62 : if (rcode == LSHIFTRT)
1811 12 : bits += (GET_MODE_UNIT_PRECISION (rmode)
1812 12 : - INTVAL (XEXP (rhs, 1)));
1813 : else /* rcode == ZERO_EXTEND */
1814 100 : bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1815 :
1816 : /* We can only widen multiplies if the result is mathematiclly
1817 : equivalent. I.e. if overflow was impossible. */
1818 124 : if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1819 50 : return simplify_gen_binary
1820 50 : (MULT, mode,
1821 : simplify_gen_unary (ZERO_EXTEND, mode, lhs, lmode),
1822 50 : simplify_gen_unary (ZERO_EXTEND, mode, rhs, rmode));
1823 : }
1824 : }
1825 :
1826 : /* (zero_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1827 11682212 : if (GET_CODE (op) == ZERO_EXTEND)
1828 22370 : return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0),
1829 22370 : GET_MODE (XEXP (op, 0)));
1830 :
1831 : /* (zero_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1832 : is (zero_extend:M (subreg:O <X>)) if there is mode with
1833 : GET_MODE_PRECISION (N) - I bits. */
1834 11659842 : if (GET_CODE (op) == LSHIFTRT
1835 52124 : && GET_CODE (XEXP (op, 0)) == ASHIFT
1836 11659860 : && is_a <scalar_int_mode> (mode, &int_mode)
1837 18 : && CONST_INT_P (XEXP (op, 1))
1838 13 : && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1839 11659842 : && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1840 0 : GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1841 : {
1842 0 : scalar_int_mode tmode;
1843 0 : if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1844 0 : - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1845 : {
1846 0 : rtx inner =
1847 0 : rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1848 0 : if (inner)
1849 0 : return simplify_gen_unary (ZERO_EXTEND, int_mode,
1850 0 : inner, tmode);
1851 : }
1852 : }
1853 :
1854 : /* (zero_extend:M (subreg:N <X:O>)) is <X:O> (for M == O) or
1855 : (zero_extend:M <X:O>), if X doesn't have any non-zero bits outside
1856 : of mode N. E.g.
1857 : (zero_extend:SI (subreg:QI (and:SI (reg:SI) (const_int 63)) 0)) is
1858 : (and:SI (reg:SI) (const_int 63)). */
1859 11659842 : if (partial_subreg_p (op)
1860 13281137 : && is_a <scalar_int_mode> (mode, &int_mode)
1861 1643210 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &op0_mode)
1862 1642499 : && GET_MODE_PRECISION (op0_mode) <= HOST_BITS_PER_WIDE_INT
1863 1314991 : && GET_MODE_PRECISION (int_mode) >= GET_MODE_PRECISION (op0_mode)
1864 1293307 : && subreg_lowpart_p (op)
1865 2546697 : && (nonzero_bits (SUBREG_REG (op), op0_mode)
1866 850459 : & ~GET_MODE_MASK (GET_MODE (op))) == 0)
1867 : {
1868 21915 : if (GET_MODE_PRECISION (int_mode) == GET_MODE_PRECISION (op0_mode))
1869 14802 : return SUBREG_REG (op);
1870 7113 : return simplify_gen_unary (ZERO_EXTEND, int_mode, SUBREG_REG (op),
1871 7113 : op0_mode);
1872 : }
1873 :
1874 : /* (zero_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1875 11637927 : if (GET_CODE (op) == SUBREG
1876 1674323 : && subreg_lowpart_p (op)
1877 968606 : && GET_MODE (SUBREG_REG (op)) == mode
1878 12459298 : && is_a <scalar_int_mode> (mode, &int_mode)
1879 821371 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1880 821371 : && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
1881 757834 : && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
1882 12395761 : && (nonzero_bits (SUBREG_REG (op), mode)
1883 757834 : & ~GET_MODE_MASK (op_mode)) == 0)
1884 0 : return SUBREG_REG (op);
1885 :
1886 : /* Trying to optimize:
1887 : (zero_extend:M (subreg:N (not:M (X:M)))) ->
1888 : (xor:M (zero_extend:M (subreg:N (X:M)), mask))
1889 : where the mask is GET_MODE_MASK (N).
1890 : For the cases when X:M doesn't have any non-zero bits
1891 : outside of mode N, (zero_extend:M (subreg:N (X:M))
1892 : will be simplified to just (X:M)
1893 : and whole optimization will be -> (xor:M (X:M, mask)). */
1894 11637927 : if (partial_subreg_p (op)
1895 1621295 : && GET_CODE (XEXP (op, 0)) == NOT
1896 1417 : && GET_MODE (XEXP (op, 0)) == mode
1897 1399 : && subreg_lowpart_p (op)
1898 11638278 : && HWI_COMPUTABLE_MODE_P (mode)
1899 352 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1900 1674675 : && (nonzero_bits (XEXP (XEXP (op, 0), 0), mode)
1901 352 : & ~GET_MODE_MASK (op_mode)) == 0)
1902 : {
1903 1 : unsigned HOST_WIDE_INT mask = GET_MODE_MASK (op_mode);
1904 2 : return simplify_gen_binary (XOR, mode,
1905 1 : XEXP (XEXP (op, 0), 0),
1906 1 : gen_int_mode (mask, mode));
1907 : }
1908 :
1909 : #if defined(POINTERS_EXTEND_UNSIGNED)
1910 : /* As we do not know which address space the pointer is referring to,
1911 : we can do this only if the target does not support different pointer
1912 : or address modes depending on the address space. */
1913 11637926 : if (target_default_pointer_address_modes_p ()
1914 : && POINTERS_EXTEND_UNSIGNED > 0
1915 13267383 : && mode == Pmode && GET_MODE (op) == ptr_mode
1916 977 : && (CONSTANT_P (op)
1917 956 : || (GET_CODE (op) == SUBREG
1918 0 : && REG_P (SUBREG_REG (op))
1919 0 : && REG_POINTER (SUBREG_REG (op))
1920 0 : && GET_MODE (SUBREG_REG (op)) == Pmode))
1921 11637947 : && !targetm.have_ptr_extend ())
1922 : {
1923 21 : temp
1924 21 : = convert_memory_address_addr_space_1 (Pmode, op,
1925 : ADDR_SPACE_GENERIC, false,
1926 : true);
1927 21 : if (temp)
1928 : return temp;
1929 : }
1930 : #endif
1931 : break;
1932 :
1933 791085 : case VEC_DUPLICATE:
1934 791085 : if (GET_CODE (op) == VEC_DUPLICATE)
1935 2 : return simplify_gen_unary (VEC_DUPLICATE, mode, XEXP (op, 0),
1936 2 : GET_MODE (XEXP (op, 0)));
1937 : break;
1938 :
1939 : default:
1940 : break;
1941 : }
1942 :
1943 19980804 : if (VECTOR_MODE_P (mode)
1944 1913746 : && vec_duplicate_p (op, &elt)
1945 21900560 : && code != VEC_DUPLICATE)
1946 : {
1947 6010 : if (code == SIGN_EXTEND || code == ZERO_EXTEND)
1948 : /* Enforce a canonical order of VEC_DUPLICATE wrt other unary
1949 : operations by promoting VEC_DUPLICATE to the root of the expression
1950 : (as far as possible). */
1951 4953 : temp = simplify_gen_unary (code, GET_MODE_INNER (mode),
1952 9906 : elt, GET_MODE_INNER (GET_MODE (op)));
1953 : else
1954 : /* Try applying the operator to ELT and see if that simplifies.
1955 : We can duplicate the result if so.
1956 :
1957 : The reason we traditionally haven't used simplify_gen_unary
1958 : for these codes is that it didn't necessarily seem to be a
1959 : win to convert things like:
1960 :
1961 : (neg:V (vec_duplicate:V (reg:S R)))
1962 :
1963 : to:
1964 :
1965 : (vec_duplicate:V (neg:S (reg:S R)))
1966 :
1967 : The first might be done entirely in vector registers while the
1968 : second might need a move between register files.
1969 :
1970 : However, there also cases where promoting the vec_duplicate is
1971 : more efficient, and there is definite value in having a canonical
1972 : form when matching instruction patterns. We should consider
1973 : extending the simplify_gen_unary code above to more cases. */
1974 1057 : temp = simplify_unary_operation (code, GET_MODE_INNER (mode),
1975 2114 : elt, GET_MODE_INNER (GET_MODE (op)));
1976 6010 : if (temp)
1977 5539 : return gen_vec_duplicate (mode, temp);
1978 : }
1979 :
1980 : return 0;
1981 : }
1982 :
1983 : /* Try to compute the value of a unary operation CODE whose output mode is to
1984 : be MODE with input operand OP whose mode was originally OP_MODE.
1985 : Return zero if the value cannot be computed. */
1986 : rtx
1987 30125492 : simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
1988 : rtx op, machine_mode op_mode)
1989 : {
1990 30125492 : scalar_int_mode result_mode;
1991 :
1992 30125492 : if (code == VEC_DUPLICATE)
1993 : {
1994 1963293 : gcc_assert (VECTOR_MODE_P (mode));
1995 1963293 : if (GET_MODE (op) != VOIDmode)
1996 : {
1997 832422 : if (!VECTOR_MODE_P (GET_MODE (op)))
1998 1651466 : gcc_assert (GET_MODE_INNER (mode) == GET_MODE (op));
1999 : else
2000 20067 : gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER
2001 : (GET_MODE (op)));
2002 : }
2003 1963293 : if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op))
2004 1171452 : return gen_const_vec_duplicate (mode, op);
2005 791841 : if (GET_CODE (op) == CONST_VECTOR
2006 791841 : && (CONST_VECTOR_DUPLICATE_P (op)
2007 756 : || CONST_VECTOR_NUNITS (op).is_constant ()))
2008 : {
2009 756 : unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op)
2010 756 : ? CONST_VECTOR_NPATTERNS (op)
2011 1510 : : CONST_VECTOR_NUNITS (op).to_constant ());
2012 2268 : gcc_assert (multiple_p (GET_MODE_NUNITS (mode), npatterns));
2013 756 : rtx_vector_builder builder (mode, npatterns, 1);
2014 3888 : for (unsigned i = 0; i < npatterns; i++)
2015 2376 : builder.quick_push (CONST_VECTOR_ELT (op, i));
2016 756 : return builder.build ();
2017 756 : }
2018 : }
2019 :
2020 27349307 : if (VECTOR_MODE_P (mode)
2021 1970277 : && GET_CODE (op) == CONST_VECTOR
2022 29081702 : && known_eq (GET_MODE_NUNITS (mode), CONST_VECTOR_NUNITS (op)))
2023 : {
2024 42806 : gcc_assert (GET_MODE (op) == op_mode);
2025 :
2026 42806 : rtx_vector_builder builder;
2027 42806 : if (!builder.new_unary_operation (mode, op, false))
2028 : return 0;
2029 :
2030 42806 : unsigned int count = builder.encoded_nelts ();
2031 170590 : for (unsigned int i = 0; i < count; i++)
2032 : {
2033 256606 : rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
2034 : CONST_VECTOR_ELT (op, i),
2035 256606 : GET_MODE_INNER (op_mode));
2036 128303 : if (!x || !valid_for_const_vector_p (mode, x))
2037 519 : return 0;
2038 127784 : builder.quick_push (x);
2039 : }
2040 42287 : return builder.build ();
2041 42806 : }
2042 :
2043 : /* The order of these tests is critical so that, for example, we don't
2044 : check the wrong mode (input vs. output) for a conversion operation,
2045 : such as FIX. At some point, this should be simplified. */
2046 :
2047 28910478 : if (code == FLOAT && CONST_SCALAR_INT_P (op))
2048 : {
2049 7973 : REAL_VALUE_TYPE d;
2050 :
2051 7973 : if (op_mode == VOIDmode)
2052 : {
2053 : /* CONST_INT have VOIDmode as the mode. We assume that all
2054 : the bits of the constant are significant, though, this is
2055 : a dangerous assumption as many times CONST_INTs are
2056 : created and used with garbage in the bits outside of the
2057 : precision of the implied mode of the const_int. */
2058 64 : op_mode = MAX_MODE_INT;
2059 : }
2060 :
2061 7973 : real_from_integer (&d, mode, rtx_mode_t (op, op_mode), SIGNED);
2062 :
2063 : /* Avoid the folding if flag_signaling_nans is on and
2064 : operand is a signaling NaN. */
2065 7973 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2066 : return 0;
2067 :
2068 7973 : d = real_value_truncate (mode, d);
2069 :
2070 : /* Avoid the folding if flag_rounding_math is on and the
2071 : conversion is not exact. */
2072 7973 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2073 : {
2074 1011 : bool fail = false;
2075 1011 : wide_int w = real_to_integer (&d, &fail,
2076 : GET_MODE_PRECISION
2077 1011 : (as_a <scalar_int_mode> (op_mode)));
2078 2022 : if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
2079 905 : return 0;
2080 1011 : }
2081 :
2082 7068 : return const_double_from_real_value (d, mode);
2083 : }
2084 28902505 : else if (code == UNSIGNED_FLOAT && CONST_SCALAR_INT_P (op))
2085 : {
2086 2134 : REAL_VALUE_TYPE d;
2087 :
2088 2134 : if (op_mode == VOIDmode)
2089 : {
2090 : /* CONST_INT have VOIDmode as the mode. We assume that all
2091 : the bits of the constant are significant, though, this is
2092 : a dangerous assumption as many times CONST_INTs are
2093 : created and used with garbage in the bits outside of the
2094 : precision of the implied mode of the const_int. */
2095 8 : op_mode = MAX_MODE_INT;
2096 : }
2097 :
2098 2134 : real_from_integer (&d, mode, rtx_mode_t (op, op_mode), UNSIGNED);
2099 :
2100 : /* Avoid the folding if flag_signaling_nans is on and
2101 : operand is a signaling NaN. */
2102 2134 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2103 : return 0;
2104 :
2105 2134 : d = real_value_truncate (mode, d);
2106 :
2107 : /* Avoid the folding if flag_rounding_math is on and the
2108 : conversion is not exact. */
2109 2134 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2110 : {
2111 16 : bool fail = false;
2112 16 : wide_int w = real_to_integer (&d, &fail,
2113 : GET_MODE_PRECISION
2114 16 : (as_a <scalar_int_mode> (op_mode)));
2115 28 : if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
2116 16 : return 0;
2117 16 : }
2118 :
2119 2118 : return const_double_from_real_value (d, mode);
2120 : }
2121 :
2122 28900371 : if (CONST_SCALAR_INT_P (op) && is_a <scalar_int_mode> (mode, &result_mode))
2123 : {
2124 3841163 : unsigned int width = GET_MODE_PRECISION (result_mode);
2125 3841163 : if (width > MAX_BITSIZE_MODE_ANY_INT)
2126 : return 0;
2127 :
2128 3841163 : wide_int result;
2129 3841163 : scalar_int_mode imode = (op_mode == VOIDmode
2130 3841163 : ? result_mode
2131 3840882 : : as_a <scalar_int_mode> (op_mode));
2132 3841163 : rtx_mode_t op0 = rtx_mode_t (op, imode);
2133 3841163 : int int_value;
2134 :
2135 : #if TARGET_SUPPORTS_WIDE_INT == 0
2136 : /* This assert keeps the simplification from producing a result
2137 : that cannot be represented in a CONST_DOUBLE but a lot of
2138 : upstream callers expect that this function never fails to
2139 : simplify something and so you if you added this to the test
2140 : above the code would die later anyway. If this assert
2141 : happens, you just need to make the port support wide int. */
2142 : gcc_assert (width <= HOST_BITS_PER_DOUBLE_INT);
2143 : #endif
2144 :
2145 3841163 : switch (code)
2146 : {
2147 173346 : case NOT:
2148 173346 : result = wi::bit_not (op0);
2149 173346 : break;
2150 :
2151 1871821 : case NEG:
2152 1871821 : result = wi::neg (op0);
2153 1871821 : break;
2154 :
2155 7111 : case ABS:
2156 7111 : result = wi::abs (op0);
2157 7111 : break;
2158 :
2159 0 : case FFS:
2160 0 : result = wi::shwi (wi::ffs (op0), result_mode);
2161 0 : break;
2162 :
2163 168 : case CLZ:
2164 168 : if (wi::ne_p (op0, 0))
2165 38 : int_value = wi::clz (op0);
2166 260 : else if (! CLZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2167 : return NULL_RTX;
2168 38 : result = wi::shwi (int_value, result_mode);
2169 38 : break;
2170 :
2171 0 : case CLRSB:
2172 0 : result = wi::shwi (wi::clrsb (op0), result_mode);
2173 0 : break;
2174 :
2175 0 : case CTZ:
2176 0 : if (wi::ne_p (op0, 0))
2177 0 : int_value = wi::ctz (op0);
2178 0 : else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2179 : return NULL_RTX;
2180 0 : result = wi::shwi (int_value, result_mode);
2181 0 : break;
2182 :
2183 160 : case POPCOUNT:
2184 160 : result = wi::shwi (wi::popcount (op0), result_mode);
2185 160 : break;
2186 :
2187 0 : case PARITY:
2188 0 : result = wi::shwi (wi::parity (op0), result_mode);
2189 0 : break;
2190 :
2191 1734 : case BSWAP:
2192 1734 : result = wi::bswap (op0);
2193 1734 : break;
2194 :
2195 0 : case BITREVERSE:
2196 0 : result = wi::bitreverse (op0);
2197 0 : break;
2198 :
2199 1607155 : case TRUNCATE:
2200 1607155 : case ZERO_EXTEND:
2201 1607155 : result = wide_int::from (op0, width, UNSIGNED);
2202 1607155 : break;
2203 :
2204 14450 : case US_TRUNCATE:
2205 14450 : case SS_TRUNCATE:
2206 14450 : {
2207 14450 : signop sgn = code == US_TRUNCATE ? UNSIGNED : SIGNED;
2208 14450 : wide_int nmax
2209 14450 : = wide_int::from (wi::max_value (width, sgn),
2210 28900 : GET_MODE_PRECISION (imode), sgn);
2211 14450 : wide_int nmin
2212 14450 : = wide_int::from (wi::min_value (width, sgn),
2213 28900 : GET_MODE_PRECISION (imode), sgn);
2214 14450 : result = wi::min (wi::max (op0, nmin, sgn), nmax, sgn);
2215 14450 : result = wide_int::from (result, width, sgn);
2216 14450 : break;
2217 14450 : }
2218 165218 : case SIGN_EXTEND:
2219 165218 : result = wide_int::from (op0, width, SIGNED);
2220 165218 : break;
2221 :
2222 0 : case SS_NEG:
2223 0 : if (wi::only_sign_bit_p (op0))
2224 0 : result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
2225 : else
2226 0 : result = wi::neg (op0);
2227 : break;
2228 :
2229 0 : case SS_ABS:
2230 0 : if (wi::only_sign_bit_p (op0))
2231 0 : result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
2232 : else
2233 0 : result = wi::abs (op0);
2234 : break;
2235 :
2236 : case SQRT:
2237 : default:
2238 : return 0;
2239 : }
2240 :
2241 3841033 : return immed_wide_int_const (result, result_mode);
2242 3841163 : }
2243 :
2244 25059208 : else if (CONST_DOUBLE_AS_FLOAT_P (op)
2245 414014 : && SCALAR_FLOAT_MODE_P (mode)
2246 411964 : && SCALAR_FLOAT_MODE_P (GET_MODE (op)))
2247 : {
2248 411964 : REAL_VALUE_TYPE d = *CONST_DOUBLE_REAL_VALUE (op);
2249 411964 : switch (code)
2250 : {
2251 : case SQRT:
2252 : return 0;
2253 838 : case ABS:
2254 838 : d = real_value_abs (&d);
2255 838 : break;
2256 15847 : case NEG:
2257 15847 : d = real_value_negate (&d);
2258 15847 : break;
2259 2284 : case FLOAT_TRUNCATE:
2260 : /* Don't perform the operation if flag_signaling_nans is on
2261 : and the operand is a signaling NaN. */
2262 2284 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2263 : return NULL_RTX;
2264 : /* Or if flag_rounding_math is on and the truncation is not
2265 : exact. */
2266 2284 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2267 2284 : && !exact_real_truncate (mode, &d))
2268 231 : return NULL_RTX;
2269 2053 : d = real_value_truncate (mode, d);
2270 2053 : break;
2271 386352 : case FLOAT_EXTEND:
2272 : /* Don't perform the operation if flag_signaling_nans is on
2273 : and the operand is a signaling NaN. */
2274 386352 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2275 : return NULL_RTX;
2276 : /* All this does is change the mode, unless changing
2277 : mode class. */
2278 386350 : if (GET_MODE_CLASS (mode) != GET_MODE_CLASS (GET_MODE (op)))
2279 0 : real_convert (&d, mode, &d);
2280 : break;
2281 0 : case FIX:
2282 : /* Don't perform the operation if flag_signaling_nans is on
2283 : and the operand is a signaling NaN. */
2284 0 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2285 : return NULL_RTX;
2286 0 : real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
2287 0 : break;
2288 6034 : case NOT:
2289 6034 : {
2290 6034 : long tmp[4];
2291 6034 : int i;
2292 :
2293 6034 : real_to_target (tmp, &d, GET_MODE (op));
2294 30170 : for (i = 0; i < 4; i++)
2295 24136 : tmp[i] = ~tmp[i];
2296 6034 : real_from_target (&d, tmp, mode);
2297 6034 : break;
2298 : }
2299 0 : default:
2300 0 : gcc_unreachable ();
2301 : }
2302 411122 : return const_double_from_real_value (d, mode);
2303 : }
2304 2050 : else if (CONST_DOUBLE_AS_FLOAT_P (op)
2305 2050 : && SCALAR_FLOAT_MODE_P (GET_MODE (op))
2306 24649294 : && is_int_mode (mode, &result_mode))
2307 : {
2308 2050 : unsigned int width = GET_MODE_PRECISION (result_mode);
2309 2050 : if (width > MAX_BITSIZE_MODE_ANY_INT)
2310 : return 0;
2311 :
2312 : /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
2313 : operators are intentionally left unspecified (to ease implementation
2314 : by target backends), for consistency, this routine implements the
2315 : same semantics for constant folding as used by the middle-end. */
2316 :
2317 : /* This was formerly used only for non-IEEE float.
2318 : eggert@twinsun.com says it is safe for IEEE also. */
2319 2050 : REAL_VALUE_TYPE t;
2320 2050 : const REAL_VALUE_TYPE *x = CONST_DOUBLE_REAL_VALUE (op);
2321 2050 : wide_int wmax, wmin;
2322 : /* This is part of the abi to real_to_integer, but we check
2323 : things before making this call. */
2324 2050 : bool fail;
2325 :
2326 2050 : switch (code)
2327 : {
2328 2042 : case FIX:
2329 : /* According to IEEE standard, for conversions from floating point to
2330 : integer. When a NaN or infinite operand cannot be represented in
2331 : the destination format and this cannot otherwise be indicated, the
2332 : invalid operation exception shall be signaled. When a numeric
2333 : operand would convert to an integer outside the range of the
2334 : destination format, the invalid operation exception shall be
2335 : signaled if this situation cannot otherwise be indicated. */
2336 2042 : if (REAL_VALUE_ISNAN (*x))
2337 955 : return flag_trapping_math ? NULL_RTX : const0_rtx;
2338 :
2339 1087 : if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
2340 : return NULL_RTX;
2341 :
2342 : /* Test against the signed upper bound. */
2343 127 : wmax = wi::max_value (width, SIGNED);
2344 127 : real_from_integer (&t, VOIDmode, wmax, SIGNED);
2345 127 : if (real_less (&t, x))
2346 3 : return (flag_trapping_math
2347 3 : ? NULL_RTX : immed_wide_int_const (wmax, mode));
2348 :
2349 : /* Test against the signed lower bound. */
2350 124 : wmin = wi::min_value (width, SIGNED);
2351 124 : real_from_integer (&t, VOIDmode, wmin, SIGNED);
2352 124 : if (real_less (x, &t))
2353 8 : return immed_wide_int_const (wmin, mode);
2354 :
2355 116 : return immed_wide_int_const (real_to_integer (x, &fail, width),
2356 : mode);
2357 :
2358 8 : case UNSIGNED_FIX:
2359 8 : if (REAL_VALUE_ISNAN (*x) || REAL_VALUE_NEGATIVE (*x))
2360 6 : return flag_trapping_math ? NULL_RTX : const0_rtx;
2361 :
2362 2 : if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
2363 : return NULL_RTX;
2364 :
2365 : /* Test against the unsigned upper bound. */
2366 0 : wmax = wi::max_value (width, UNSIGNED);
2367 0 : real_from_integer (&t, VOIDmode, wmax, UNSIGNED);
2368 0 : if (real_less (&t, x))
2369 0 : return (flag_trapping_math
2370 0 : ? NULL_RTX : immed_wide_int_const (wmax, mode));
2371 :
2372 0 : return immed_wide_int_const (real_to_integer (x, &fail, width),
2373 : mode);
2374 :
2375 0 : default:
2376 0 : gcc_unreachable ();
2377 : }
2378 2050 : }
2379 :
2380 : /* Handle polynomial integers. */
2381 : else if (CONST_POLY_INT_P (op))
2382 : {
2383 : poly_wide_int result;
2384 : switch (code)
2385 : {
2386 : case NEG:
2387 : result = -const_poly_int_value (op);
2388 : break;
2389 :
2390 : case NOT:
2391 : result = ~const_poly_int_value (op);
2392 : break;
2393 :
2394 : default:
2395 : return NULL_RTX;
2396 : }
2397 : return immed_wide_int_const (result, mode);
2398 : }
2399 :
2400 : return NULL_RTX;
2401 : }
2402 :
2403 : /* Subroutine of simplify_binary_operation to simplify a binary operation
2404 : CODE that can commute with byte swapping, with result mode MODE and
2405 : operating on OP0 and OP1. CODE is currently one of AND, IOR or XOR.
2406 : Return zero if no simplification or canonicalization is possible. */
2407 :
2408 : rtx
2409 37898169 : simplify_context::simplify_byte_swapping_operation (rtx_code code,
2410 : machine_mode mode,
2411 : rtx op0, rtx op1)
2412 : {
2413 37898169 : rtx tem;
2414 :
2415 : /* (op (bswap x) C1)) -> (bswap (op x C2)) with C2 swapped. */
2416 37898169 : if (GET_CODE (op0) == BSWAP && CONST_SCALAR_INT_P (op1))
2417 : {
2418 227 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0),
2419 : simplify_gen_unary (BSWAP, mode, op1, mode));
2420 227 : return simplify_gen_unary (BSWAP, mode, tem, mode);
2421 : }
2422 :
2423 : /* (op (bswap x) (bswap y)) -> (bswap (op x y)). */
2424 37897942 : if (GET_CODE (op0) == BSWAP && GET_CODE (op1) == BSWAP)
2425 : {
2426 0 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0), XEXP (op1, 0));
2427 0 : return simplify_gen_unary (BSWAP, mode, tem, mode);
2428 : }
2429 :
2430 : return NULL_RTX;
2431 : }
2432 :
2433 : /* Subroutine of simplify_binary_operation to simplify a commutative,
2434 : associative binary operation CODE with result mode MODE, operating
2435 : on OP0 and OP1. CODE is currently one of PLUS, MULT, AND, IOR, XOR,
2436 : SMIN, SMAX, UMIN or UMAX. Return zero if no simplification or
2437 : canonicalization is possible. */
2438 :
2439 : rtx
2440 48908232 : simplify_context::simplify_associative_operation (rtx_code code,
2441 : machine_mode mode,
2442 : rtx op0, rtx op1)
2443 : {
2444 48908232 : rtx tem;
2445 :
2446 : /* Normally expressions simplified by simplify-rtx.cc are combined
2447 : at most from a few machine instructions and therefore the
2448 : expressions should be fairly small. During var-tracking
2449 : we can see arbitrarily large expressions though and reassociating
2450 : those can be quadratic, so punt after encountering max_assoc_count
2451 : simplify_associative_operation calls during outermost simplify_*
2452 : call. */
2453 48908232 : if (++assoc_count >= max_assoc_count)
2454 : return NULL_RTX;
2455 :
2456 : /* Linearize the operator to the left. */
2457 48903161 : if (GET_CODE (op1) == code)
2458 : {
2459 : /* "(a op b) op (c op d)" becomes "((a op b) op c) op d)". */
2460 18199 : if (GET_CODE (op0) == code)
2461 : {
2462 5065 : tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
2463 5065 : return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
2464 : }
2465 :
2466 : /* "a op (b op c)" becomes "(b op c) op a". */
2467 13134 : if (! swap_commutative_operands_p (op1, op0))
2468 13134 : return simplify_gen_binary (code, mode, op1, op0);
2469 :
2470 : std::swap (op0, op1);
2471 : }
2472 :
2473 48884962 : if (GET_CODE (op0) == code)
2474 : {
2475 : /* Canonicalize "(x op c) op y" as "(x op y) op c". */
2476 1238181 : if (swap_commutative_operands_p (XEXP (op0, 1), op1))
2477 : {
2478 266043 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
2479 266043 : return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2480 : }
2481 :
2482 : /* Attempt to simplify "(a op b) op c" as "a op (b op c)". */
2483 972138 : tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
2484 972138 : if (tem != 0)
2485 69917 : return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
2486 :
2487 : /* Attempt to simplify "(a op b) op c" as "(a op c) op b". */
2488 902221 : tem = simplify_binary_operation (code, mode, XEXP (op0, 0), op1);
2489 902221 : if (tem != 0)
2490 37431 : return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2491 : }
2492 :
2493 : return 0;
2494 : }
2495 :
2496 : /* If COMPARISON can be treated as an unsigned comparison, return a mask
2497 : that represents it (8 if it includes <, 4 if it includes > and 2
2498 : if it includes ==). Return 0 otherwise. */
2499 : static int
2500 18610 : unsigned_comparison_to_mask (rtx_code comparison)
2501 : {
2502 0 : switch (comparison)
2503 : {
2504 : case LTU:
2505 : return 8;
2506 : case GTU:
2507 : return 4;
2508 : case EQ:
2509 : return 2;
2510 :
2511 : case LEU:
2512 : return 10;
2513 : case GEU:
2514 : return 6;
2515 :
2516 : case NE:
2517 : return 12;
2518 :
2519 : default:
2520 : return 0;
2521 : }
2522 : }
2523 :
2524 : /* Reverse the mapping in unsigned_comparison_to_mask, going from masks
2525 : to comparisons. */
2526 : static rtx_code
2527 6577 : mask_to_unsigned_comparison (int mask)
2528 : {
2529 6577 : switch (mask)
2530 : {
2531 : case 8:
2532 : return LTU;
2533 160 : case 4:
2534 160 : return GTU;
2535 2562 : case 2:
2536 2562 : return EQ;
2537 :
2538 160 : case 10:
2539 160 : return LEU;
2540 160 : case 6:
2541 160 : return GEU;
2542 :
2543 3375 : case 12:
2544 3375 : return NE;
2545 :
2546 0 : default:
2547 0 : gcc_unreachable ();
2548 : }
2549 : }
2550 :
2551 : /* Return a mask describing the COMPARISON. */
2552 : static int
2553 2448 : comparison_to_mask (enum rtx_code comparison)
2554 : {
2555 2448 : switch (comparison)
2556 : {
2557 : case LT:
2558 : return 8;
2559 400 : case GT:
2560 400 : return 4;
2561 423 : case EQ:
2562 423 : return 2;
2563 23 : case UNORDERED:
2564 23 : return 1;
2565 :
2566 0 : case LTGT:
2567 0 : return 12;
2568 400 : case LE:
2569 400 : return 10;
2570 401 : case GE:
2571 401 : return 6;
2572 0 : case UNLT:
2573 0 : return 9;
2574 0 : case UNGT:
2575 0 : return 5;
2576 0 : case UNEQ:
2577 0 : return 3;
2578 :
2579 0 : case ORDERED:
2580 0 : return 14;
2581 400 : case NE:
2582 400 : return 13;
2583 0 : case UNLE:
2584 0 : return 11;
2585 0 : case UNGE:
2586 0 : return 7;
2587 :
2588 0 : default:
2589 0 : gcc_unreachable ();
2590 : }
2591 : }
2592 :
2593 : /* Return a comparison corresponding to the MASK. */
2594 : static enum rtx_code
2595 984 : mask_to_comparison (int mask)
2596 : {
2597 984 : switch (mask)
2598 : {
2599 : case 8:
2600 : return LT;
2601 : case 4:
2602 : return GT;
2603 : case 2:
2604 : return EQ;
2605 : case 1:
2606 : return UNORDERED;
2607 :
2608 : case 12:
2609 : return LTGT;
2610 : case 10:
2611 : return LE;
2612 : case 6:
2613 : return GE;
2614 : case 9:
2615 : return UNLT;
2616 : case 5:
2617 : return UNGT;
2618 : case 3:
2619 : return UNEQ;
2620 :
2621 : case 14:
2622 : return ORDERED;
2623 : case 13:
2624 : return NE;
2625 : case 11:
2626 : return UNLE;
2627 : case 7:
2628 : return UNGE;
2629 :
2630 0 : default:
2631 0 : gcc_unreachable ();
2632 : }
2633 : }
2634 :
2635 : /* Canonicalize RES, a scalar const0_rtx/const_true_rtx to the right
2636 : false/true value of comparison with MODE where comparison operands
2637 : have CMP_MODE. */
2638 :
2639 : static rtx
2640 785509 : relational_result (machine_mode mode, machine_mode cmp_mode, rtx res)
2641 : {
2642 785509 : if (SCALAR_FLOAT_MODE_P (mode))
2643 : {
2644 168 : if (res == const0_rtx)
2645 164 : return CONST0_RTX (mode);
2646 : #ifdef FLOAT_STORE_FLAG_VALUE
2647 : REAL_VALUE_TYPE val = FLOAT_STORE_FLAG_VALUE (mode);
2648 : return const_double_from_real_value (val, mode);
2649 : #else
2650 : return NULL_RTX;
2651 : #endif
2652 : }
2653 785341 : if (VECTOR_MODE_P (mode))
2654 : {
2655 423 : if (res == const0_rtx)
2656 82 : return CONST0_RTX (mode);
2657 : #ifdef VECTOR_STORE_FLAG_VALUE
2658 341 : rtx val = VECTOR_STORE_FLAG_VALUE (mode);
2659 331 : if (val == NULL_RTX)
2660 : return NULL_RTX;
2661 331 : if (val == const1_rtx)
2662 0 : return CONST1_RTX (mode);
2663 :
2664 331 : return gen_const_vec_duplicate (mode, val);
2665 : #else
2666 : return NULL_RTX;
2667 : #endif
2668 : }
2669 : /* For vector comparison with scalar int result, it is unknown
2670 : if the target means here a comparison into an integral bitmask,
2671 : or comparison where all comparisons true mean const_true_rtx
2672 : whole result, or where any comparisons true mean const_true_rtx
2673 : whole result. For const0_rtx all the cases are the same. */
2674 784918 : if (VECTOR_MODE_P (cmp_mode)
2675 0 : && SCALAR_INT_MODE_P (mode)
2676 0 : && res == const_true_rtx)
2677 0 : return NULL_RTX;
2678 :
2679 : return res;
2680 : }
2681 :
2682 : /* Simplify a logical operation CODE with result mode MODE, operating on OP0
2683 : and OP1, in the case where both are relational operations. Assume that
2684 : OP0 is inverted if INVERT0_P is true.
2685 :
2686 : Return 0 if no such simplification is possible. */
2687 : rtx
2688 13517655 : simplify_context::simplify_logical_relational_operation (rtx_code code,
2689 : machine_mode mode,
2690 : rtx op0, rtx op1,
2691 : bool invert0_p)
2692 : {
2693 13517655 : if (!(COMPARISON_P (op0) && COMPARISON_P (op1)))
2694 : return 0;
2695 :
2696 21440 : if (!(rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2697 9749 : && rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))))
2698 : return 0;
2699 :
2700 9305 : if (side_effects_p (op0))
2701 : return 0;
2702 :
2703 9305 : enum rtx_code code0 = GET_CODE (op0);
2704 9305 : enum rtx_code code1 = GET_CODE (op1);
2705 9305 : machine_mode cmp_mode = GET_MODE (XEXP (op0, 0));
2706 9305 : if (cmp_mode == VOIDmode)
2707 0 : cmp_mode = GET_MODE (XEXP (op0, 1));
2708 :
2709 : /* Assume at first that the comparisons are on integers, and that the
2710 : operands are therefore ordered. */
2711 9305 : int all = 14;
2712 9305 : int mask0 = unsigned_comparison_to_mask (code0);
2713 9305 : int mask1 = unsigned_comparison_to_mask (code1);
2714 18610 : bool unsigned_p = (IN_RANGE (mask0 & 12, 4, 8)
2715 9305 : || IN_RANGE (mask1 & 12, 4, 8));
2716 1224 : if (unsigned_p)
2717 : {
2718 : /* We only reach here when comparing integers. Reject mixtures of signed
2719 : and unsigned comparisons. */
2720 8081 : if (mask0 == 0 || mask1 == 0)
2721 : return 0;
2722 : }
2723 : else
2724 : {
2725 : /* See whether the operands might be unordered. Assume that all
2726 : results are possible for CC modes, and punt later if we don't get an
2727 : always-true or always-false answer. */
2728 1224 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC || HONOR_NANS (cmp_mode))
2729 : all = 15;
2730 1224 : mask0 = comparison_to_mask (code0) & all;
2731 1224 : mask1 = comparison_to_mask (code1) & all;
2732 : }
2733 :
2734 8025 : if (invert0_p)
2735 4522 : mask0 = mask0 ^ all;
2736 :
2737 8025 : int mask;
2738 8025 : if (code == AND)
2739 928 : mask = mask0 & mask1;
2740 7097 : else if (code == IOR)
2741 952 : mask = mask0 | mask1;
2742 6145 : else if (code == XOR)
2743 6145 : mask = mask0 ^ mask1;
2744 : else
2745 : return 0;
2746 :
2747 8025 : if (mask == all)
2748 232 : return relational_result (mode, GET_MODE (op0), const_true_rtx);
2749 :
2750 7793 : if (mask == 0)
2751 232 : return relational_result (mode, GET_MODE (op0), const0_rtx);
2752 :
2753 7561 : if (unsigned_p)
2754 6577 : code = mask_to_unsigned_comparison (mask);
2755 : else
2756 : {
2757 984 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
2758 : return 0;
2759 :
2760 984 : code = mask_to_comparison (mask);
2761 : /* LTGT and NE are arithmetically equivalent for ordered operands,
2762 : with NE being the canonical choice. */
2763 984 : if (code == LTGT && all == 14)
2764 160 : code = NE;
2765 : }
2766 :
2767 7561 : op0 = XEXP (op1, 0);
2768 7561 : op1 = XEXP (op1, 1);
2769 :
2770 7561 : return simplify_gen_relational (code, mode, VOIDmode, op0, op1);
2771 : }
2772 :
2773 : /* We are going to IOR together OP0/OP1. If there is a common term in OP0/OP1
2774 : then we may be able to simplify the expression. We're primarily trying to
2775 : simplify down to IOR/XOR expression right now, but there may be other
2776 : simplifications we can do in the future.
2777 :
2778 : Return the simplified expression or NULL_RTX if no simplification was
2779 : possible. */
2780 : rtx
2781 27535972 : simplify_context::simplify_ior_with_common_term (machine_mode mode, rtx op0, rtx op1)
2782 : {
2783 : /* (ior X (plus/xor X C)) can be simplified into (ior X C) when
2784 : X and C have no bits in common. */
2785 27535972 : if ((GET_CODE (op1) == PLUS || GET_CODE (op1) == XOR)
2786 254466 : && rtx_equal_p (op0, XEXP (op1, 0))
2787 8336 : && ((nonzero_bits (op0, GET_MODE (op0))
2788 8336 : & nonzero_bits (XEXP (op1, 1), GET_MODE (op1))) == 0)
2789 27535972 : && !side_effects_p (op1))
2790 0 : return simplify_gen_binary (IOR, mode, op0, XEXP (op1, 1));
2791 :
2792 : /* (ior (and A C1) (and (not A) C2)) can be converted
2793 : into (and (xor A C2) (C1 + C2)) when there are no bits
2794 : in common between C1 and C2. */
2795 27535972 : if (GET_CODE (op0) == AND
2796 4376002 : && GET_CODE (op1) == AND
2797 414936 : && GET_CODE (XEXP (op1, 0)) == NOT
2798 20188 : && rtx_equal_p (XEXP (op0, 0), XEXP (XEXP (op1, 0), 0))
2799 3620 : && CONST_INT_P (XEXP (op0, 1))
2800 90 : && CONST_INT_P (XEXP (op1, 1))
2801 27536062 : && (INTVAL (XEXP (op0, 1)) & INTVAL (XEXP (op1, 1))) == 0)
2802 : {
2803 90 : rtx c = GEN_INT (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1)));
2804 :
2805 90 : rtx tem = simplify_gen_binary (XOR, mode, XEXP (op0, 0), XEXP (op1, 1));
2806 90 : if (tem)
2807 : {
2808 90 : tem = simplify_gen_binary (AND, mode, tem, c);
2809 :
2810 90 : if (tem)
2811 : return tem;
2812 : }
2813 : }
2814 :
2815 : /* Another variant seen on some target particularly those with
2816 : sub-word operations.
2817 :
2818 : (ior (and A C1) (plus (and A C2) C2)) can be simplified into
2819 : (and (xor (A C2) (C1 + C2).
2820 :
2821 : Where C2 is the sign bit for A's mode. So 0x80 for QI,
2822 : 0x8000 for HI, etc. In this case we know there is no carry
2823 : from the PLUS into relevant bits of the output. */
2824 27535882 : if (GET_CODE (op0) == AND
2825 4375912 : && GET_CODE (op1) == PLUS
2826 8018 : && GET_CODE (XEXP (op1, 0)) == AND
2827 330 : && rtx_equal_p (XEXP (op0, 0), XEXP (XEXP (op1, 0), 0))
2828 144 : && CONST_INT_P (XEXP (op0, 1))
2829 144 : && CONST_INT_P (XEXP (op1, 1))
2830 144 : && CONST_INT_P (XEXP (XEXP (op1, 0), 1))
2831 144 : && INTVAL (XEXP (op1, 1)) == INTVAL (XEXP (XEXP (op1, 0), 1))
2832 36 : && GET_MODE_BITSIZE (GET_MODE (op1)).is_constant ()
2833 72 : && ((INTVAL (XEXP (op1, 1)) & GET_MODE_MASK (GET_MODE (op1)))
2834 72 : == HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (GET_MODE (op1)).to_constant () - 1))
2835 27535882 : && (INTVAL (XEXP (op0, 1)) & INTVAL (XEXP (op1, 1))) == 0)
2836 : {
2837 0 : rtx c = GEN_INT (INTVAL (XEXP (op0, 1)) + INTVAL (XEXP (op1, 1)));
2838 :
2839 0 : rtx tem = simplify_gen_binary (XOR, mode, XEXP (op0, 0), XEXP (op1, 1));
2840 0 : if (tem)
2841 : {
2842 0 : tem = simplify_gen_binary (AND, mode, tem, c);
2843 0 : if (tem)
2844 : return tem;
2845 : }
2846 : }
2847 : return NULL_RTX;
2848 : }
2849 :
2850 :
2851 : /* Simplify a binary operation CODE with result mode MODE, operating on OP0
2852 : and OP1. Return 0 if no simplification is possible.
2853 :
2854 : Don't use this for relational operations such as EQ or LT.
2855 : Use simplify_relational_operation instead. */
2856 : rtx
2857 496244047 : simplify_context::simplify_binary_operation (rtx_code code, machine_mode mode,
2858 : rtx op0, rtx op1)
2859 : {
2860 496244047 : rtx trueop0, trueop1;
2861 496244047 : rtx tem;
2862 :
2863 : /* Relational operations don't work here. We must know the mode
2864 : of the operands in order to do the comparison correctly.
2865 : Assuming a full word can give incorrect results.
2866 : Consider comparing 128 with -128 in QImode. */
2867 496244047 : gcc_assert (GET_RTX_CLASS (code) != RTX_COMPARE);
2868 496244047 : gcc_assert (GET_RTX_CLASS (code) != RTX_COMM_COMPARE);
2869 :
2870 : /* Make sure the constant is second. */
2871 496244047 : if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
2872 496244047 : && swap_commutative_operands_p (op0, op1))
2873 : std::swap (op0, op1);
2874 :
2875 496244047 : trueop0 = avoid_constant_pool_reference (op0);
2876 496244047 : trueop1 = avoid_constant_pool_reference (op1);
2877 :
2878 496244047 : tem = simplify_const_binary_operation (code, mode, trueop0, trueop1);
2879 496244047 : if (tem)
2880 : return tem;
2881 465407793 : tem = simplify_binary_operation_1 (code, mode, op0, op1, trueop0, trueop1);
2882 :
2883 465407793 : if (tem)
2884 : return tem;
2885 :
2886 : /* If the above steps did not result in a simplification and op0 or op1
2887 : were constant pool references, use the referenced constants directly. */
2888 400360600 : if (trueop0 != op0 || trueop1 != op1)
2889 585218 : return simplify_gen_binary (code, mode, trueop0, trueop1);
2890 :
2891 : return NULL_RTX;
2892 : }
2893 :
2894 : /* Subroutine of simplify_binary_operation_1 that looks for cases in
2895 : which OP0 and OP1 are both vector series or vector duplicates
2896 : (which are really just series with a step of 0). If so, try to
2897 : form a new series by applying CODE to the bases and to the steps.
2898 : Return null if no simplification is possible.
2899 :
2900 : MODE is the mode of the operation and is known to be a vector
2901 : integer mode. */
2902 :
2903 : rtx
2904 2670455 : simplify_context::simplify_binary_operation_series (rtx_code code,
2905 : machine_mode mode,
2906 : rtx op0, rtx op1)
2907 : {
2908 2670455 : rtx base0, step0;
2909 2670455 : if (vec_duplicate_p (op0, &base0))
2910 77774 : step0 = const0_rtx;
2911 2592681 : else if (!vec_series_p (op0, &base0, &step0))
2912 : return NULL_RTX;
2913 :
2914 78518 : rtx base1, step1;
2915 78518 : if (vec_duplicate_p (op1, &base1))
2916 435 : step1 = const0_rtx;
2917 78083 : else if (!vec_series_p (op1, &base1, &step1))
2918 : return NULL_RTX;
2919 :
2920 : /* Only create a new series if we can simplify both parts. In other
2921 : cases this isn't really a simplification, and it's not necessarily
2922 : a win to replace a vector operation with a scalar operation. */
2923 5735 : scalar_mode inner_mode = GET_MODE_INNER (mode);
2924 5735 : rtx new_base = simplify_binary_operation (code, inner_mode, base0, base1);
2925 5735 : if (!new_base)
2926 : return NULL_RTX;
2927 :
2928 4757 : rtx new_step = simplify_binary_operation (code, inner_mode, step0, step1);
2929 4757 : if (!new_step)
2930 : return NULL_RTX;
2931 :
2932 4757 : return gen_vec_series (mode, new_base, new_step);
2933 : }
2934 :
2935 : /* Subroutine of simplify_binary_operation_1. Un-distribute a binary
2936 : operation CODE with result mode MODE, operating on OP0 and OP1.
2937 : e.g. simplify (xor (and A C) (and (B C)) to (and (xor (A B) C).
2938 : Returns NULL_RTX if no simplification is possible. */
2939 :
2940 : rtx
2941 1407709 : simplify_context::simplify_distributive_operation (rtx_code code,
2942 : machine_mode mode,
2943 : rtx op0, rtx op1)
2944 : {
2945 1407709 : enum rtx_code op = GET_CODE (op0);
2946 1407709 : gcc_assert (GET_CODE (op1) == op);
2947 :
2948 1407709 : if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))
2949 1407709 : && ! side_effects_p (XEXP (op0, 1)))
2950 349393 : return simplify_gen_binary (op, mode,
2951 : simplify_gen_binary (code, mode,
2952 : XEXP (op0, 0),
2953 : XEXP (op1, 0)),
2954 349393 : XEXP (op0, 1));
2955 :
2956 1058316 : if (GET_RTX_CLASS (op) == RTX_COMM_ARITH)
2957 : {
2958 1039784 : if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2959 1039784 : && ! side_effects_p (XEXP (op0, 0)))
2960 516376 : return simplify_gen_binary (op, mode,
2961 : simplify_gen_binary (code, mode,
2962 : XEXP (op0, 1),
2963 : XEXP (op1, 1)),
2964 516376 : XEXP (op0, 0));
2965 523408 : if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 1))
2966 523408 : && ! side_effects_p (XEXP (op0, 0)))
2967 54 : return simplify_gen_binary (op, mode,
2968 : simplify_gen_binary (code, mode,
2969 : XEXP (op0, 1),
2970 : XEXP (op1, 0)),
2971 54 : XEXP (op0, 0));
2972 523354 : if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 0))
2973 523354 : && ! side_effects_p (XEXP (op0, 1)))
2974 263913 : return simplify_gen_binary (op, mode,
2975 : simplify_gen_binary (code, mode,
2976 : XEXP (op0, 0),
2977 : XEXP (op1, 1)),
2978 263913 : XEXP (op0, 1));
2979 : }
2980 :
2981 : return NULL_RTX;
2982 : }
2983 :
2984 : /* Return TRUE if a rotate in mode MODE with a constant count in OP1
2985 : should be reversed.
2986 :
2987 : If the rotate should not be reversed, return FALSE.
2988 :
2989 : LEFT indicates if this is a rotate left or a rotate right. */
2990 :
2991 : bool
2992 149596 : reverse_rotate_by_imm_p (machine_mode mode, unsigned int left, rtx op1)
2993 : {
2994 149596 : if (!CONST_INT_P (op1))
2995 : return false;
2996 :
2997 : /* Some targets may only be able to rotate by a constant
2998 : in one direction. So we need to query the optab interface
2999 : to see what is possible. */
3000 112354 : optab binoptab = left ? rotl_optab : rotr_optab;
3001 48306 : optab re_binoptab = left ? rotr_optab : rotl_optab;
3002 112354 : enum insn_code icode = optab_handler (binoptab, mode);
3003 112354 : enum insn_code re_icode = optab_handler (re_binoptab, mode);
3004 :
3005 : /* If the target can not support the reversed optab, then there
3006 : is nothing to do. */
3007 112354 : if (re_icode == CODE_FOR_nothing)
3008 : return false;
3009 :
3010 : /* If the target does not support the requested rotate-by-immediate,
3011 : then we want to try reversing the rotate. We also want to try
3012 : reversing to minimize the count. */
3013 109872 : if ((icode == CODE_FOR_nothing)
3014 109872 : || (!insn_operand_matches (icode, 2, op1))
3015 549360 : || (IN_RANGE (INTVAL (op1),
3016 : GET_MODE_UNIT_PRECISION (mode) / 2 + left,
3017 : GET_MODE_UNIT_PRECISION (mode) - 1)))
3018 15463 : return (insn_operand_matches (re_icode, 2, op1));
3019 : return false;
3020 : }
3021 :
3022 : /* Analyse argument X to see if it represents an (ASHIFT X Y) operation
3023 : and return the expression to be shifted in SHIFT_OPND and the shift amount
3024 : in SHIFT_AMNT. This is primarily used to group handling of ASHIFT (X, CST)
3025 : and (PLUS (X, X)) in one place. If the expression is not equivalent to an
3026 : ASHIFT then return FALSE and set SHIFT_OPND and SHIFT_AMNT to NULL. */
3027 :
3028 : static bool
3029 548024490 : extract_ashift_operands_p (rtx x, rtx *shift_opnd, rtx *shift_amnt)
3030 : {
3031 548024490 : if (GET_CODE (x) == ASHIFT)
3032 : {
3033 14026052 : *shift_opnd = XEXP (x, 0);
3034 14026052 : *shift_amnt = XEXP (x, 1);
3035 14026052 : return true;
3036 : }
3037 533998438 : if (GET_CODE (x) == PLUS && rtx_equal_p (XEXP (x, 0), XEXP (x, 1)))
3038 : {
3039 11581 : *shift_opnd = XEXP (x, 0);
3040 11581 : *shift_amnt = CONST1_RTX (GET_MODE (x));
3041 11581 : return true;
3042 : }
3043 533986857 : *shift_opnd = NULL_RTX;
3044 533986857 : *shift_amnt = NULL_RTX;
3045 533986857 : return false;
3046 : }
3047 :
3048 : /* OP0 and OP1 are combined under an operation of mode MODE that can
3049 : potentially result in a ROTATE expression. Analyze the OP0 and OP1
3050 : and return the resulting ROTATE expression if so. Return NULL otherwise.
3051 : This is used in detecting the patterns (X << C1) [+,|,^] (X >> C2) where
3052 : C1 + C2 == GET_MODE_UNIT_PRECISION (mode).
3053 : (X << C1) and (C >> C2) would be OP0 and OP1. */
3054 :
3055 : static rtx
3056 276896826 : simplify_rotate_op (rtx op0, rtx op1, machine_mode mode)
3057 : {
3058 : /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3059 : mode size to (rotate A CX). */
3060 :
3061 276896826 : rtx opleft = op0;
3062 276896826 : rtx opright = op1;
3063 276896826 : rtx ashift_opnd, ashift_amnt;
3064 : /* In some cases the ASHIFT is not a direct ASHIFT. Look deeper and extract
3065 : the relevant operands here. */
3066 276896826 : bool ashift_op_p
3067 276896826 : = extract_ashift_operands_p (op1, &ashift_opnd, &ashift_amnt);
3068 :
3069 276896826 : if (ashift_op_p
3070 275117518 : || GET_CODE (op1) == SUBREG)
3071 : {
3072 : opleft = op1;
3073 : opright = op0;
3074 : }
3075 : else
3076 : {
3077 271127664 : opright = op1;
3078 271127664 : opleft = op0;
3079 271127664 : ashift_op_p
3080 271127664 : = extract_ashift_operands_p (opleft, &ashift_opnd, &ashift_amnt);
3081 : }
3082 :
3083 14037633 : if (ashift_op_p && GET_CODE (opright) == LSHIFTRT
3084 275189254 : && rtx_equal_p (ashift_opnd, XEXP (opright, 0)))
3085 : {
3086 9586 : rtx leftcst = unwrap_const_vec_duplicate (ashift_amnt);
3087 9586 : rtx rightcst = unwrap_const_vec_duplicate (XEXP (opright, 1));
3088 :
3089 5754 : if (CONST_INT_P (leftcst) && CONST_INT_P (rightcst)
3090 15340 : && (INTVAL (leftcst) + INTVAL (rightcst)
3091 5754 : == GET_MODE_UNIT_PRECISION (mode)))
3092 5095 : return gen_rtx_ROTATE (mode, XEXP (opright, 0), ashift_amnt);
3093 : }
3094 :
3095 : /* Same, but for ashift that has been "simplified" to a wider mode
3096 : by simplify_shift_const. */
3097 276891731 : scalar_int_mode int_mode, inner_mode;
3098 :
3099 276891731 : if (GET_CODE (opleft) == SUBREG
3100 282562389 : && is_a <scalar_int_mode> (mode, &int_mode)
3101 5665563 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (opleft)),
3102 : &inner_mode)
3103 5626554 : && GET_CODE (SUBREG_REG (opleft)) == ASHIFT
3104 190952 : && GET_CODE (opright) == LSHIFTRT
3105 874 : && GET_CODE (XEXP (opright, 0)) == SUBREG
3106 238 : && known_eq (SUBREG_BYTE (opleft), SUBREG_BYTE (XEXP (opright, 0)))
3107 472 : && GET_MODE_SIZE (int_mode) < GET_MODE_SIZE (inner_mode)
3108 229 : && rtx_equal_p (XEXP (SUBREG_REG (opleft), 0),
3109 229 : SUBREG_REG (XEXP (opright, 0)))
3110 13 : && CONST_INT_P (XEXP (SUBREG_REG (opleft), 1))
3111 13 : && CONST_INT_P (XEXP (opright, 1))
3112 276891731 : && (INTVAL (XEXP (SUBREG_REG (opleft), 1))
3113 13 : + INTVAL (XEXP (opright, 1))
3114 13 : == GET_MODE_PRECISION (int_mode)))
3115 1 : return gen_rtx_ROTATE (int_mode, XEXP (opright, 0),
3116 : XEXP (SUBREG_REG (opleft), 1));
3117 : return NULL_RTX;
3118 : }
3119 :
3120 : /* Returns true if OP0 and OP1 match the pattern (OP (plus (A - 1)) (neg A)),
3121 : and the pattern can be simplified (there are no side effects). */
3122 :
3123 : static bool
3124 39885132 : match_plus_neg_pattern (rtx op0, rtx op1, machine_mode mode)
3125 : {
3126 : /* Remove SUBREG from OP0 and OP1, if needed. */
3127 39885132 : if (GET_CODE (op0) == SUBREG
3128 7173060 : && GET_CODE (op1) == SUBREG
3129 301531 : && subreg_lowpart_p (op0)
3130 40186002 : && subreg_lowpart_p (op1))
3131 : {
3132 300861 : op0 = XEXP (op0, 0);
3133 300861 : op1 = XEXP (op1, 0);
3134 : }
3135 :
3136 : /* Check for the pattern (OP (plus (A - 1)) (neg A)). */
3137 39885132 : if (((GET_CODE (op1) == NEG
3138 3888 : && GET_CODE (op0) == PLUS
3139 2132 : && XEXP (op0, 1) == CONSTM1_RTX (mode))
3140 39884446 : || (GET_CODE (op0) == NEG
3141 78040 : && GET_CODE (op1) == PLUS
3142 0 : && XEXP (op1, 1) == CONSTM1_RTX (mode)))
3143 686 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3144 39885134 : && !side_effects_p (XEXP (op0, 0)))
3145 2 : return true;
3146 : return false;
3147 : }
3148 :
3149 : /* Check if OP matches the pattern of (subreg (not X)) and the subreg is
3150 : non-paradoxical. */
3151 :
3152 : static bool
3153 75798732 : non_paradoxical_subreg_not_p (rtx op)
3154 : {
3155 75798732 : return GET_CODE (op) == SUBREG
3156 8730961 : && !paradoxical_subreg_p (op)
3157 78609679 : && GET_CODE (SUBREG_REG (op)) == NOT;
3158 : }
3159 :
3160 : /* Convert (binop (subreg (not X)) Y) into (binop (not (subreg X)) Y), or
3161 : (binop X (subreg (not Y))) into (binop X (not (subreg Y))) to expose
3162 : opportunities to combine another binary logical operation with NOT. */
3163 :
3164 : static rtx
3165 37900592 : simplify_with_subreg_not (rtx_code binop, machine_mode mode, rtx op0, rtx op1)
3166 : {
3167 37900592 : rtx opn = NULL_RTX;
3168 37900592 : if (non_paradoxical_subreg_not_p (op0))
3169 : opn = op0;
3170 37898140 : else if (non_paradoxical_subreg_not_p (op1))
3171 : opn = op1;
3172 :
3173 2475 : if (opn == NULL_RTX)
3174 : return NULL_RTX;
3175 :
3176 4950 : rtx new_subreg = simplify_gen_subreg (mode,
3177 : XEXP (SUBREG_REG (opn), 0),
3178 2475 : GET_MODE (SUBREG_REG (opn)),
3179 2475 : SUBREG_BYTE (opn));
3180 :
3181 2475 : if (!new_subreg)
3182 : return NULL_RTX;
3183 :
3184 2423 : rtx new_not = simplify_gen_unary (NOT, mode, new_subreg, mode);
3185 2423 : if (opn == op0)
3186 2400 : return simplify_gen_binary (binop, mode, new_not, op1);
3187 : else
3188 23 : return simplify_gen_binary (binop, mode, op0, new_not);
3189 : }
3190 :
3191 : /* Return TRUE iff NOP is a negated form of OP, or vice-versa. */
3192 : static bool
3193 7196745 : negated_ops_p (rtx nop, rtx op)
3194 : {
3195 : /* Explicit negation. */
3196 7196745 : if (GET_CODE (nop) == NOT
3197 7196745 : && rtx_equal_p (XEXP (nop, 0), op))
3198 : return true;
3199 7193385 : if (GET_CODE (op) == NOT
3200 7193385 : && rtx_equal_p (XEXP (op, 0), nop))
3201 : return true;
3202 :
3203 : /* (~C <r A) is a negated form of (C << A) if C == 1. */
3204 7190213 : if (GET_CODE (op) == ASHIFT
3205 1483770 : && GET_CODE (nop) == ROTATE
3206 0 : && XEXP (op, 0) == CONST1_RTX (GET_MODE (op))
3207 0 : && CONST_INT_P (XEXP (nop, 0))
3208 0 : && INTVAL (XEXP (nop, 0)) == -2
3209 7190213 : && rtx_equal_p (XEXP (op, 1), XEXP (nop, 1)))
3210 : return true;
3211 7190213 : if (GET_CODE (nop) == ASHIFT
3212 153898 : && GET_CODE (op) == ROTATE
3213 0 : && XEXP (nop, 0) == CONST1_RTX (GET_MODE (op))
3214 0 : && CONST_INT_P (XEXP (nop, 0))
3215 0 : && INTVAL (XEXP (nop, 0)) == -2
3216 7190213 : && rtx_equal_p (XEXP (op, 1), XEXP (nop, 1)))
3217 : return true;
3218 :
3219 : /* ??? Should we consider rotations of C and ~C by the same amount? */
3220 :
3221 : return false;
3222 : }
3223 :
3224 : /* Subroutine of simplify_binary_operation. Simplify a binary operation
3225 : CODE with result mode MODE, operating on OP0 and OP1. If OP0 and/or
3226 : OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the
3227 : actual constants. */
3228 :
3229 : rtx
3230 465407793 : simplify_context::simplify_binary_operation_1 (rtx_code code,
3231 : machine_mode mode,
3232 : rtx op0, rtx op1,
3233 : rtx trueop0, rtx trueop1)
3234 : {
3235 465407793 : rtx tem, reversed, elt0, elt1;
3236 465407793 : HOST_WIDE_INT val;
3237 465407793 : scalar_int_mode int_mode, inner_mode;
3238 465407793 : poly_int64 offset;
3239 :
3240 : /* Even if we can't compute a constant result,
3241 : there are some cases worth simplifying. */
3242 :
3243 465407793 : switch (code)
3244 : {
3245 266656530 : case PLUS:
3246 : /* Maybe simplify x + 0 to x. The two expressions are equivalent
3247 : when x is NaN, infinite, or finite and nonzero. They aren't
3248 : when x is -0 and the rounding mode is not towards -infinity,
3249 : since (-0) + 0 is then 0. */
3250 529409576 : if (!HONOR_SIGNED_ZEROS (mode) && !HONOR_SNANS (mode)
3251 529409564 : && trueop1 == CONST0_RTX (mode))
3252 : return op0;
3253 :
3254 : /* ((-a) + b) -> (b - a) and similarly for (a + (-b)). These
3255 : transformations are safe even for IEEE. */
3256 265034864 : if (GET_CODE (op0) == NEG)
3257 64401 : return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
3258 264970463 : else if (GET_CODE (op1) == NEG)
3259 8568 : return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
3260 :
3261 : /* (~a) + 1 -> -a */
3262 264961895 : if (INTEGRAL_MODE_P (mode)
3263 260148152 : && GET_CODE (op0) == NOT
3264 1385731 : && trueop1 == const1_rtx)
3265 3925 : return simplify_gen_unary (NEG, mode, XEXP (op0, 0), mode);
3266 :
3267 : /* Handle both-operands-constant cases. We can only add
3268 : CONST_INTs to constants since the sum of relocatable symbols
3269 : can't be handled by most assemblers. Don't add CONST_INT
3270 : to CONST_INT since overflow won't be computed properly if wider
3271 : than HOST_BITS_PER_WIDE_INT. */
3272 :
3273 264957970 : if ((GET_CODE (op0) == CONST
3274 264957970 : || GET_CODE (op0) == SYMBOL_REF
3275 262338294 : || GET_CODE (op0) == LABEL_REF)
3276 264957970 : && poly_int_rtx_p (op1, &offset))
3277 2618711 : return plus_constant (mode, op0, offset);
3278 262339259 : else if ((GET_CODE (op1) == CONST
3279 262339259 : || GET_CODE (op1) == SYMBOL_REF
3280 258163342 : || GET_CODE (op1) == LABEL_REF)
3281 262339259 : && poly_int_rtx_p (op0, &offset))
3282 0 : return plus_constant (mode, op1, offset);
3283 :
3284 : /* See if this is something like X * C - X or vice versa or
3285 : if the multiplication is written as a shift. If so, we can
3286 : distribute and make a new multiply, shift, or maybe just
3287 : have X (if C is 2 in the example above). But don't make
3288 : something more expensive than we had before. */
3289 :
3290 262339259 : if (is_a <scalar_int_mode> (mode, &int_mode))
3291 : {
3292 255221835 : rtx lhs = op0, rhs = op1;
3293 :
3294 255221835 : wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
3295 255221835 : wide_int coeff1 = wi::one (GET_MODE_PRECISION (int_mode));
3296 :
3297 255221835 : if (GET_CODE (lhs) == NEG)
3298 : {
3299 0 : coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3300 0 : lhs = XEXP (lhs, 0);
3301 : }
3302 255221835 : else if (GET_CODE (lhs) == MULT
3303 9581051 : && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
3304 : {
3305 8251665 : coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
3306 8251665 : lhs = XEXP (lhs, 0);
3307 : }
3308 246970170 : else if (GET_CODE (lhs) == ASHIFT
3309 11110337 : && CONST_INT_P (XEXP (lhs, 1))
3310 11037812 : && INTVAL (XEXP (lhs, 1)) >= 0
3311 258007970 : && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
3312 : {
3313 11037800 : coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
3314 22075600 : GET_MODE_PRECISION (int_mode));
3315 11037800 : lhs = XEXP (lhs, 0);
3316 : }
3317 :
3318 255221835 : if (GET_CODE (rhs) == NEG)
3319 : {
3320 0 : coeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3321 0 : rhs = XEXP (rhs, 0);
3322 : }
3323 255221835 : else if (GET_CODE (rhs) == MULT
3324 353268 : && CONST_INT_P (XEXP (rhs, 1)))
3325 : {
3326 195758 : coeff1 = rtx_mode_t (XEXP (rhs, 1), int_mode);
3327 195758 : rhs = XEXP (rhs, 0);
3328 : }
3329 255026077 : else if (GET_CODE (rhs) == ASHIFT
3330 626414 : && CONST_INT_P (XEXP (rhs, 1))
3331 616577 : && INTVAL (XEXP (rhs, 1)) >= 0
3332 255642654 : && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
3333 : {
3334 616577 : coeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
3335 1233154 : GET_MODE_PRECISION (int_mode));
3336 616577 : rhs = XEXP (rhs, 0);
3337 : }
3338 :
3339 : /* Don't merge operands that have side effects. */
3340 255221835 : if (rtx_equal_p (lhs, rhs) && !side_effects_p (lhs))
3341 : {
3342 850278 : rtx orig = gen_rtx_PLUS (int_mode, op0, op1);
3343 850278 : rtx coeff;
3344 850278 : bool speed = optimize_function_for_speed_p (cfun);
3345 :
3346 850278 : coeff = immed_wide_int_const (coeff0 + coeff1, int_mode);
3347 :
3348 850278 : tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
3349 850278 : return (set_src_cost (tem, int_mode, speed)
3350 850278 : <= set_src_cost (orig, int_mode, speed) ? tem : 0);
3351 : }
3352 :
3353 : /* Optimize (X - 1) * Y + Y to X * Y. */
3354 254371557 : lhs = op0;
3355 254371557 : rhs = op1;
3356 254371557 : if (GET_CODE (op0) == MULT)
3357 : {
3358 9529518 : if (((GET_CODE (XEXP (op0, 0)) == PLUS
3359 631316 : && XEXP (XEXP (op0, 0), 1) == constm1_rtx)
3360 9476123 : || (GET_CODE (XEXP (op0, 0)) == MINUS
3361 51304 : && XEXP (XEXP (op0, 0), 1) == const1_rtx))
3362 9582913 : && rtx_equal_p (XEXP (op0, 1), op1))
3363 85 : lhs = XEXP (XEXP (op0, 0), 0);
3364 9529433 : else if (((GET_CODE (XEXP (op0, 1)) == PLUS
3365 1680 : && XEXP (XEXP (op0, 1), 1) == constm1_rtx)
3366 9529357 : || (GET_CODE (XEXP (op0, 1)) == MINUS
3367 502 : && XEXP (XEXP (op0, 1), 1) == const1_rtx))
3368 9529509 : && rtx_equal_p (XEXP (op0, 0), op1))
3369 0 : lhs = XEXP (XEXP (op0, 1), 0);
3370 : }
3371 244842039 : else if (GET_CODE (op1) == MULT)
3372 : {
3373 128138 : if (((GET_CODE (XEXP (op1, 0)) == PLUS
3374 99 : && XEXP (XEXP (op1, 0), 1) == constm1_rtx)
3375 128130 : || (GET_CODE (XEXP (op1, 0)) == MINUS
3376 23 : && XEXP (XEXP (op1, 0), 1) == const1_rtx))
3377 128146 : && rtx_equal_p (XEXP (op1, 1), op0))
3378 0 : rhs = XEXP (XEXP (op1, 0), 0);
3379 128138 : else if (((GET_CODE (XEXP (op1, 1)) == PLUS
3380 45 : && XEXP (XEXP (op1, 1), 1) == constm1_rtx)
3381 128138 : || (GET_CODE (XEXP (op1, 1)) == MINUS
3382 4 : && XEXP (XEXP (op1, 1), 1) == const1_rtx))
3383 128138 : && rtx_equal_p (XEXP (op1, 0), op0))
3384 0 : rhs = XEXP (XEXP (op1, 1), 0);
3385 : }
3386 85 : if ((lhs != op0 && !side_effects_p (op1))
3387 254371558 : || (rhs != op1 && !side_effects_p (op0)))
3388 84 : return simplify_gen_binary (MULT, int_mode, lhs, rhs);
3389 255221835 : }
3390 :
3391 : /* (plus (xor X C1) C2) is (xor X (C1^C2)) if C2 is signbit. */
3392 261488897 : if (CONST_SCALAR_INT_P (op1)
3393 198956508 : && GET_CODE (op0) == XOR
3394 18625 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
3395 261498624 : && mode_signbit_p (mode, op1))
3396 121 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3397 : simplify_gen_binary (XOR, mode, op1,
3398 121 : XEXP (op0, 1)));
3399 :
3400 : /* (plus (xor X C1) C2) is (xor X (C1^C2)) if X is either 0 or 1 and
3401 : 2 * ((X ^ C1) & C2) == 0; based on A + B == A ^ B + 2 * (A & B). */
3402 261488776 : if (CONST_SCALAR_INT_P (op1)
3403 198956387 : && GET_CODE (op0) == XOR
3404 18504 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
3405 9606 : && nonzero_bits (XEXP (op0, 0), mode) == 1
3406 341 : && 2 * (INTVAL (XEXP (op0, 1)) & INTVAL (op1)) == 0
3407 261488776 : && 2 * ((1 ^ INTVAL (XEXP (op0, 1))) & INTVAL (op1)) == 0)
3408 0 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3409 : simplify_gen_binary (XOR, mode, op1,
3410 0 : XEXP (op0, 1)));
3411 :
3412 : /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)). */
3413 261488776 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3414 261486248 : && GET_CODE (op0) == MULT
3415 271401455 : && GET_CODE (XEXP (op0, 0)) == NEG)
3416 : {
3417 4085 : rtx in1, in2;
3418 :
3419 4085 : in1 = XEXP (XEXP (op0, 0), 0);
3420 4085 : in2 = XEXP (op0, 1);
3421 4085 : return simplify_gen_binary (MINUS, mode, op1,
3422 : simplify_gen_binary (MULT, mode,
3423 4085 : in1, in2));
3424 : }
3425 :
3426 : /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
3427 : C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
3428 : is 1. */
3429 261484691 : if (COMPARISON_P (op0)
3430 1298206 : && ((STORE_FLAG_VALUE == -1 && trueop1 == const1_rtx)
3431 1298206 : || (STORE_FLAG_VALUE == 1 && trueop1 == constm1_rtx))
3432 261542076 : && (reversed = reversed_comparison (op0, mode)))
3433 57028 : return
3434 57028 : simplify_gen_unary (NEG, mode, reversed, mode);
3435 :
3436 : /* Convert (plus (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3437 : mode size to (rotate A CX). */
3438 261427663 : if ((tem = simplify_rotate_op (op0, op1, mode)))
3439 : return tem;
3440 :
3441 : /* If one of the operands is a PLUS or a MINUS, see if we can
3442 : simplify this by the associative law.
3443 : Don't use the associative law for floating point.
3444 : The inaccuracy makes it nonassociative,
3445 : and subtle programs can break if operations are associated. */
3446 :
3447 261426173 : if (INTEGRAL_MODE_P (mode)
3448 256612479 : && (plus_minus_operand_p (op0)
3449 221840672 : || plus_minus_operand_p (op1))
3450 35779013 : && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
3451 : return tem;
3452 :
3453 : /* Reassociate floating point addition only when the user
3454 : specifies associative math operations. */
3455 226289300 : if (FLOAT_MODE_P (mode)
3456 4813694 : && flag_associative_math)
3457 : {
3458 910127 : tem = simplify_associative_operation (code, mode, op0, op1);
3459 910127 : if (tem)
3460 : return tem;
3461 : }
3462 :
3463 : /* Handle vector series. */
3464 226275596 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3465 : {
3466 2129390 : tem = simplify_binary_operation_series (code, mode, op0, op1);
3467 2129390 : if (tem)
3468 : return tem;
3469 : }
3470 : break;
3471 :
3472 : case COMPARE:
3473 : break;
3474 :
3475 45985768 : case MINUS:
3476 : /* We can't assume x-x is 0 even with non-IEEE floating point,
3477 : but since it is zero except in very strange circumstances, we
3478 : will treat it as zero with -ffinite-math-only. */
3479 45985768 : if (rtx_equal_p (trueop0, trueop1)
3480 214072 : && ! side_effects_p (op0)
3481 46199398 : && (!FLOAT_MODE_P (mode) || !HONOR_NANS (mode)))
3482 210773 : return CONST0_RTX (mode);
3483 :
3484 : /* Change subtraction from zero into negation. (0 - x) is the
3485 : same as -x when x is NaN, infinite, or finite and nonzero.
3486 : But if the mode has signed zeros, and does not round towards
3487 : -infinity, then 0 - 0 is 0, not -0. */
3488 45774995 : if (!HONOR_SIGNED_ZEROS (mode) && trueop0 == CONST0_RTX (mode))
3489 360467 : return simplify_gen_unary (NEG, mode, op1, mode);
3490 :
3491 : /* (-1 - a) is ~a, unless the expression contains symbolic
3492 : constants, in which case not retaining additions and
3493 : subtractions could cause invalid assembly to be produced. */
3494 45414528 : if (trueop0 == CONSTM1_RTX (mode)
3495 45414528 : && !contains_symbolic_reference_p (op1))
3496 616161 : return simplify_gen_unary (NOT, mode, op1, mode);
3497 :
3498 : /* Subtracting 0 has no effect unless the mode has signalling NaNs,
3499 : or has signed zeros and supports rounding towards -infinity.
3500 : In such a case, 0 - 0 is -0. */
3501 45542848 : if (!(HONOR_SIGNED_ZEROS (mode)
3502 744481 : && HONOR_SIGN_DEPENDENT_ROUNDING (mode))
3503 44797217 : && !HONOR_SNANS (mode)
3504 89595548 : && trueop1 == CONST0_RTX (mode))
3505 : return op0;
3506 :
3507 : /* See if this is something like X * C - X or vice versa or
3508 : if the multiplication is written as a shift. If so, we can
3509 : distribute and make a new multiply, shift, or maybe just
3510 : have X (if C is 2 in the example above). But don't make
3511 : something more expensive than we had before. */
3512 :
3513 43866000 : if (is_a <scalar_int_mode> (mode, &int_mode))
3514 : {
3515 42429338 : rtx lhs = op0, rhs = op1;
3516 :
3517 42429338 : wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
3518 42429338 : wide_int negcoeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3519 :
3520 42429338 : if (GET_CODE (lhs) == NEG)
3521 : {
3522 73828 : coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3523 73828 : lhs = XEXP (lhs, 0);
3524 : }
3525 42355510 : else if (GET_CODE (lhs) == MULT
3526 236598 : && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
3527 : {
3528 80463 : coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
3529 80463 : lhs = XEXP (lhs, 0);
3530 : }
3531 42275047 : else if (GET_CODE (lhs) == ASHIFT
3532 307624 : && CONST_INT_P (XEXP (lhs, 1))
3533 304366 : && INTVAL (XEXP (lhs, 1)) >= 0
3534 42579392 : && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
3535 : {
3536 304345 : coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
3537 608690 : GET_MODE_PRECISION (int_mode));
3538 304345 : lhs = XEXP (lhs, 0);
3539 : }
3540 :
3541 42429338 : if (GET_CODE (rhs) == NEG)
3542 : {
3543 13479 : negcoeff1 = wi::one (GET_MODE_PRECISION (int_mode));
3544 13479 : rhs = XEXP (rhs, 0);
3545 : }
3546 42415859 : else if (GET_CODE (rhs) == MULT
3547 131949 : && CONST_INT_P (XEXP (rhs, 1)))
3548 : {
3549 93335 : negcoeff1 = wi::neg (rtx_mode_t (XEXP (rhs, 1), int_mode));
3550 93335 : rhs = XEXP (rhs, 0);
3551 : }
3552 42322524 : else if (GET_CODE (rhs) == ASHIFT
3553 404327 : && CONST_INT_P (XEXP (rhs, 1))
3554 403779 : && INTVAL (XEXP (rhs, 1)) >= 0
3555 42726303 : && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
3556 : {
3557 403779 : negcoeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
3558 807558 : GET_MODE_PRECISION (int_mode));
3559 403779 : negcoeff1 = -negcoeff1;
3560 403779 : rhs = XEXP (rhs, 0);
3561 : }
3562 :
3563 42429338 : if (rtx_equal_p (lhs, rhs) && !side_effects_p (lhs))
3564 : {
3565 92122 : rtx orig = gen_rtx_MINUS (int_mode, op0, op1);
3566 92122 : rtx coeff;
3567 92122 : bool speed = optimize_function_for_speed_p (cfun);
3568 :
3569 92122 : coeff = immed_wide_int_const (coeff0 + negcoeff1, int_mode);
3570 :
3571 92122 : tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
3572 92122 : return (set_src_cost (tem, int_mode, speed)
3573 92122 : <= set_src_cost (orig, int_mode, speed) ? tem : 0);
3574 : }
3575 :
3576 : /* Optimize (X + 1) * Y - Y to X * Y. */
3577 42337216 : lhs = op0;
3578 42337216 : if (GET_CODE (op0) == MULT)
3579 : {
3580 236120 : if (((GET_CODE (XEXP (op0, 0)) == PLUS
3581 4953 : && XEXP (XEXP (op0, 0), 1) == const1_rtx)
3582 234420 : || (GET_CODE (XEXP (op0, 0)) == MINUS
3583 1665 : && XEXP (XEXP (op0, 0), 1) == constm1_rtx))
3584 237820 : && rtx_equal_p (XEXP (op0, 1), op1))
3585 3 : lhs = XEXP (XEXP (op0, 0), 0);
3586 236117 : else if (((GET_CODE (XEXP (op0, 1)) == PLUS
3587 30 : && XEXP (XEXP (op0, 1), 1) == const1_rtx)
3588 236109 : || (GET_CODE (XEXP (op0, 1)) == MINUS
3589 84 : && XEXP (XEXP (op0, 1), 1) == constm1_rtx))
3590 236125 : && rtx_equal_p (XEXP (op0, 0), op1))
3591 0 : lhs = XEXP (XEXP (op0, 1), 0);
3592 : }
3593 42337216 : if (lhs != op0 && !side_effects_p (op1))
3594 2 : return simplify_gen_binary (MULT, int_mode, lhs, op1);
3595 42429338 : }
3596 :
3597 : /* (a - (-b)) -> (a + b). True even for IEEE. */
3598 43773876 : if (GET_CODE (op1) == NEG)
3599 13425 : return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
3600 :
3601 : /* (-x - c) may be simplified as (-c - x). */
3602 43760451 : if (GET_CODE (op0) == NEG
3603 77973 : && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1)))
3604 : {
3605 724 : tem = simplify_unary_operation (NEG, mode, op1, mode);
3606 724 : if (tem)
3607 724 : return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
3608 : }
3609 :
3610 43759727 : if ((GET_CODE (op0) == CONST
3611 43759727 : || GET_CODE (op0) == SYMBOL_REF
3612 38076772 : || GET_CODE (op0) == LABEL_REF)
3613 43759727 : && poly_int_rtx_p (op1, &offset))
3614 54018 : return plus_constant (mode, op0, trunc_int_for_mode (-offset, mode));
3615 :
3616 : /* Don't let a relocatable value get a negative coeff. */
3617 43705709 : if (is_a <scalar_int_mode> (mode)
3618 42269078 : && poly_int_rtx_p (op1)
3619 51062913 : && GET_MODE (op0) != VOIDmode)
3620 7357204 : return simplify_gen_binary (PLUS, mode,
3621 : op0,
3622 7357204 : neg_poly_int_rtx (mode, op1));
3623 :
3624 : /* (x - (x & y)) -> (x & ~y) */
3625 36348505 : if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND)
3626 : {
3627 223770 : if (rtx_equal_p (op0, XEXP (op1, 0)))
3628 : {
3629 590 : tem = simplify_gen_unary (NOT, mode, XEXP (op1, 1),
3630 295 : GET_MODE (XEXP (op1, 1)));
3631 295 : return simplify_gen_binary (AND, mode, op0, tem);
3632 : }
3633 223475 : if (rtx_equal_p (op0, XEXP (op1, 1)))
3634 : {
3635 2476 : tem = simplify_gen_unary (NOT, mode, XEXP (op1, 0),
3636 1238 : GET_MODE (XEXP (op1, 0)));
3637 1238 : return simplify_gen_binary (AND, mode, op0, tem);
3638 : }
3639 : }
3640 :
3641 : /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
3642 : by reversing the comparison code if valid. */
3643 36346972 : if (STORE_FLAG_VALUE == 1
3644 36346972 : && trueop0 == const1_rtx
3645 1211532 : && COMPARISON_P (op1)
3646 36451618 : && (reversed = reversed_comparison (op1, mode)))
3647 : return reversed;
3648 :
3649 : /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A). */
3650 36242331 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3651 36240980 : && GET_CODE (op1) == MULT
3652 36474916 : && GET_CODE (XEXP (op1, 0)) == NEG)
3653 : {
3654 173 : rtx in1, in2;
3655 :
3656 173 : in1 = XEXP (XEXP (op1, 0), 0);
3657 173 : in2 = XEXP (op1, 1);
3658 173 : return simplify_gen_binary (PLUS, mode,
3659 : simplify_gen_binary (MULT, mode,
3660 : in1, in2),
3661 173 : op0);
3662 : }
3663 :
3664 : /* Canonicalize (minus (neg A) (mult B C)) to
3665 : (minus (mult (neg B) C) A). */
3666 36242158 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3667 36240807 : && GET_CODE (op1) == MULT
3668 36474570 : && GET_CODE (op0) == NEG)
3669 : {
3670 678 : rtx in1, in2;
3671 :
3672 678 : in1 = simplify_gen_unary (NEG, mode, XEXP (op1, 0), mode);
3673 678 : in2 = XEXP (op1, 1);
3674 678 : return simplify_gen_binary (MINUS, mode,
3675 : simplify_gen_binary (MULT, mode,
3676 : in1, in2),
3677 678 : XEXP (op0, 0));
3678 : }
3679 :
3680 : /* If one of the operands is a PLUS or a MINUS, see if we can
3681 : simplify this by the associative law. This will, for example,
3682 : canonicalize (minus A (plus B C)) to (minus (minus A B) C).
3683 : Don't use the associative law for floating point.
3684 : The inaccuracy makes it nonassociative,
3685 : and subtle programs can break if operations are associated. */
3686 :
3687 36241480 : if (INTEGRAL_MODE_P (mode)
3688 35375544 : && (plus_minus_operand_p (op0)
3689 32422212 : || plus_minus_operand_p (op1))
3690 4195995 : && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
3691 : return tem;
3692 :
3693 : /* Handle vector series. */
3694 32197278 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3695 : {
3696 541065 : tem = simplify_binary_operation_series (code, mode, op0, op1);
3697 541065 : if (tem)
3698 : return tem;
3699 : }
3700 : break;
3701 :
3702 12913496 : case MULT:
3703 12913496 : if (trueop1 == constm1_rtx)
3704 34847 : return simplify_gen_unary (NEG, mode, op0, mode);
3705 :
3706 12878649 : if (GET_CODE (op0) == NEG)
3707 : {
3708 38101 : rtx temp = simplify_unary_operation (NEG, mode, op1, mode);
3709 : /* If op1 is a MULT as well and simplify_unary_operation
3710 : just moved the NEG to the second operand, simplify_gen_binary
3711 : below could through simplify_associative_operation move
3712 : the NEG around again and recurse endlessly. */
3713 38101 : if (temp
3714 1901 : && GET_CODE (op1) == MULT
3715 0 : && GET_CODE (temp) == MULT
3716 0 : && XEXP (op1, 0) == XEXP (temp, 0)
3717 0 : && GET_CODE (XEXP (temp, 1)) == NEG
3718 0 : && XEXP (op1, 1) == XEXP (XEXP (temp, 1), 0))
3719 : temp = NULL_RTX;
3720 : if (temp)
3721 1901 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp);
3722 : }
3723 12876748 : if (GET_CODE (op1) == NEG)
3724 : {
3725 961 : rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
3726 : /* If op0 is a MULT as well and simplify_unary_operation
3727 : just moved the NEG to the second operand, simplify_gen_binary
3728 : below could through simplify_associative_operation move
3729 : the NEG around again and recurse endlessly. */
3730 961 : if (temp
3731 399 : && GET_CODE (op0) == MULT
3732 296 : && GET_CODE (temp) == MULT
3733 296 : && XEXP (op0, 0) == XEXP (temp, 0)
3734 6 : && GET_CODE (XEXP (temp, 1)) == NEG
3735 5 : && XEXP (op0, 1) == XEXP (XEXP (temp, 1), 0))
3736 : temp = NULL_RTX;
3737 : if (temp)
3738 394 : return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
3739 : }
3740 :
3741 : /* Maybe simplify x * 0 to 0. The reduction is not valid if
3742 : x is NaN, since x * 0 is then also NaN. Nor is it valid
3743 : when the mode has signed zeros, since multiplying a negative
3744 : number by 0 will give -0, not 0. */
3745 12876354 : if (!HONOR_NANS (mode)
3746 11886564 : && !HONOR_SIGNED_ZEROS (mode)
3747 11886148 : && trueop1 == CONST0_RTX (mode)
3748 12923091 : && ! side_effects_p (op0))
3749 : return op1;
3750 :
3751 : /* In IEEE floating point, x*1 is not equivalent to x for
3752 : signalling NaNs. */
3753 12829617 : if (!HONOR_SNANS (mode)
3754 12829617 : && trueop1 == CONST1_RTX (mode))
3755 : return op0;
3756 :
3757 : /* Convert multiply by constant power of two into shift. */
3758 12287413 : if (mem_depth == 0 && CONST_SCALAR_INT_P (trueop1))
3759 : {
3760 6280237 : val = wi::exact_log2 (rtx_mode_t (trueop1, mode));
3761 6280237 : if (val >= 0)
3762 2949319 : return simplify_gen_binary (ASHIFT, mode, op0,
3763 2949319 : gen_int_shift_amount (mode, val));
3764 : }
3765 :
3766 : /* x*2 is x+x and x*(-1) is -x */
3767 9338094 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
3768 173284 : && SCALAR_FLOAT_MODE_P (GET_MODE (trueop1))
3769 173284 : && !DECIMAL_FLOAT_MODE_P (GET_MODE (trueop1))
3770 173000 : && GET_MODE (op0) == mode)
3771 : {
3772 173000 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
3773 :
3774 173000 : if (real_equal (d1, &dconst2))
3775 682 : return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
3776 :
3777 172318 : if (!HONOR_SNANS (mode)
3778 172318 : && real_equal (d1, &dconstm1))
3779 24 : return simplify_gen_unary (NEG, mode, op0, mode);
3780 : }
3781 :
3782 : /* Optimize -x * -x as x * x. */
3783 9337388 : if (FLOAT_MODE_P (mode)
3784 1413096 : && GET_CODE (op0) == NEG
3785 8342 : && GET_CODE (op1) == NEG
3786 0 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3787 0 : && !side_effects_p (XEXP (op0, 0)))
3788 0 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3789 :
3790 : /* Likewise, optimize abs(x) * abs(x) as x * x. */
3791 9337388 : if (SCALAR_FLOAT_MODE_P (mode)
3792 1107943 : && GET_CODE (op0) == ABS
3793 1488 : && GET_CODE (op1) == ABS
3794 1 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3795 9337388 : && !side_effects_p (XEXP (op0, 0)))
3796 0 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3797 :
3798 : /* Reassociate multiplication, but for floating point MULTs
3799 : only when the user specifies unsafe math optimizations. */
3800 9337388 : if (! FLOAT_MODE_P (mode)
3801 1413096 : || flag_unsafe_math_optimizations)
3802 : {
3803 8348712 : tem = simplify_associative_operation (code, mode, op0, op1);
3804 8348712 : if (tem)
3805 : return tem;
3806 : }
3807 : break;
3808 :
3809 14977070 : case IOR:
3810 14977070 : if (trueop1 == CONST0_RTX (mode))
3811 : return op0;
3812 14257301 : if (INTEGRAL_MODE_P (mode)
3813 13980439 : && trueop1 == CONSTM1_RTX (mode)
3814 10033 : && !side_effects_p (op0))
3815 : return op1;
3816 14247268 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
3817 : return op0;
3818 : /* A | (~A) -> -1 */
3819 77129 : if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
3820 14236434 : || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
3821 0 : && ! side_effects_p (op0)
3822 14236434 : && GET_MODE_CLASS (mode) != MODE_CC)
3823 0 : return CONSTM1_RTX (mode);
3824 :
3825 : /* IOR of two single bit bitfields extracted from the same object.
3826 : Bitfields are represented as an AND based extraction */
3827 14236434 : if (GET_CODE (op0) == AND
3828 4408856 : && GET_CODE (op1) == AND
3829 : /* Verify both AND operands are logical right shifts. */
3830 291695 : && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
3831 2264 : && GET_CODE (XEXP (op1, 0)) == LSHIFTRT
3832 : /* Verify both bitfields are extracted from the same object. */
3833 260 : && XEXP (XEXP (op0, 0), 0) == XEXP (XEXP (op1, 0), 0)
3834 : /* Verify both fields are a single bit (could be generalized). */
3835 256 : && XEXP (op0, 1) == CONST1_RTX (mode)
3836 0 : && XEXP (op1, 1) == CONST1_RTX (mode)
3837 : /* Verify bit positions (for cases with variable bit position). */
3838 0 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
3839 0 : && CONST_INT_P (XEXP (XEXP (op1, 0), 1)))
3840 : {
3841 0 : unsigned HOST_WIDE_INT bitpos1 = INTVAL (XEXP (XEXP (op0, 0), 1));
3842 0 : unsigned HOST_WIDE_INT bitpos2 = INTVAL (XEXP (XEXP (op1, 0), 1));
3843 0 : unsigned HOST_WIDE_INT mask
3844 0 : = (HOST_WIDE_INT_1U << bitpos1) | (HOST_WIDE_INT_1U << bitpos2);
3845 :
3846 0 : rtx m = GEN_INT (mask);
3847 0 : rtx t = gen_rtx_AND (mode, XEXP (XEXP (op0, 0), 0), m);
3848 0 : t = gen_rtx_NE (mode, t, CONST0_RTX (mode));
3849 0 : return t;
3850 : }
3851 :
3852 : /* IOR of multiple single bit bitfields extracted from the same object
3853 : (building on previous case).
3854 : First bitfield is represented as an AND based extraction, as done
3855 : above. Second represented as NE based extraction, from
3856 : output above. */
3857 14236434 : if (GET_CODE (op0) == AND
3858 4408856 : && GET_CODE (op1) == NE
3859 : /* Verify AND operand is logical right shift. */
3860 3392 : && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
3861 : /* Verify NE operand is an AND (based on output above). */
3862 86 : && GET_CODE (XEXP (op1, 0)) == AND
3863 : /* Verify both bitfields are extracted from the same object. */
3864 0 : && XEXP (XEXP (op0, 0), 0) == XEXP (XEXP (op1, 0), 0)
3865 : /* Verify masking is with a single bit and that we have a NE 0
3866 : comparison for the other operand. */
3867 0 : && XEXP (op0, 1) == CONST1_RTX (mode)
3868 0 : && XEXP (op1, 1) == CONST0_RTX (mode)
3869 : /* Verify bit position. */
3870 0 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
3871 : {
3872 0 : unsigned HOST_WIDE_INT bitpos1 = INTVAL (XEXP (XEXP (op0, 0), 1));
3873 0 : unsigned HOST_WIDE_INT mask
3874 0 : = (HOST_WIDE_INT_1U << bitpos1) | INTVAL (XEXP (XEXP (op1, 0), 1));
3875 :
3876 0 : rtx m = GEN_INT (mask);
3877 0 : rtx t = gen_rtx_AND (mode, XEXP (XEXP (op0, 0), 0), m);
3878 0 : t = gen_rtx_NE (mode, t, CONST0_RTX (mode));
3879 0 : return t;
3880 : }
3881 :
3882 : /* Convert (ior (plus (A - 1)) (neg A)) to -1. */
3883 14236434 : if (match_plus_neg_pattern (op0, op1, mode))
3884 0 : return CONSTM1_RTX (mode);
3885 :
3886 : /* (ior A C) is C if all bits of A that might be nonzero are on in C. */
3887 14236434 : if (CONST_INT_P (op1)
3888 3742347 : && HWI_COMPUTABLE_MODE_P (mode)
3889 3685637 : && (nonzero_bits (op0, mode) & ~UINTVAL (op1)) == 0
3890 14460498 : && !side_effects_p (op0))
3891 : return op1;
3892 :
3893 : /* Canonicalize (X & C1) | C2. */
3894 14012370 : if (GET_CODE (op0) == AND
3895 4399995 : && CONST_INT_P (trueop1)
3896 786743 : && CONST_INT_P (XEXP (op0, 1)))
3897 : {
3898 563310 : HOST_WIDE_INT mask = GET_MODE_MASK (mode);
3899 563310 : HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
3900 563310 : HOST_WIDE_INT c2 = INTVAL (trueop1);
3901 :
3902 : /* If (C1&C2) == C1, then (X&C1)|C2 becomes C2. */
3903 563310 : if ((c1 & c2) == c1
3904 563310 : && !side_effects_p (XEXP (op0, 0)))
3905 : return trueop1;
3906 :
3907 : /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2. */
3908 563302 : if (((c1|c2) & mask) == mask)
3909 78054 : return simplify_gen_binary (IOR, mode, XEXP (op0, 0), op1);
3910 :
3911 : /* If (C1|C2) has a single bit clear, then adjust C1 so that
3912 : when split it'll match a single bit clear style insn.
3913 :
3914 : This could have been done with a target dependent splitter, but
3915 : then every target with single bit manipulation insns would need
3916 : to implement such splitters. */
3917 485248 : if (exact_log2 (~(c1 | c2)) >= 0)
3918 : {
3919 69515 : rtx temp = gen_rtx_AND (mode, XEXP (op0, 0), GEN_INT (c1 | c2));
3920 69515 : temp = gen_rtx_IOR (mode, temp, trueop1);
3921 69515 : return temp;
3922 : }
3923 : }
3924 :
3925 : /* Convert (A & B) | A to A. */
3926 13864793 : if (GET_CODE (op0) == AND
3927 4252418 : && (rtx_equal_p (XEXP (op0, 0), op1)
3928 4251933 : || rtx_equal_p (XEXP (op0, 1), op1))
3929 3676 : && ! side_effects_p (XEXP (op0, 0))
3930 13868469 : && ! side_effects_p (XEXP (op0, 1)))
3931 : return op1;
3932 :
3933 : /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3934 : mode size to (rotate A CX). */
3935 13861117 : tem = simplify_rotate_op (op0, op1, mode);
3936 13861117 : if (tem)
3937 : return tem;
3938 :
3939 : /* If OP0 is (ashiftrt (plus ...) C), it might actually be
3940 : a (sign_extend (plus ...)). Then check if OP1 is a CONST_INT and
3941 : the PLUS does not affect any of the bits in OP1: then we can do
3942 : the IOR as a PLUS and we can associate. This is valid if OP1
3943 : can be safely shifted left C bits. */
3944 13858891 : if (CONST_INT_P (trueop1) && GET_CODE (op0) == ASHIFTRT
3945 6186 : && GET_CODE (XEXP (op0, 0)) == PLUS
3946 74 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
3947 50 : && CONST_INT_P (XEXP (op0, 1))
3948 50 : && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
3949 : {
3950 50 : int count = INTVAL (XEXP (op0, 1));
3951 50 : HOST_WIDE_INT mask = UINTVAL (trueop1) << count;
3952 :
3953 50 : if (mask >> count == INTVAL (trueop1)
3954 43 : && trunc_int_for_mode (mask, mode) == mask
3955 80 : && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
3956 0 : return simplify_gen_binary (ASHIFTRT, mode,
3957 : plus_constant (mode, XEXP (op0, 0),
3958 0 : mask),
3959 : XEXP (op0, 1));
3960 : }
3961 :
3962 : /* The following happens with bitfield merging.
3963 : (X & C) | ((X | Y) & ~C) -> X | (Y & ~C) */
3964 13858891 : if (GET_CODE (op0) == AND
3965 4248742 : && GET_CODE (op1) == AND
3966 291695 : && CONST_INT_P (XEXP (op0, 1))
3967 130500 : && CONST_INT_P (XEXP (op1, 1))
3968 126126 : && (INTVAL (XEXP (op0, 1))
3969 126126 : == ~INTVAL (XEXP (op1, 1))))
3970 : {
3971 : /* The IOR/XOR may be on both sides. */
3972 37098 : rtx top0 = NULL_RTX, top1 = NULL_RTX;
3973 37098 : if (GET_CODE (XEXP (op1, 0)) == IOR
3974 37098 : || GET_CODE (XEXP (op1, 0)) == XOR)
3975 : top0 = op0, top1 = op1;
3976 36979 : else if (GET_CODE (XEXP (op0, 0)) == IOR
3977 36979 : || GET_CODE (XEXP (op0, 0)) == XOR)
3978 3 : top0 = op1, top1 = op0;
3979 37098 : if (top0 && top1)
3980 : {
3981 : /* X may be on either side of the inner IOR/XOR. */
3982 122 : rtx tem = NULL_RTX;
3983 122 : if (rtx_equal_p (XEXP (top0, 0),
3984 122 : XEXP (XEXP (top1, 0), 0)))
3985 76 : tem = XEXP (XEXP (top1, 0), 1);
3986 46 : else if (rtx_equal_p (XEXP (top0, 0),
3987 46 : XEXP (XEXP (top1, 0), 1)))
3988 13 : tem = XEXP (XEXP (top1, 0), 0);
3989 89 : if (tem)
3990 89 : return simplify_gen_binary (GET_CODE (XEXP (top1, 0)),
3991 : mode, XEXP (top0, 0),
3992 : simplify_gen_binary
3993 89 : (AND, mode, tem, XEXP (top1, 1)));
3994 : }
3995 : }
3996 :
3997 : /* Convert (ior (and A C) (and B C)) into (and (ior A B) C). */
3998 13858802 : if (GET_CODE (op0) == GET_CODE (op1)
3999 3052560 : && (GET_CODE (op0) == AND
4000 : || GET_CODE (op0) == IOR
4001 3052560 : || GET_CODE (op0) == LSHIFTRT
4002 2759983 : || GET_CODE (op0) == ASHIFTRT
4003 2759850 : || GET_CODE (op0) == ASHIFT
4004 2742991 : || GET_CODE (op0) == ROTATE
4005 2742991 : || GET_CODE (op0) == ROTATERT))
4006 : {
4007 309569 : tem = simplify_distributive_operation (code, mode, op0, op1);
4008 309569 : if (tem)
4009 : return tem;
4010 : }
4011 :
4012 : /* Convert (ior (and (not A) B) A) into A | B. */
4013 13774527 : if (GET_CODE (op0) == AND
4014 13774527 : && negated_ops_p (XEXP (op0, 0), op1))
4015 6496 : return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
4016 :
4017 : /* op0/op1 may have a common term which in turn may allow simplification
4018 : of the the outer IOR. There are likely other cases we should
4019 : handle for the outer code as well as the form of the operands. */
4020 13768031 : tem = simplify_ior_with_common_term (mode, op0, op1);
4021 13768031 : if (tem)
4022 : return tem;
4023 :
4024 : /* IOR is commutative and we can't rely on canonicalization at this point,
4025 : so try again to simplify with the operands reversed. */
4026 13767941 : tem = simplify_ior_with_common_term (mode, op1, op0);
4027 13767941 : if (tem)
4028 : return tem;
4029 :
4030 13767941 : tem = simplify_with_subreg_not (code, mode, op0, op1);
4031 13767941 : if (tem)
4032 : return tem;
4033 :
4034 13767936 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
4035 13767936 : if (tem)
4036 : return tem;
4037 :
4038 13767930 : tem = simplify_associative_operation (code, mode, op0, op1);
4039 13767930 : if (tem)
4040 : return tem;
4041 :
4042 13507768 : tem = simplify_logical_relational_operation (code, mode, op0, op1);
4043 13507768 : if (tem)
4044 : return tem;
4045 : break;
4046 :
4047 1896415 : case XOR:
4048 1896415 : if (trueop1 == CONST0_RTX (mode))
4049 : return op0;
4050 1836600 : if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
4051 31096 : return simplify_gen_unary (NOT, mode, op0, mode);
4052 1805504 : if (rtx_equal_p (trueop0, trueop1)
4053 2851 : && ! side_effects_p (op0)
4054 1808351 : && GET_MODE_CLASS (mode) != MODE_CC)
4055 2847 : return CONST0_RTX (mode);
4056 :
4057 : /* Canonicalize XOR of the most significant bit to PLUS. */
4058 1802657 : if (CONST_SCALAR_INT_P (op1)
4059 1802657 : && mode_signbit_p (mode, op1))
4060 41202 : return simplify_gen_binary (PLUS, mode, op0, op1);
4061 : /* (xor (plus X C1) C2) is (xor X (C1^C2)) if C1 is signbit. */
4062 1761455 : if (CONST_SCALAR_INT_P (op1)
4063 505600 : && GET_CODE (op0) == PLUS
4064 2539 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
4065 1762975 : && mode_signbit_p (mode, XEXP (op0, 1)))
4066 189 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
4067 : simplify_gen_binary (XOR, mode, op1,
4068 189 : XEXP (op0, 1)));
4069 :
4070 : /* If we are XORing two things that have no bits in common,
4071 : convert them into an IOR. This helps to detect rotation encoded
4072 : using those methods and possibly other simplifications. */
4073 :
4074 1761266 : if (HWI_COMPUTABLE_MODE_P (mode)
4075 1415523 : && (nonzero_bits (op0, mode)
4076 1415523 : & nonzero_bits (op1, mode)) == 0)
4077 10205 : return (simplify_gen_binary (IOR, mode, op0, op1));
4078 :
4079 : /* Convert (xor (plus (A - 1)) (neg A)) to -1. */
4080 1751061 : if (match_plus_neg_pattern (op0, op1, mode))
4081 0 : return CONSTM1_RTX (mode);
4082 :
4083 : /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
4084 : Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
4085 : (NOT y). */
4086 1751061 : {
4087 1751061 : int num_negated = 0;
4088 :
4089 1751061 : if (GET_CODE (op0) == NOT)
4090 723 : num_negated++, op0 = XEXP (op0, 0);
4091 1751061 : if (GET_CODE (op1) == NOT)
4092 67 : num_negated++, op1 = XEXP (op1, 0);
4093 :
4094 67 : if (num_negated == 2)
4095 0 : return simplify_gen_binary (XOR, mode, op0, op1);
4096 1751061 : else if (num_negated == 1)
4097 790 : return simplify_gen_unary (NOT, mode,
4098 : simplify_gen_binary (XOR, mode, op0, op1),
4099 790 : mode);
4100 : }
4101 :
4102 : /* Convert (xor (and A B) B) to (and (not A) B). The latter may
4103 : correspond to a machine insn or result in further simplifications
4104 : if B is a constant. */
4105 :
4106 1750271 : if (GET_CODE (op0) == AND
4107 195245 : && rtx_equal_p (XEXP (op0, 1), op1)
4108 1773258 : && ! side_effects_p (op1))
4109 22987 : return simplify_gen_binary (AND, mode,
4110 : simplify_gen_unary (NOT, mode,
4111 : XEXP (op0, 0), mode),
4112 22987 : op1);
4113 :
4114 1727284 : else if (GET_CODE (op0) == AND
4115 172258 : && rtx_equal_p (XEXP (op0, 0), op1)
4116 1729386 : && ! side_effects_p (op1))
4117 2102 : return simplify_gen_binary (AND, mode,
4118 : simplify_gen_unary (NOT, mode,
4119 : XEXP (op0, 1), mode),
4120 2102 : op1);
4121 :
4122 : /* Similarly, convert (xor (ior A B) B) to (and (not B) A). */
4123 1725182 : else if (GET_CODE (op0) == IOR
4124 23216 : && rtx_equal_p (XEXP (op0, 1), op1)
4125 1725337 : && ! side_effects_p (op1))
4126 155 : return simplify_gen_binary (AND, mode,
4127 : simplify_gen_unary (NOT, mode,
4128 : op1, mode),
4129 155 : XEXP (op0, 0));
4130 1725027 : else if (GET_CODE (op0) == IOR
4131 23061 : && rtx_equal_p (XEXP (op0, 0), op1)
4132 1725035 : && ! side_effects_p (op1))
4133 8 : return simplify_gen_binary (AND, mode,
4134 : simplify_gen_unary (NOT, mode,
4135 : op1, mode),
4136 8 : XEXP (op0, 1));
4137 :
4138 : /* Given (xor (ior (xor A B) C) D), where B, C and D are
4139 : constants, simplify to (xor (ior A C) (B&~C)^D), canceling
4140 : out bits inverted twice and not set by C. Similarly, given
4141 : (xor (and (xor A B) C) D), simplify without inverting C in
4142 : the xor operand: (xor (and A C) (B&C)^D).
4143 : */
4144 1725019 : else if ((GET_CODE (op0) == IOR || GET_CODE (op0) == AND)
4145 193209 : && GET_CODE (XEXP (op0, 0)) == XOR
4146 7612 : && CONST_INT_P (op1)
4147 222 : && CONST_INT_P (XEXP (op0, 1))
4148 179 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
4149 : {
4150 38 : enum rtx_code op = GET_CODE (op0);
4151 38 : rtx a = XEXP (XEXP (op0, 0), 0);
4152 38 : rtx b = XEXP (XEXP (op0, 0), 1);
4153 38 : rtx c = XEXP (op0, 1);
4154 38 : rtx d = op1;
4155 38 : HOST_WIDE_INT bval = INTVAL (b);
4156 38 : HOST_WIDE_INT cval = INTVAL (c);
4157 38 : HOST_WIDE_INT dval = INTVAL (d);
4158 38 : HOST_WIDE_INT xcval;
4159 :
4160 38 : if (op == IOR)
4161 8 : xcval = ~cval;
4162 : else
4163 : xcval = cval;
4164 :
4165 38 : return simplify_gen_binary (XOR, mode,
4166 : simplify_gen_binary (op, mode, a, c),
4167 38 : gen_int_mode ((bval & xcval) ^ dval,
4168 : mode));
4169 : }
4170 :
4171 : /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P),
4172 : we can transform like this:
4173 : (A&B)^C == ~(A&B)&C | ~C&(A&B)
4174 : == (~A|~B)&C | ~C&(A&B) * DeMorgan's Law
4175 : == ~A&C | ~B&C | A&(~C&B) * Distribute and re-order
4176 : Attempt a few simplifications when B and C are both constants. */
4177 1724981 : if (GET_CODE (op0) == AND
4178 170126 : && CONST_INT_P (op1)
4179 14490 : && CONST_INT_P (XEXP (op0, 1)))
4180 : {
4181 11501 : rtx a = XEXP (op0, 0);
4182 11501 : rtx b = XEXP (op0, 1);
4183 11501 : rtx c = op1;
4184 11501 : HOST_WIDE_INT bval = INTVAL (b);
4185 11501 : HOST_WIDE_INT cval = INTVAL (c);
4186 :
4187 : /* Instead of computing ~A&C, we compute its negated value,
4188 : ~(A|~C). If it yields -1, ~A&C is zero, so we can
4189 : optimize for sure. If it does not simplify, we still try
4190 : to compute ~A&C below, but since that always allocates
4191 : RTL, we don't try that before committing to returning a
4192 : simplified expression. */
4193 11501 : rtx n_na_c = simplify_binary_operation (IOR, mode, a,
4194 : GEN_INT (~cval));
4195 :
4196 11501 : if ((~cval & bval) == 0)
4197 : {
4198 824 : rtx na_c = NULL_RTX;
4199 824 : if (n_na_c)
4200 0 : na_c = simplify_gen_unary (NOT, mode, n_na_c, mode);
4201 : else
4202 : {
4203 : /* If ~A does not simplify, don't bother: we don't
4204 : want to simplify 2 operations into 3, and if na_c
4205 : were to simplify with na, n_na_c would have
4206 : simplified as well. */
4207 824 : rtx na = simplify_unary_operation (NOT, mode, a, mode);
4208 824 : if (na)
4209 0 : na_c = simplify_gen_binary (AND, mode, na, c);
4210 : }
4211 :
4212 : /* Try to simplify ~A&C | ~B&C. */
4213 0 : if (na_c != NULL_RTX)
4214 0 : return simplify_gen_binary (IOR, mode, na_c,
4215 0 : gen_int_mode (~bval & cval, mode));
4216 : }
4217 : else
4218 : {
4219 : /* If ~A&C is zero, simplify A&(~C&B) | ~B&C. */
4220 10677 : if (n_na_c == CONSTM1_RTX (mode))
4221 : {
4222 0 : rtx a_nc_b = simplify_gen_binary (AND, mode, a,
4223 0 : gen_int_mode (~cval & bval,
4224 : mode));
4225 0 : return simplify_gen_binary (IOR, mode, a_nc_b,
4226 0 : gen_int_mode (~bval & cval,
4227 : mode));
4228 : }
4229 : }
4230 : }
4231 :
4232 : /* If we have (xor (and (xor A B) C) A) with C a constant we can instead
4233 : do (ior (and A ~C) (and B C)) which is a machine instruction on some
4234 : machines, and also has shorter instruction path length. */
4235 1724981 : if (GET_CODE (op0) == AND
4236 170126 : && GET_CODE (XEXP (op0, 0)) == XOR
4237 7124 : && CONST_INT_P (XEXP (op0, 1))
4238 1728809 : && rtx_equal_p (XEXP (XEXP (op0, 0), 0), trueop1))
4239 : {
4240 7 : rtx a = trueop1;
4241 7 : rtx b = XEXP (XEXP (op0, 0), 1);
4242 7 : rtx c = XEXP (op0, 1);
4243 7 : rtx nc = simplify_gen_unary (NOT, mode, c, mode);
4244 7 : rtx a_nc = simplify_gen_binary (AND, mode, a, nc);
4245 7 : rtx bc = simplify_gen_binary (AND, mode, b, c);
4246 7 : return simplify_gen_binary (IOR, mode, a_nc, bc);
4247 : }
4248 : /* Similarly, (xor (and (xor A B) C) B) as (ior (and A C) (and B ~C)) */
4249 1724974 : else if (GET_CODE (op0) == AND
4250 170119 : && GET_CODE (XEXP (op0, 0)) == XOR
4251 7117 : && CONST_INT_P (XEXP (op0, 1))
4252 1728795 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), trueop1))
4253 : {
4254 8 : rtx a = XEXP (XEXP (op0, 0), 0);
4255 8 : rtx b = trueop1;
4256 8 : rtx c = XEXP (op0, 1);
4257 8 : rtx nc = simplify_gen_unary (NOT, mode, c, mode);
4258 8 : rtx b_nc = simplify_gen_binary (AND, mode, b, nc);
4259 8 : rtx ac = simplify_gen_binary (AND, mode, a, c);
4260 8 : return simplify_gen_binary (IOR, mode, ac, b_nc);
4261 : }
4262 :
4263 : /* (xor (comparison foo bar) (const_int 1)) can become the reversed
4264 : comparison if STORE_FLAG_VALUE is 1. */
4265 1724966 : if (STORE_FLAG_VALUE == 1
4266 1724966 : && trueop1 == const1_rtx
4267 212555 : && COMPARISON_P (op0)
4268 1731765 : && (reversed = reversed_comparison (op0, mode)))
4269 : return reversed;
4270 :
4271 : /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
4272 : is (lt foo (const_int 0)), so we can perform the above
4273 : simplification if STORE_FLAG_VALUE is 1. */
4274 :
4275 1718191 : if (is_a <scalar_int_mode> (mode, &int_mode)
4276 : && STORE_FLAG_VALUE == 1
4277 1376987 : && trueop1 == const1_rtx
4278 205780 : && GET_CODE (op0) == LSHIFTRT
4279 35201 : && CONST_INT_P (XEXP (op0, 1))
4280 35201 : && INTVAL (XEXP (op0, 1)) == GET_MODE_PRECISION (int_mode) - 1)
4281 34098 : return gen_rtx_GE (int_mode, XEXP (op0, 0), const0_rtx);
4282 :
4283 : /* (xor (comparison foo bar) (const_int sign-bit))
4284 : when STORE_FLAG_VALUE is the sign bit. */
4285 1684093 : if (is_a <scalar_int_mode> (mode, &int_mode)
4286 1342889 : && val_signbit_p (int_mode, STORE_FLAG_VALUE)
4287 0 : && trueop1 == const_true_rtx
4288 0 : && COMPARISON_P (op0)
4289 0 : && (reversed = reversed_comparison (op0, int_mode)))
4290 : return reversed;
4291 :
4292 : /* Convert (xor (and A C) (and B C)) into (and (xor A B) C). */
4293 1684093 : if (GET_CODE (op0) == GET_CODE (op1)
4294 586608 : && (GET_CODE (op0) == AND
4295 586608 : || GET_CODE (op0) == LSHIFTRT
4296 507485 : || GET_CODE (op0) == ASHIFTRT
4297 507383 : || GET_CODE (op0) == ASHIFT
4298 507255 : || GET_CODE (op0) == ROTATE
4299 507113 : || GET_CODE (op0) == ROTATERT))
4300 : {
4301 80029 : tem = simplify_distributive_operation (code, mode, op0, op1);
4302 80029 : if (tem)
4303 : return tem;
4304 : }
4305 :
4306 : /* Convert (xor (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
4307 : mode size to (rotate A CX). */
4308 1608046 : tem = simplify_rotate_op (op0, op1, mode);
4309 1608046 : if (tem)
4310 : return tem;
4311 :
4312 : /* Convert (xor (and (not A) B) A) into A | B. */
4313 1606666 : if (GET_CODE (op0) == AND
4314 1606666 : && negated_ops_p (XEXP (op0, 0), op1))
4315 0 : return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
4316 :
4317 : /* Convert (xor (and (rotate (~1) A) B) (ashift 1 A))
4318 : into B | (1 << A). */
4319 1606666 : if (SHIFT_COUNT_TRUNCATED
4320 : && GET_CODE (op0) == AND
4321 : && GET_CODE (XEXP (op0, 0)) == ROTATE
4322 : && CONST_INT_P (XEXP (XEXP (op0, 0), 0))
4323 : && INTVAL (XEXP (XEXP (op0, 0), 0)) == -2
4324 : && GET_CODE (op1) == ASHIFT
4325 : && CONST_INT_P (XEXP (op1, 0))
4326 : && INTVAL (XEXP (op1, 0)) == 1
4327 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), XEXP (op1, 1))
4328 : && !side_effects_p (XEXP (op1, 1)))
4329 : return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
4330 :
4331 1606666 : tem = simplify_with_subreg_not (code, mode, op0, op1);
4332 1606666 : if (tem)
4333 : return tem;
4334 :
4335 1606665 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
4336 1606665 : if (tem)
4337 : return tem;
4338 :
4339 1606665 : tem = simplify_associative_operation (code, mode, op0, op1);
4340 1606665 : if (tem)
4341 : return tem;
4342 : break;
4343 :
4344 25094019 : case AND:
4345 25094019 : if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
4346 : return trueop1;
4347 24764042 : if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
4348 : return op0;
4349 24354651 : if (HWI_COMPUTABLE_MODE_P (mode))
4350 : {
4351 : /* When WORD_REGISTER_OPERATIONS is true, we need to know the
4352 : nonzero bits in WORD_MODE rather than MODE. */
4353 21328522 : scalar_int_mode tmode = as_a <scalar_int_mode> (mode);
4354 21328522 : if (WORD_REGISTER_OPERATIONS
4355 : && GET_MODE_BITSIZE (tmode) < BITS_PER_WORD)
4356 : tmode = word_mode;
4357 21328522 : HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, tmode);
4358 21328522 : HOST_WIDE_INT nzop1;
4359 21328522 : if (CONST_INT_P (trueop1))
4360 : {
4361 18012982 : HOST_WIDE_INT val1 = INTVAL (trueop1);
4362 : /* If we are turning off bits already known off in OP0, we need
4363 : not do an AND. */
4364 18012982 : if ((nzop0 & ~val1) == 0)
4365 448521 : return op0;
4366 :
4367 : /* Canonicalize (and (subreg (lshiftrt X shift)) mask) into
4368 : (and (lshiftrt (subreg X) shift) mask).
4369 :
4370 : Keeps shift and AND in the same mode, improving recognition.
4371 : Only applied when subreg is a lowpart, shift is valid,
4372 : and no precision is lost. */
4373 17651478 : if (SUBREG_P (op0)
4374 6208121 : && subreg_lowpart_p (op0)
4375 6191076 : && !paradoxical_subreg_p (op0)
4376 799030 : && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
4377 : /* simplify_subreg asserts the object being accessed is not
4378 : VOIDmode or BLKmode. We may have a REG_EQUAL note which
4379 : is not simplified and the source operand is a constant,
4380 : and thus VOIDmode. Guard against that. */
4381 117448 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) != VOIDmode
4382 117398 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) != BLKmode
4383 117398 : && !CONST_INT_P (XEXP (XEXP (op0, 0), 0))
4384 117398 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
4385 96425 : && INTVAL (XEXP (XEXP (op0, 0), 1)) >= 0
4386 96425 : && INTVAL (XEXP (XEXP (op0, 0), 1)) < HOST_BITS_PER_WIDE_INT
4387 17747878 : && ((INTVAL (XEXP (XEXP (op0, 0), 1))
4388 96400 : + floor_log2 (val1))
4389 17651478 : < GET_MODE_PRECISION (as_a <scalar_int_mode> (mode))))
4390 : {
4391 13389 : tem = XEXP (XEXP (op0, 0), 0);
4392 13389 : if (SUBREG_P (tem))
4393 : {
4394 296 : if (subreg_lowpart_p (tem))
4395 296 : tem = SUBREG_REG (tem);
4396 : else
4397 : tem = NULL_RTX;
4398 : }
4399 296 : if (tem != NULL_RTX)
4400 : {
4401 13389 : offset = subreg_lowpart_offset (mode, GET_MODE (tem));
4402 13389 : tem = simplify_gen_subreg (mode, tem, GET_MODE (tem),
4403 13389 : offset);
4404 13389 : if (tem)
4405 : {
4406 13389 : unsigned shiftamt = INTVAL (XEXP (XEXP (op0, 0), 1));
4407 13389 : rtx shiftamtrtx = gen_int_shift_amount (mode,
4408 13389 : shiftamt);
4409 13389 : op0 = simplify_gen_binary (LSHIFTRT, mode, tem,
4410 : shiftamtrtx);
4411 13389 : return simplify_gen_binary (AND, mode, op0, op1);
4412 : }
4413 : }
4414 : }
4415 : }
4416 20953629 : nzop1 = nonzero_bits (trueop1, mode);
4417 : /* If we are clearing all the nonzero bits, the result is zero. */
4418 20953629 : if ((nzop1 & nzop0) == 0
4419 20953629 : && !side_effects_p (op0) && !side_effects_p (op1))
4420 73628 : return CONST0_RTX (mode);
4421 : }
4422 23910894 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
4423 23910890 : && GET_MODE_CLASS (mode) != MODE_CC)
4424 : return op0;
4425 : /* A & (~A) -> 0 */
4426 638361 : if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
4427 23897684 : || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
4428 3734 : && ! side_effects_p (op0)
4429 23905103 : && GET_MODE_CLASS (mode) != MODE_CC)
4430 3733 : return CONST0_RTX (mode);
4431 :
4432 : /* Convert (and (plus (A - 1)) (neg A)) to 0. */
4433 23897637 : if (match_plus_neg_pattern (op0, op1, mode))
4434 2 : return CONST0_RTX (mode);
4435 :
4436 : /* Transform (and (extend X) C) into (zero_extend (and X C)) if
4437 : there are no nonzero bits of C outside of X's mode. */
4438 47795270 : if ((GET_CODE (op0) == SIGN_EXTEND
4439 23897635 : || GET_CODE (op0) == ZERO_EXTEND)
4440 95478 : && CONST_SCALAR_INT_P (trueop1)
4441 82249 : && is_a <scalar_int_mode> (mode, &int_mode)
4442 82249 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
4443 23979884 : && (wi::mask (GET_MODE_PRECISION (inner_mode), true,
4444 82249 : GET_MODE_PRECISION (int_mode))
4445 23979884 : & rtx_mode_t (trueop1, mode)) == 0)
4446 : {
4447 80187 : machine_mode imode = GET_MODE (XEXP (op0, 0));
4448 80187 : tem = immed_wide_int_const (rtx_mode_t (trueop1, mode), imode);
4449 80187 : tem = simplify_gen_binary (AND, imode, XEXP (op0, 0), tem);
4450 80187 : return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
4451 : }
4452 :
4453 : /* Transform (and (truncate X) C) into (truncate (and X C)). This way
4454 : we might be able to further simplify the AND with X and potentially
4455 : remove the truncation altogether. */
4456 23817448 : if (GET_CODE (op0) == TRUNCATE && CONST_INT_P (trueop1))
4457 : {
4458 6 : rtx x = XEXP (op0, 0);
4459 6 : machine_mode xmode = GET_MODE (x);
4460 6 : tem = simplify_gen_binary (AND, xmode, x,
4461 6 : gen_int_mode (INTVAL (trueop1), xmode));
4462 6 : return simplify_gen_unary (TRUNCATE, mode, tem, xmode);
4463 : }
4464 :
4465 : /* Canonicalize (A | C1) & C2 as (A & C2) | (C1 & C2). */
4466 23817442 : if (GET_CODE (op0) == IOR
4467 1463100 : && CONST_INT_P (trueop1)
4468 225032 : && CONST_INT_P (XEXP (op0, 1)))
4469 : {
4470 142219 : HOST_WIDE_INT tmp = INTVAL (trueop1) & INTVAL (XEXP (op0, 1));
4471 142219 : return simplify_gen_binary (IOR, mode,
4472 : simplify_gen_binary (AND, mode,
4473 : XEXP (op0, 0), op1),
4474 142219 : gen_int_mode (tmp, mode));
4475 : }
4476 :
4477 : /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
4478 : insn (and may simplify more). */
4479 23675223 : if (GET_CODE (op0) == XOR
4480 155366 : && rtx_equal_p (XEXP (op0, 0), op1)
4481 23676879 : && ! side_effects_p (op1))
4482 1656 : return simplify_gen_binary (AND, mode,
4483 : simplify_gen_unary (NOT, mode,
4484 : XEXP (op0, 1), mode),
4485 1656 : op1);
4486 :
4487 23673567 : if (GET_CODE (op0) == XOR
4488 153710 : && rtx_equal_p (XEXP (op0, 1), op1)
4489 23678437 : && ! side_effects_p (op1))
4490 4870 : return simplify_gen_binary (AND, mode,
4491 : simplify_gen_unary (NOT, mode,
4492 : XEXP (op0, 0), mode),
4493 4870 : op1);
4494 :
4495 : /* Similarly for (~(A ^ B)) & A. */
4496 23668697 : if (GET_CODE (op0) == NOT
4497 634676 : && GET_CODE (XEXP (op0, 0)) == XOR
4498 3868 : && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
4499 23668751 : && ! side_effects_p (op1))
4500 54 : return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
4501 :
4502 23668643 : if (GET_CODE (op0) == NOT
4503 634622 : && GET_CODE (XEXP (op0, 0)) == XOR
4504 3814 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
4505 23668680 : && ! side_effects_p (op1))
4506 37 : return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
4507 :
4508 : /* Convert (A | B) & A to A. */
4509 23668606 : if (GET_CODE (op0) == IOR
4510 1320881 : && (rtx_equal_p (XEXP (op0, 0), op1)
4511 1320356 : || rtx_equal_p (XEXP (op0, 1), op1))
4512 750 : && ! side_effects_p (XEXP (op0, 0))
4513 23669356 : && ! side_effects_p (XEXP (op0, 1)))
4514 : return op1;
4515 :
4516 : /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
4517 : ((A & N) + B) & M -> (A + B) & M
4518 : Similarly if (N & M) == 0,
4519 : ((A | N) + B) & M -> (A + B) & M
4520 : and for - instead of + and/or ^ instead of |.
4521 : Also, if (N & M) == 0, then
4522 : (A +- N) & M -> A & M. */
4523 23667856 : if (CONST_INT_P (trueop1)
4524 17437069 : && HWI_COMPUTABLE_MODE_P (mode)
4525 17415145 : && ~UINTVAL (trueop1)
4526 17415145 : && (UINTVAL (trueop1) & (UINTVAL (trueop1) + 1)) == 0
4527 35142440 : && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS))
4528 : {
4529 991504 : rtx pmop[2];
4530 991504 : int which;
4531 :
4532 991504 : pmop[0] = XEXP (op0, 0);
4533 991504 : pmop[1] = XEXP (op0, 1);
4534 :
4535 991504 : if (CONST_INT_P (pmop[1])
4536 489881 : && (UINTVAL (pmop[1]) & UINTVAL (trueop1)) == 0)
4537 172301 : return simplify_gen_binary (AND, mode, pmop[0], op1);
4538 :
4539 2480526 : for (which = 0; which < 2; which++)
4540 : {
4541 1653684 : tem = pmop[which];
4542 1653684 : switch (GET_CODE (tem))
4543 : {
4544 14762 : case AND:
4545 14762 : if (CONST_INT_P (XEXP (tem, 1))
4546 13191 : && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1))
4547 : == UINTVAL (trueop1))
4548 7630 : pmop[which] = XEXP (tem, 0);
4549 : break;
4550 1346 : case IOR:
4551 1346 : case XOR:
4552 1346 : if (CONST_INT_P (XEXP (tem, 1))
4553 176 : && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1)) == 0)
4554 9 : pmop[which] = XEXP (tem, 0);
4555 : break;
4556 : default:
4557 : break;
4558 : }
4559 : }
4560 :
4561 826842 : if (pmop[0] != XEXP (op0, 0) || pmop[1] != XEXP (op0, 1))
4562 : {
4563 7639 : tem = simplify_gen_binary (GET_CODE (op0), mode,
4564 : pmop[0], pmop[1]);
4565 7639 : return simplify_gen_binary (code, mode, tem, op1);
4566 : }
4567 : }
4568 :
4569 : /* (and X (ior (not X) Y) -> (and X Y) */
4570 23495555 : if (GET_CODE (op1) == IOR
4571 1018327 : && GET_CODE (XEXP (op1, 0)) == NOT
4572 23500974 : && rtx_equal_p (op0, XEXP (XEXP (op1, 0), 0)))
4573 0 : return simplify_gen_binary (AND, mode, op0, XEXP (op1, 1));
4574 :
4575 : /* (and (ior (not X) Y) X) -> (and X Y) */
4576 23495555 : if (GET_CODE (op0) == IOR
4577 1320131 : && GET_CODE (XEXP (op0, 0)) == NOT
4578 23548122 : && rtx_equal_p (op1, XEXP (XEXP (op0, 0), 0)))
4579 6 : return simplify_gen_binary (AND, mode, op1, XEXP (op0, 1));
4580 :
4581 : /* (and X (ior Y (not X)) -> (and X Y) */
4582 23495549 : if (GET_CODE (op1) == IOR
4583 1018327 : && GET_CODE (XEXP (op1, 1)) == NOT
4584 23496115 : && rtx_equal_p (op0, XEXP (XEXP (op1, 1), 0)))
4585 0 : return simplify_gen_binary (AND, mode, op0, XEXP (op1, 0));
4586 :
4587 : /* (and (ior Y (not X)) X) -> (and X Y) */
4588 23495549 : if (GET_CODE (op0) == IOR
4589 1320125 : && GET_CODE (XEXP (op0, 1)) == NOT
4590 23502939 : && rtx_equal_p (op1, XEXP (XEXP (op0, 1), 0)))
4591 72 : return simplify_gen_binary (AND, mode, op1, XEXP (op0, 0));
4592 :
4593 : /* (and (ior/xor X Y) (not Y)) -> X & ~Y */
4594 23495477 : if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
4595 23495477 : && negated_ops_p (op1, XEXP (op0, 1)))
4596 36 : return simplify_gen_binary (AND, mode, XEXP (op0, 0),
4597 : simplify_gen_unary (NOT, mode,
4598 : XEXP (op0, 1),
4599 36 : mode));
4600 : /* (and (ior/xor Y X) (not Y)) -> X & ~Y */
4601 23495441 : if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
4602 23495441 : && negated_ops_p (op1, XEXP (op0, 0)))
4603 0 : return simplify_gen_binary (AND, mode, XEXP (op0, 1),
4604 : simplify_gen_unary (NOT, mode,
4605 : XEXP (op0, 0),
4606 0 : mode));
4607 :
4608 : /* Convert (and (ior A C) (ior B C)) into (ior (and A B) C). */
4609 23495441 : if (GET_CODE (op0) == GET_CODE (op1)
4610 2400046 : && (GET_CODE (op0) == AND
4611 : || GET_CODE (op0) == IOR
4612 2400046 : || GET_CODE (op0) == LSHIFTRT
4613 1382235 : || GET_CODE (op0) == ASHIFTRT
4614 1382095 : || GET_CODE (op0) == ASHIFT
4615 1381935 : || GET_CODE (op0) == ROTATE
4616 1381935 : || GET_CODE (op0) == ROTATERT))
4617 : {
4618 1018111 : tem = simplify_distributive_operation (code, mode, op0, op1);
4619 1018111 : if (tem)
4620 : return tem;
4621 : }
4622 :
4623 : /* (and:v4si
4624 : (ashiftrt:v4si A 16)
4625 : (const_vector: 0xffff x4))
4626 : is just (lshiftrt:v4si A 16). */
4627 22526027 : if (VECTOR_MODE_P (mode) && GET_CODE (op0) == ASHIFTRT
4628 4880 : && (CONST_INT_P (XEXP (op0, 1))
4629 2035 : || (GET_CODE (XEXP (op0, 1)) == CONST_VECTOR
4630 94 : && const_vec_duplicate_p (XEXP (op0, 1))
4631 0 : && CONST_INT_P (XVECEXP (XEXP (op0, 1), 0, 0))))
4632 2845 : && GET_CODE (op1) == CONST_VECTOR
4633 22526055 : && const_vec_duplicate_p (op1)
4634 22526097 : && CONST_INT_P (XVECEXP (op1, 0, 0)))
4635 : {
4636 136 : unsigned HOST_WIDE_INT shift_count
4637 : = (CONST_INT_P (XEXP (op0, 1))
4638 68 : ? UINTVAL (XEXP (op0, 1))
4639 0 : : UINTVAL (XVECEXP (XEXP (op0, 1), 0, 0)));
4640 68 : unsigned HOST_WIDE_INT inner_prec
4641 136 : = GET_MODE_PRECISION (GET_MODE_INNER (mode));
4642 :
4643 : /* Avoid UD shift count. */
4644 68 : if (shift_count < inner_prec
4645 56 : && (UINTVAL (XVECEXP (op1, 0, 0))
4646 56 : == (HOST_WIDE_INT_1U << (inner_prec - shift_count)) - 1))
4647 42 : return simplify_gen_binary (LSHIFTRT, mode, XEXP (op0, 0), XEXP (op0, 1));
4648 : }
4649 :
4650 22525985 : tem = simplify_with_subreg_not (code, mode, op0, op1);
4651 22525985 : if (tem)
4652 : return tem;
4653 :
4654 22523568 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
4655 22523568 : if (tem)
4656 : return tem;
4657 :
4658 22523347 : tem = simplify_associative_operation (code, mode, op0, op1);
4659 22523347 : if (tem)
4660 : return tem;
4661 : break;
4662 :
4663 901351 : case UDIV:
4664 : /* 0/x is 0 (or x&0 if x has side-effects). */
4665 901351 : if (trueop0 == CONST0_RTX (mode)
4666 392 : && !cfun->can_throw_non_call_exceptions)
4667 : {
4668 392 : if (side_effects_p (op1))
4669 0 : return simplify_gen_binary (AND, mode, op1, trueop0);
4670 : return trueop0;
4671 : }
4672 : /* x/1 is x. */
4673 900959 : if (trueop1 == CONST1_RTX (mode))
4674 : {
4675 242049 : tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4676 242049 : if (tem)
4677 : return tem;
4678 : }
4679 : /* Convert divide by power of two into shift. */
4680 658910 : if (CONST_INT_P (trueop1)
4681 984080 : && (val = exact_log2 (UINTVAL (trueop1))) > 0)
4682 325170 : return simplify_gen_binary (LSHIFTRT, mode, op0,
4683 325170 : gen_int_shift_amount (mode, val));
4684 : break;
4685 :
4686 1434182 : case DIV:
4687 : /* Handle floating point and integers separately. */
4688 1434182 : if (SCALAR_FLOAT_MODE_P (mode))
4689 : {
4690 : /* Maybe change 0.0 / x to 0.0. This transformation isn't
4691 : safe for modes with NaNs, since 0.0 / 0.0 will then be
4692 : NaN rather than 0.0. Nor is it safe for modes with signed
4693 : zeros, since dividing 0 by a negative number gives -0.0 */
4694 339673 : if (trueop0 == CONST0_RTX (mode)
4695 2817 : && !HONOR_NANS (mode)
4696 14 : && !HONOR_SIGNED_ZEROS (mode)
4697 339687 : && ! side_effects_p (op1))
4698 : return op0;
4699 : /* x/1.0 is x. */
4700 339659 : if (trueop1 == CONST1_RTX (mode)
4701 339659 : && !HONOR_SNANS (mode))
4702 : return op0;
4703 :
4704 339655 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
4705 35045 : && trueop1 != CONST0_RTX (mode))
4706 : {
4707 28975 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
4708 :
4709 : /* x/-1.0 is -x. */
4710 28975 : if (real_equal (d1, &dconstm1)
4711 28975 : && !HONOR_SNANS (mode))
4712 0 : return simplify_gen_unary (NEG, mode, op0, mode);
4713 :
4714 : /* Change FP division by a constant into multiplication.
4715 : Only do this with -freciprocal-math. */
4716 28975 : if (flag_reciprocal_math
4717 28975 : && !real_equal (d1, &dconst0))
4718 : {
4719 7 : REAL_VALUE_TYPE d;
4720 7 : real_arithmetic (&d, RDIV_EXPR, &dconst1, d1);
4721 7 : tem = const_double_from_real_value (d, mode);
4722 7 : return simplify_gen_binary (MULT, mode, op0, tem);
4723 : }
4724 : }
4725 : }
4726 1094509 : else if (SCALAR_INT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
4727 : {
4728 : /* 0/x is 0 (or x&0 if x has side-effects). */
4729 1062970 : if (trueop0 == CONST0_RTX (mode)
4730 984 : && !cfun->can_throw_non_call_exceptions)
4731 : {
4732 930 : if (side_effects_p (op1))
4733 8 : return simplify_gen_binary (AND, mode, op1, trueop0);
4734 : return trueop0;
4735 : }
4736 : /* x/1 is x. */
4737 1062040 : if (trueop1 == CONST1_RTX (mode))
4738 : {
4739 92 : tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4740 92 : if (tem)
4741 : return tem;
4742 : }
4743 : /* x/-1 is -x. */
4744 1061948 : if (trueop1 == CONSTM1_RTX (mode))
4745 : {
4746 512 : rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4747 512 : if (x)
4748 512 : return simplify_gen_unary (NEG, mode, x, mode);
4749 : }
4750 : }
4751 : break;
4752 :
4753 917913 : case UMOD:
4754 : /* 0%x is 0 (or x&0 if x has side-effects). */
4755 917913 : if (trueop0 == CONST0_RTX (mode))
4756 : {
4757 951 : if (side_effects_p (op1))
4758 0 : return simplify_gen_binary (AND, mode, op1, trueop0);
4759 : return trueop0;
4760 : }
4761 : /* x%1 is 0 (of x&0 if x has side-effects). */
4762 916962 : if (trueop1 == CONST1_RTX (mode))
4763 : {
4764 268596 : if (side_effects_p (op0))
4765 0 : return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
4766 268596 : return CONST0_RTX (mode);
4767 : }
4768 : /* Implement modulus by power of two as AND. */
4769 648366 : if (CONST_INT_P (trueop1)
4770 947327 : && exact_log2 (UINTVAL (trueop1)) > 0)
4771 298961 : return simplify_gen_binary (AND, mode, op0,
4772 298961 : gen_int_mode (UINTVAL (trueop1) - 1,
4773 : mode));
4774 : break;
4775 :
4776 580552 : case MOD:
4777 : /* 0%x is 0 (or x&0 if x has side-effects). */
4778 580552 : if (trueop0 == CONST0_RTX (mode))
4779 : {
4780 1216 : if (side_effects_p (op1))
4781 8 : return simplify_gen_binary (AND, mode, op1, trueop0);
4782 : return trueop0;
4783 : }
4784 : /* x%1 and x%-1 is 0 (or x&0 if x has side-effects). */
4785 579336 : if (trueop1 == CONST1_RTX (mode) || trueop1 == constm1_rtx)
4786 : {
4787 486 : if (side_effects_p (op0))
4788 0 : return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
4789 486 : return CONST0_RTX (mode);
4790 : }
4791 : break;
4792 :
4793 141031 : case ROTATERT:
4794 141031 : case ROTATE:
4795 141031 : if (trueop1 == CONST0_RTX (mode))
4796 : return op0;
4797 : /* Canonicalize rotates by constant amount. If the condition of
4798 : reversing direction is met, then reverse the direction. */
4799 : #if defined(HAVE_rotate) && defined(HAVE_rotatert)
4800 140941 : if (reverse_rotate_by_imm_p (mode, (code == ROTATE), trueop1))
4801 : {
4802 12173 : int new_amount = GET_MODE_UNIT_PRECISION (mode) - INTVAL (trueop1);
4803 12173 : rtx new_amount_rtx = gen_int_shift_amount (mode, new_amount);
4804 12899 : return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
4805 : mode, op0, new_amount_rtx);
4806 : }
4807 : #endif
4808 : /* ROTATE/ROTATERT:HI (X:HI, 8) is BSWAP:HI (X). Other combinations
4809 : such as SImode with a count of 16 do not correspond to RTL BSWAP
4810 : semantics. */
4811 128768 : tem = unwrap_const_vec_duplicate (trueop1);
4812 128768 : if (GET_MODE_UNIT_BITSIZE (mode) == (2 * BITS_PER_UNIT)
4813 128768 : && CONST_INT_P (tem) && INTVAL (tem) == BITS_PER_UNIT)
4814 666 : return simplify_gen_unary (BSWAP, mode, op0, mode);
4815 :
4816 : /* FALLTHRU */
4817 5506132 : case ASHIFTRT:
4818 5506132 : if (trueop1 == CONST0_RTX (mode))
4819 : return op0;
4820 5503850 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4821 : return op0;
4822 : /* Rotating ~0 always results in ~0. */
4823 5503669 : if (CONST_INT_P (trueop0)
4824 15591 : && HWI_COMPUTABLE_MODE_P (mode)
4825 15563 : && UINTVAL (trueop0) == GET_MODE_MASK (mode)
4826 5503669 : && ! side_effects_p (op1))
4827 : return op0;
4828 :
4829 32258396 : canonicalize_shift:
4830 : /* Given:
4831 : scalar modes M1, M2
4832 : scalar constants c1, c2
4833 : size (M2) > size (M1)
4834 : c1 == size (M2) - size (M1)
4835 : optimize:
4836 : ([a|l]shiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int <c1>))
4837 : <low_part>)
4838 : (const_int <c2>))
4839 : to:
4840 : (subreg:M1 ([a|l]shiftrt:M2 (reg:M2) (const_int <c1 + c2>))
4841 : <low_part>). */
4842 32258396 : if ((code == ASHIFTRT || code == LSHIFTRT)
4843 12347272 : && is_a <scalar_int_mode> (mode, &int_mode)
4844 11513871 : && SUBREG_P (op0)
4845 1262601 : && CONST_INT_P (op1)
4846 1259619 : && GET_CODE (SUBREG_REG (op0)) == LSHIFTRT
4847 19077 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op0)),
4848 : &inner_mode)
4849 19077 : && CONST_INT_P (XEXP (SUBREG_REG (op0), 1))
4850 37768 : && GET_MODE_BITSIZE (inner_mode) > GET_MODE_BITSIZE (int_mode)
4851 18884 : && (INTVAL (XEXP (SUBREG_REG (op0), 1))
4852 37768 : == GET_MODE_BITSIZE (inner_mode) - GET_MODE_BITSIZE (int_mode))
4853 32277031 : && subreg_lowpart_p (op0))
4854 : {
4855 18635 : rtx tmp = gen_int_shift_amount
4856 18635 : (inner_mode, INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (op1));
4857 :
4858 : /* Combine would usually zero out the value when combining two
4859 : local shifts and the range becomes larger or equal to the mode.
4860 : However since we fold away one of the shifts here combine won't
4861 : see it so we should immediately zero the result if it's out of
4862 : range. */
4863 18635 : if (code == LSHIFTRT
4864 33743 : && INTVAL (tmp) >= GET_MODE_BITSIZE (inner_mode))
4865 0 : tmp = const0_rtx;
4866 : else
4867 18635 : tmp = simplify_gen_binary (code,
4868 : inner_mode,
4869 18635 : XEXP (SUBREG_REG (op0), 0),
4870 : tmp);
4871 :
4872 18635 : return lowpart_subreg (int_mode, tmp, inner_mode);
4873 : }
4874 :
4875 32239761 : if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
4876 : {
4877 : val = INTVAL (op1) & (GET_MODE_UNIT_PRECISION (mode) - 1);
4878 : if (val != INTVAL (op1))
4879 : return simplify_gen_binary (code, mode, op0,
4880 : gen_int_shift_amount (mode, val));
4881 : }
4882 :
4883 : /* Simplify:
4884 :
4885 : (code:M1
4886 : (subreg:M1
4887 : ([al]shiftrt:M2
4888 : (subreg:M2
4889 : (ashift:M1 X C1))
4890 : C2))
4891 : C3)
4892 :
4893 : to:
4894 :
4895 : (code:M1
4896 : ([al]shiftrt:M1
4897 : (ashift:M1 X C1+N)
4898 : C2+N)
4899 : C3)
4900 :
4901 : where M1 is N bits wider than M2. Optimizing the (subreg:M1 ...)
4902 : directly would be arithmetically correct, but restricting the
4903 : simplification to shifts by constants is more conservative,
4904 : since it is more likely to lead to further simplifications. */
4905 32239761 : if (is_a<scalar_int_mode> (mode, &int_mode)
4906 5688466 : && paradoxical_subreg_p (op0)
4907 5170204 : && is_a<scalar_int_mode> (GET_MODE (SUBREG_REG (op0)), &inner_mode)
4908 5145757 : && (GET_CODE (SUBREG_REG (op0)) == ASHIFTRT
4909 5145757 : || GET_CODE (SUBREG_REG (op0)) == LSHIFTRT)
4910 135467 : && CONST_INT_P (op1))
4911 : {
4912 135467 : auto xcode = GET_CODE (SUBREG_REG (op0));
4913 135467 : rtx xop0 = XEXP (SUBREG_REG (op0), 0);
4914 135467 : rtx xop1 = XEXP (SUBREG_REG (op0), 1);
4915 135467 : if (SUBREG_P (xop0)
4916 10087 : && GET_MODE (SUBREG_REG (xop0)) == mode
4917 9964 : && GET_CODE (SUBREG_REG (xop0)) == ASHIFT
4918 595 : && CONST_INT_P (xop1)
4919 136062 : && UINTVAL (xop1) < GET_MODE_PRECISION (inner_mode))
4920 : {
4921 595 : rtx yop0 = XEXP (SUBREG_REG (xop0), 0);
4922 595 : rtx yop1 = XEXP (SUBREG_REG (xop0), 1);
4923 595 : if (CONST_INT_P (yop1)
4924 595 : && UINTVAL (yop1) < GET_MODE_PRECISION (inner_mode))
4925 : {
4926 1190 : auto bias = (GET_MODE_BITSIZE (int_mode)
4927 595 : - GET_MODE_BITSIZE (inner_mode));
4928 595 : tem = simplify_gen_binary (ASHIFT, mode, yop0,
4929 595 : GEN_INT (INTVAL (yop1) + bias));
4930 595 : tem = simplify_gen_binary (xcode, mode, tem,
4931 595 : GEN_INT (INTVAL (xop1) + bias));
4932 595 : return simplify_gen_binary (code, mode, tem, op1);
4933 : }
4934 : }
4935 : }
4936 : break;
4937 :
4938 0 : case SS_ASHIFT:
4939 0 : if (CONST_INT_P (trueop0)
4940 0 : && HWI_COMPUTABLE_MODE_P (mode)
4941 0 : && (UINTVAL (trueop0) == (GET_MODE_MASK (mode) >> 1)
4942 0 : || mode_signbit_p (mode, trueop0))
4943 0 : && ! side_effects_p (op1))
4944 : return op0;
4945 0 : goto simplify_ashift;
4946 :
4947 0 : case US_ASHIFT:
4948 0 : if (CONST_INT_P (trueop0)
4949 0 : && HWI_COMPUTABLE_MODE_P (mode)
4950 0 : && UINTVAL (trueop0) == GET_MODE_MASK (mode)
4951 0 : && ! side_effects_p (op1))
4952 : return op0;
4953 : /* FALLTHRU */
4954 :
4955 20199380 : case ASHIFT:
4956 20199380 : simplify_ashift:
4957 20199380 : if (trueop1 == CONST0_RTX (mode))
4958 : return op0;
4959 20029101 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4960 : return op0;
4961 19999410 : if (mem_depth
4962 216357 : && code == ASHIFT
4963 216357 : && CONST_INT_P (trueop1)
4964 216349 : && is_a <scalar_int_mode> (mode, &int_mode)
4965 20215747 : && IN_RANGE (UINTVAL (trueop1),
4966 : 1, GET_MODE_PRECISION (int_mode) - 1))
4967 : {
4968 216337 : auto c = (wi::one (GET_MODE_PRECISION (int_mode))
4969 216337 : << UINTVAL (trueop1));
4970 216337 : rtx new_op1 = immed_wide_int_const (c, int_mode);
4971 216337 : return simplify_gen_binary (MULT, int_mode, op0, new_op1);
4972 216337 : }
4973 :
4974 : /* If we're shifting left a signed bitfield extraction and the
4975 : shift count + bitfield size is a natural integral mode and
4976 : the field starts at offset 0 (counting from the LSB), then
4977 : this can be simplified to a sign extension of a left shift.
4978 :
4979 : Some ISAs (RISC-V 64-bit) have inherent support for such
4980 : instructions and it's better for various optimizations to
4981 : express as a SIGN_EXTEND rather than a shifted SIGN_EXTRACT. */
4982 19783073 : if (GET_CODE (op0) == SIGN_EXTRACT
4983 26 : && REG_P (XEXP (op0, 0))
4984 : /* The size of the bitfield, the location of the bitfield and
4985 : shift count must be CONST_INTs. */
4986 20 : && CONST_INT_P (op1)
4987 20 : && CONST_INT_P (XEXP (op0, 1))
4988 20 : && CONST_INT_P (XEXP (op0, 2)))
4989 : {
4990 20 : int size = INTVAL (op1) + INTVAL (XEXP (op0, 1));
4991 20 : machine_mode smaller_mode;
4992 : /* Now we need to verify the size of the bitfield plus the shift
4993 : count is an integral mode and smaller than MODE. This is
4994 : requirement for using SIGN_EXTEND. We also need to verify the
4995 : field starts at bit location 0 and that the subreg lowpart also
4996 : starts at zero. */
4997 20 : if (int_mode_for_size (size, size).exists (&smaller_mode)
4998 1 : && mode > smaller_mode
4999 20 : && (subreg_lowpart_offset (smaller_mode, mode).to_constant ()
5000 1 : == UINTVAL (XEXP (op0, 2)))
5001 1 : && XEXP (op0, 2) == CONST0_RTX (mode))
5002 : {
5003 : /* Everything passed. So we just need to get the subreg of the
5004 : original input, shift it and sign extend the result. */
5005 1 : rtx op = gen_lowpart (smaller_mode, XEXP (op0, 0));
5006 1 : rtx x = gen_rtx_ASHIFT (smaller_mode, op, op1);
5007 1 : return gen_rtx_SIGN_EXTEND (mode, x);
5008 : }
5009 : }
5010 19783072 : goto canonicalize_shift;
5011 :
5012 8759306 : case LSHIFTRT:
5013 8759306 : if (trueop1 == CONST0_RTX (mode))
5014 : return op0;
5015 6973235 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
5016 : return op0;
5017 : /* Optimize (lshiftrt (clz X) C) as (eq X 0). */
5018 6971655 : if (GET_CODE (op0) == CLZ
5019 0 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
5020 0 : && CONST_INT_P (trueop1)
5021 : && STORE_FLAG_VALUE == 1
5022 6971655 : && INTVAL (trueop1) < GET_MODE_UNIT_PRECISION (mode))
5023 : {
5024 0 : unsigned HOST_WIDE_INT zero_val = 0;
5025 :
5026 0 : if (CLZ_DEFINED_VALUE_AT_ZERO (inner_mode, zero_val)
5027 0 : && zero_val == GET_MODE_PRECISION (inner_mode)
5028 0 : && INTVAL (trueop1) == exact_log2 (zero_val))
5029 0 : return simplify_gen_relational (EQ, mode, inner_mode,
5030 0 : XEXP (op0, 0), const0_rtx);
5031 : }
5032 6971655 : goto canonicalize_shift;
5033 :
5034 228636 : case SMIN:
5035 228636 : if (HWI_COMPUTABLE_MODE_P (mode)
5036 207702 : && mode_signbit_p (mode, trueop1)
5037 0 : && ! side_effects_p (op0))
5038 : return op1;
5039 228636 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5040 : return op0;
5041 228458 : tem = simplify_associative_operation (code, mode, op0, op1);
5042 228458 : if (tem)
5043 : return tem;
5044 : break;
5045 :
5046 716630 : case SMAX:
5047 716630 : if (HWI_COMPUTABLE_MODE_P (mode)
5048 688557 : && CONST_INT_P (trueop1)
5049 655034 : && (UINTVAL (trueop1) == GET_MODE_MASK (mode) >> 1)
5050 0 : && ! side_effects_p (op0))
5051 : return op1;
5052 716630 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5053 : return op0;
5054 716523 : tem = simplify_associative_operation (code, mode, op0, op1);
5055 716523 : if (tem)
5056 : return tem;
5057 : break;
5058 :
5059 427944 : case UMIN:
5060 427944 : if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
5061 : return op1;
5062 427869 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5063 : return op0;
5064 427750 : tem = simplify_associative_operation (code, mode, op0, op1);
5065 427750 : if (tem)
5066 : return tem;
5067 : break;
5068 :
5069 378810 : case UMAX:
5070 378810 : if (trueop1 == constm1_rtx && ! side_effects_p (op0))
5071 : return op1;
5072 378810 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5073 : return op0;
5074 378720 : tem = simplify_associative_operation (code, mode, op0, op1);
5075 378720 : if (tem)
5076 : return tem;
5077 : break;
5078 :
5079 12130 : case SS_PLUS:
5080 12130 : case US_PLUS:
5081 12130 : case SS_MINUS:
5082 12130 : case US_MINUS:
5083 : /* Simplify x +/- 0 to x, if possible. */
5084 12130 : if (trueop1 == CONST0_RTX (mode))
5085 0 : return op0;
5086 : return 0;
5087 :
5088 0 : case SS_MULT:
5089 0 : case US_MULT:
5090 : /* Simplify x * 0 to 0, if possible. */
5091 0 : if (trueop1 == CONST0_RTX (mode)
5092 0 : && !side_effects_p (op0))
5093 : return op1;
5094 :
5095 : /* Simplify x * 1 to x, if possible. */
5096 0 : if (trueop1 == CONST1_RTX (mode))
5097 0 : return op0;
5098 : return 0;
5099 :
5100 201164 : case SMUL_HIGHPART:
5101 : /* Simplify x h* 0 to 0, if possible. */
5102 201164 : if (trueop1 == CONST0_RTX (mode)
5103 201164 : && !side_effects_p (op0))
5104 : return op1;
5105 : /* Simplify x h* 1 to sign(x). */
5106 201164 : if (trueop1 == const1_rtx
5107 201164 : && is_a <scalar_int_mode> (mode, &int_mode))
5108 : {
5109 0 : HOST_WIDE_INT bits = GET_MODE_PRECISION (int_mode) - 1;
5110 0 : return simplify_gen_binary (ASHIFTRT, mode, op0,
5111 0 : gen_int_shift_amount (mode, bits));
5112 : }
5113 : /* Simplify SMUL_HIGHPART by power of two as ASHIFRT. */
5114 201164 : if (CONST_INT_P (trueop1)
5115 89990 : && INTVAL (trueop1) > 1
5116 277830 : && is_a <scalar_int_mode> (mode, &int_mode))
5117 : {
5118 76666 : HOST_WIDE_INT prec = GET_MODE_PRECISION (int_mode);
5119 76666 : val = wi::exact_log2 (INTVAL (trueop1));
5120 76666 : if (val > 0 && val < prec)
5121 0 : return simplify_gen_binary (ASHIFTRT, mode, op0,
5122 : gen_int_shift_amount (mode,
5123 0 : prec - val));
5124 : }
5125 : return 0;
5126 :
5127 309866 : case UMUL_HIGHPART:
5128 : /* Simplify x h* 0 to 0, if possible. */
5129 309866 : if (trueop1 == CONST0_RTX (mode)
5130 309866 : && !side_effects_p (op0))
5131 : return op1;
5132 : /* Simplify x h* 1 to 0. */
5133 309792 : if (trueop1 == CONST1_RTX (mode)
5134 309792 : && !side_effects_p (op1))
5135 0 : return CONST0_RTX (mode);
5136 : /* Simplify UMUL_HIGHPART by power of two as LSHIFRT. */
5137 309792 : if (CONST_INT_P (trueop1)
5138 156098 : && UINTVAL (trueop1) > 1
5139 465890 : && is_a <scalar_int_mode> (mode, &int_mode))
5140 : {
5141 156098 : HOST_WIDE_INT prec = GET_MODE_PRECISION (int_mode);
5142 156098 : val = wi::exact_log2 (UINTVAL (trueop1));
5143 156098 : if (val > 0 && val < prec)
5144 58 : return simplify_gen_binary (LSHIFTRT, mode, op0,
5145 : gen_int_shift_amount (mode,
5146 58 : prec - val));
5147 : }
5148 : return 0;
5149 :
5150 0 : case SS_DIV:
5151 0 : case US_DIV:
5152 : /* Simplify x / 1 to x, if possible. */
5153 0 : if (trueop1 == CONST1_RTX (mode))
5154 0 : return op0;
5155 : return 0;
5156 :
5157 0 : case COPYSIGN:
5158 0 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
5159 : return op0;
5160 0 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1))
5161 : {
5162 0 : REAL_VALUE_TYPE f1;
5163 0 : real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (trueop1));
5164 0 : rtx tmp = simplify_gen_unary (ABS, mode, op0, mode);
5165 0 : if (REAL_VALUE_NEGATIVE (f1))
5166 0 : tmp = simplify_unary_operation (NEG, mode, tmp, mode);
5167 0 : return tmp;
5168 : }
5169 0 : if (GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
5170 0 : return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
5171 0 : if (GET_CODE (op1) == ABS
5172 0 : && ! side_effects_p (op1))
5173 0 : return simplify_gen_unary (ABS, mode, op0, mode);
5174 0 : if (GET_CODE (op0) == COPYSIGN
5175 0 : && ! side_effects_p (XEXP (op0, 1)))
5176 0 : return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
5177 0 : if (GET_CODE (op1) == COPYSIGN
5178 0 : && ! side_effects_p (XEXP (op1, 0)))
5179 0 : return simplify_gen_binary (COPYSIGN, mode, op0, XEXP (op1, 1));
5180 : return 0;
5181 :
5182 1115 : case VEC_SERIES:
5183 2230 : if (op1 == CONST0_RTX (GET_MODE_INNER (mode)))
5184 92 : return gen_vec_duplicate (mode, op0);
5185 1023 : if (valid_for_const_vector_p (mode, op0)
5186 1023 : && valid_for_const_vector_p (mode, op1))
5187 93 : return gen_const_vec_series (mode, op0, op1);
5188 : return 0;
5189 :
5190 3748746 : case VEC_SELECT:
5191 3748746 : if (!VECTOR_MODE_P (mode))
5192 : {
5193 826211 : gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
5194 1652422 : gcc_assert (mode == GET_MODE_INNER (GET_MODE (trueop0)));
5195 826211 : gcc_assert (GET_CODE (trueop1) == PARALLEL);
5196 826211 : gcc_assert (XVECLEN (trueop1, 0) == 1);
5197 :
5198 : /* We can't reason about selections made at runtime. */
5199 826211 : if (!CONST_INT_P (XVECEXP (trueop1, 0, 0)))
5200 465407793 : return 0;
5201 :
5202 826211 : if (vec_duplicate_p (trueop0, &elt0))
5203 2020 : return elt0;
5204 :
5205 824191 : if (GET_CODE (trueop0) == CONST_VECTOR)
5206 7345 : return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP
5207 : (trueop1, 0, 0)));
5208 :
5209 : /* Extract a scalar element from a nested VEC_SELECT expression
5210 : (with optional nested VEC_CONCAT expression). Some targets
5211 : (i386) extract scalar element from a vector using chain of
5212 : nested VEC_SELECT expressions. When input operand is a memory
5213 : operand, this operation can be simplified to a simple scalar
5214 : load from an offsetted memory address. */
5215 816846 : int n_elts;
5216 816846 : if (GET_CODE (trueop0) == VEC_SELECT
5217 889783 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
5218 72937 : .is_constant (&n_elts)))
5219 : {
5220 72937 : rtx op0 = XEXP (trueop0, 0);
5221 72937 : rtx op1 = XEXP (trueop0, 1);
5222 :
5223 72937 : int i = INTVAL (XVECEXP (trueop1, 0, 0));
5224 72937 : int elem;
5225 :
5226 72937 : rtvec vec;
5227 72937 : rtx tmp_op, tmp;
5228 :
5229 72937 : gcc_assert (GET_CODE (op1) == PARALLEL);
5230 72937 : gcc_assert (i < XVECLEN (op1, 0));
5231 :
5232 : /* Select element, pointed by nested selector. */
5233 72937 : elem = INTVAL (XVECEXP (op1, 0, i));
5234 :
5235 72937 : gcc_assert (elem < n_elts);
5236 :
5237 : /* Handle the case when nested VEC_SELECT wraps VEC_CONCAT. */
5238 72937 : if (GET_CODE (op0) == VEC_CONCAT)
5239 : {
5240 30068 : rtx op00 = XEXP (op0, 0);
5241 30068 : rtx op01 = XEXP (op0, 1);
5242 :
5243 30068 : machine_mode mode00, mode01;
5244 30068 : int n_elts00, n_elts01;
5245 :
5246 30068 : mode00 = GET_MODE (op00);
5247 30068 : mode01 = GET_MODE (op01);
5248 :
5249 : /* Find out the number of elements of each operand.
5250 : Since the concatenated result has a constant number
5251 : of elements, the operands must too. */
5252 30068 : n_elts00 = GET_MODE_NUNITS (mode00).to_constant ();
5253 30068 : n_elts01 = GET_MODE_NUNITS (mode01).to_constant ();
5254 :
5255 30068 : gcc_assert (n_elts == n_elts00 + n_elts01);
5256 :
5257 : /* Select correct operand of VEC_CONCAT
5258 : and adjust selector. */
5259 30068 : if (elem < n_elts01)
5260 : tmp_op = op00;
5261 : else
5262 : {
5263 41 : tmp_op = op01;
5264 41 : elem -= n_elts00;
5265 : }
5266 : }
5267 : else
5268 : tmp_op = op0;
5269 :
5270 72937 : vec = rtvec_alloc (1);
5271 72937 : RTVEC_ELT (vec, 0) = GEN_INT (elem);
5272 :
5273 72937 : tmp = gen_rtx_fmt_ee (code, mode,
5274 : tmp_op, gen_rtx_PARALLEL (VOIDmode, vec));
5275 72937 : return tmp;
5276 : }
5277 : /* If we select one half of a vec_concat, return that. */
5278 743909 : else if (GET_CODE (trueop0) == VEC_CONCAT)
5279 : {
5280 725 : rtx subop0 = XEXP (trueop0, 0);
5281 725 : rtx subop1 = XEXP (trueop0, 1);
5282 725 : machine_mode mode0 = GET_MODE (subop0);
5283 725 : machine_mode mode1 = GET_MODE (subop1);
5284 725 : int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5285 725 : if (i0 == 0 && mode == mode0 && !side_effects_p (subop1))
5286 465407793 : return subop0;
5287 490 : if (known_eq (i0, GET_MODE_NUNITS (mode0))
5288 245 : && mode == mode1 && !side_effects_p (subop0))
5289 : return subop1;
5290 : }
5291 : }
5292 : else
5293 : {
5294 2922535 : gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
5295 8767605 : gcc_assert (GET_MODE_INNER (mode)
5296 : == GET_MODE_INNER (GET_MODE (trueop0)));
5297 2922535 : gcc_assert (GET_CODE (trueop1) == PARALLEL);
5298 :
5299 2922535 : if (vec_duplicate_p (trueop0, &elt0))
5300 : /* It doesn't matter which elements are selected by trueop1,
5301 : because they are all the same. */
5302 17682 : return gen_vec_duplicate (mode, elt0);
5303 :
5304 2904853 : if (GET_CODE (trueop0) == CONST_VECTOR)
5305 : {
5306 25922 : unsigned n_elts = XVECLEN (trueop1, 0);
5307 25922 : rtvec v = rtvec_alloc (n_elts);
5308 25922 : unsigned int i;
5309 :
5310 51844 : gcc_assert (known_eq (n_elts, GET_MODE_NUNITS (mode)));
5311 107420 : for (i = 0; i < n_elts; i++)
5312 : {
5313 81498 : rtx x = XVECEXP (trueop1, 0, i);
5314 :
5315 81498 : if (!CONST_INT_P (x))
5316 : return 0;
5317 :
5318 81498 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0,
5319 : INTVAL (x));
5320 : }
5321 :
5322 25922 : return gen_rtx_CONST_VECTOR (mode, v);
5323 : }
5324 :
5325 : /* Recognize the identity. */
5326 2878931 : if (GET_MODE (trueop0) == mode)
5327 : {
5328 618127 : bool maybe_ident = true;
5329 618127 : for (int i = 0; i < XVECLEN (trueop1, 0); i++)
5330 : {
5331 617730 : rtx j = XVECEXP (trueop1, 0, i);
5332 617730 : if (!CONST_INT_P (j) || INTVAL (j) != i)
5333 : {
5334 : maybe_ident = false;
5335 : break;
5336 : }
5337 : }
5338 381872 : if (maybe_ident)
5339 : return trueop0;
5340 : }
5341 :
5342 : /* If we select a low-part subreg, return that. */
5343 2878534 : if (vec_series_lowpart_p (mode, GET_MODE (trueop0), trueop1))
5344 : {
5345 0 : rtx new_rtx = lowpart_subreg (mode, trueop0,
5346 0 : GET_MODE (trueop0));
5347 0 : if (new_rtx != NULL_RTX)
5348 : return new_rtx;
5349 : }
5350 :
5351 : /* If we build {a,b} then permute it, build the result directly. */
5352 2878534 : if (XVECLEN (trueop1, 0) == 2
5353 637569 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
5354 637569 : && CONST_INT_P (XVECEXP (trueop1, 0, 1))
5355 637569 : && GET_CODE (trueop0) == VEC_CONCAT
5356 168114 : && GET_CODE (XEXP (trueop0, 0)) == VEC_CONCAT
5357 63 : && GET_MODE (XEXP (trueop0, 0)) == mode
5358 63 : && GET_CODE (XEXP (trueop0, 1)) == VEC_CONCAT
5359 52 : && GET_MODE (XEXP (trueop0, 1)) == mode)
5360 : {
5361 52 : unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5362 52 : unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
5363 52 : rtx subop0, subop1;
5364 :
5365 52 : gcc_assert (i0 < 4 && i1 < 4);
5366 52 : subop0 = XEXP (XEXP (trueop0, i0 / 2), i0 % 2);
5367 52 : subop1 = XEXP (XEXP (trueop0, i1 / 2), i1 % 2);
5368 :
5369 52 : return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
5370 : }
5371 :
5372 2878482 : if (XVECLEN (trueop1, 0) == 2
5373 637517 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
5374 637517 : && CONST_INT_P (XVECEXP (trueop1, 0, 1))
5375 637517 : && GET_CODE (trueop0) == VEC_CONCAT
5376 168062 : && GET_MODE (trueop0) == mode)
5377 : {
5378 2 : unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5379 2 : unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
5380 2 : rtx subop0, subop1;
5381 :
5382 2 : gcc_assert (i0 < 2 && i1 < 2);
5383 2 : subop0 = XEXP (trueop0, i0);
5384 2 : subop1 = XEXP (trueop0, i1);
5385 :
5386 2 : return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
5387 : }
5388 :
5389 : /* If we select one half of a vec_concat, return that. */
5390 2878480 : int l0, l1;
5391 2878480 : if (GET_CODE (trueop0) == VEC_CONCAT
5392 3740948 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
5393 1870474 : .is_constant (&l0))
5394 3740948 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 1)))
5395 1870474 : .is_constant (&l1))
5396 4748954 : && CONST_INT_P (XVECEXP (trueop1, 0, 0)))
5397 : {
5398 1870474 : rtx subop0 = XEXP (trueop0, 0);
5399 1870474 : rtx subop1 = XEXP (trueop0, 1);
5400 1870474 : machine_mode mode0 = GET_MODE (subop0);
5401 1870474 : machine_mode mode1 = GET_MODE (subop1);
5402 1870474 : int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5403 1870474 : if (i0 == 0 && !side_effects_p (op1) && mode == mode0)
5404 : {
5405 1425708 : bool success = true;
5406 1425708 : for (int i = 1; i < l0; ++i)
5407 : {
5408 1425382 : rtx j = XVECEXP (trueop1, 0, i);
5409 1425382 : if (!CONST_INT_P (j) || INTVAL (j) != i)
5410 : {
5411 : success = false;
5412 : break;
5413 : }
5414 : }
5415 1211064 : if (success)
5416 : return subop0;
5417 : }
5418 1870148 : if (i0 == l0 && !side_effects_p (op0) && mode == mode1)
5419 : {
5420 1234 : bool success = true;
5421 1234 : for (int i = 1; i < l1; ++i)
5422 : {
5423 1187 : rtx j = XVECEXP (trueop1, 0, i);
5424 1187 : if (!CONST_INT_P (j) || INTVAL (j) != i0 + i)
5425 : {
5426 : success = false;
5427 : break;
5428 : }
5429 : }
5430 560 : if (success)
5431 : return subop1;
5432 : }
5433 : }
5434 :
5435 : /* Simplify vec_select of a subreg of X to just a vec_select of X
5436 : when X has same component mode as vec_select. */
5437 2878107 : unsigned HOST_WIDE_INT subreg_offset = 0;
5438 2878107 : if (GET_CODE (trueop0) == SUBREG
5439 416018 : && GET_MODE_INNER (mode)
5440 832036 : == GET_MODE_INNER (GET_MODE (SUBREG_REG (trueop0)))
5441 29894 : && GET_MODE_NUNITS (mode).is_constant (&l1)
5442 3294125 : && constant_multiple_p (subreg_memory_offset (trueop0),
5443 29894 : GET_MODE_UNIT_BITSIZE (mode),
5444 : &subreg_offset))
5445 : {
5446 14947 : poly_uint64 nunits
5447 29894 : = GET_MODE_NUNITS (GET_MODE (SUBREG_REG (trueop0)));
5448 14947 : bool success = true;
5449 91723 : for (int i = 0; i != l1; i++)
5450 : {
5451 87125 : rtx idx = XVECEXP (trueop1, 0, i);
5452 87125 : if (!CONST_INT_P (idx)
5453 87125 : || maybe_ge (UINTVAL (idx) + subreg_offset, nunits))
5454 : {
5455 : success = false;
5456 : break;
5457 : }
5458 : }
5459 :
5460 14947 : if (success)
5461 : {
5462 4598 : rtx par = trueop1;
5463 4598 : if (subreg_offset)
5464 : {
5465 0 : rtvec vec = rtvec_alloc (l1);
5466 0 : for (int i = 0; i < l1; i++)
5467 0 : RTVEC_ELT (vec, i)
5468 0 : = GEN_INT (INTVAL (XVECEXP (trueop1, 0, i))
5469 : + subreg_offset);
5470 0 : par = gen_rtx_PARALLEL (VOIDmode, vec);
5471 : }
5472 4598 : return gen_rtx_VEC_SELECT (mode, SUBREG_REG (trueop0), par);
5473 : }
5474 : }
5475 : }
5476 :
5477 3616878 : if (XVECLEN (trueop1, 0) == 1
5478 743453 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
5479 743453 : && GET_CODE (trueop0) == VEC_CONCAT)
5480 : {
5481 185 : rtx vec = trueop0;
5482 370 : offset = INTVAL (XVECEXP (trueop1, 0, 0)) * GET_MODE_SIZE (mode);
5483 :
5484 : /* Try to find the element in the VEC_CONCAT. */
5485 185 : while (GET_MODE (vec) != mode
5486 370 : && GET_CODE (vec) == VEC_CONCAT)
5487 : {
5488 185 : poly_int64 vec_size;
5489 :
5490 185 : if (CONST_INT_P (XEXP (vec, 0)))
5491 : {
5492 : /* vec_concat of two const_ints doesn't make sense with
5493 : respect to modes. */
5494 0 : if (CONST_INT_P (XEXP (vec, 1)))
5495 465407793 : return 0;
5496 :
5497 0 : vec_size = GET_MODE_SIZE (GET_MODE (trueop0))
5498 0 : - GET_MODE_SIZE (GET_MODE (XEXP (vec, 1)));
5499 : }
5500 : else
5501 370 : vec_size = GET_MODE_SIZE (GET_MODE (XEXP (vec, 0)));
5502 :
5503 185 : if (known_lt (offset, vec_size))
5504 : vec = XEXP (vec, 0);
5505 15 : else if (known_ge (offset, vec_size))
5506 : {
5507 15 : offset -= vec_size;
5508 15 : vec = XEXP (vec, 1);
5509 : }
5510 : else
5511 : break;
5512 185 : vec = avoid_constant_pool_reference (vec);
5513 : }
5514 :
5515 185 : if (GET_MODE (vec) == mode)
5516 : return vec;
5517 : }
5518 :
5519 : /* If we select elements in a vec_merge that all come from the same
5520 : operand, select from that operand directly. */
5521 3616878 : if (GET_CODE (op0) == VEC_MERGE)
5522 : {
5523 9282 : rtx trueop02 = avoid_constant_pool_reference (XEXP (op0, 2));
5524 9282 : if (CONST_INT_P (trueop02))
5525 : {
5526 2871 : unsigned HOST_WIDE_INT sel = UINTVAL (trueop02);
5527 2871 : bool all_operand0 = true;
5528 2871 : bool all_operand1 = true;
5529 10689 : for (int i = 0; i < XVECLEN (trueop1, 0); i++)
5530 : {
5531 7818 : rtx j = XVECEXP (trueop1, 0, i);
5532 7818 : if (sel & (HOST_WIDE_INT_1U << UINTVAL (j)))
5533 : all_operand1 = false;
5534 : else
5535 3504 : all_operand0 = false;
5536 : }
5537 2871 : if (all_operand0 && !side_effects_p (XEXP (op0, 1)))
5538 1340 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 0), op1);
5539 1531 : if (all_operand1 && !side_effects_p (XEXP (op0, 0)))
5540 55 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 1), op1);
5541 : }
5542 : }
5543 :
5544 : /* If we have two nested selects that are inverses of each
5545 : other, replace them with the source operand. */
5546 3615483 : if (GET_CODE (trueop0) == VEC_SELECT
5547 72502 : && GET_MODE (XEXP (trueop0, 0)) == mode)
5548 : {
5549 1048 : rtx op0_subop1 = XEXP (trueop0, 1);
5550 1048 : gcc_assert (GET_CODE (op0_subop1) == PARALLEL);
5551 2096 : gcc_assert (known_eq (XVECLEN (trueop1, 0), GET_MODE_NUNITS (mode)));
5552 : bool identical_p = true;
5553 :
5554 : /* Apply the outer ordering vector to the inner one. (The inner
5555 : ordering vector is expressly permitted to be of a different
5556 : length than the outer one.) If the result is { 0, 1, ..., n-1 }
5557 : then the two VEC_SELECTs cancel. */
5558 9068 : for (int i = 0; i < XVECLEN (trueop1, 0); ++i)
5559 : {
5560 8020 : rtx x = XVECEXP (trueop1, 0, i);
5561 8020 : if (!CONST_INT_P (x))
5562 : return 0;
5563 8020 : rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
5564 8020 : if (!CONST_INT_P (y))
5565 : return 0;
5566 8020 : if (i != INTVAL (y))
5567 5918 : identical_p = false;
5568 : }
5569 1048 : if (identical_p)
5570 : return XEXP (trueop0, 0);
5571 :
5572 : /* Otherwise a permutation of a permutation is a permutation. */
5573 1048 : int len = XVECLEN (trueop1, 0);
5574 1048 : rtvec vec = rtvec_alloc (len);
5575 10116 : for (int i = 0; i < len; ++i)
5576 : {
5577 8020 : rtx x = XVECEXP (trueop1, 0, i);
5578 8020 : rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
5579 8020 : RTVEC_ELT (vec, i) = y;
5580 : }
5581 1048 : return gen_rtx_fmt_ee (code, mode, XEXP (trueop0, 0),
5582 : gen_rtx_PARALLEL (VOIDmode, vec));
5583 : }
5584 :
5585 : return 0;
5586 4090776 : case VEC_CONCAT:
5587 4090776 : {
5588 4090776 : machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
5589 4090776 : ? GET_MODE (trueop0)
5590 4090776 : : GET_MODE_INNER (mode));
5591 4090776 : machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
5592 4090776 : ? GET_MODE (trueop1)
5593 4090776 : : GET_MODE_INNER (mode));
5594 :
5595 4090776 : gcc_assert (VECTOR_MODE_P (mode));
5596 16363104 : gcc_assert (known_eq (GET_MODE_SIZE (op0_mode)
5597 : + GET_MODE_SIZE (op1_mode),
5598 : GET_MODE_SIZE (mode)));
5599 :
5600 4090776 : if (VECTOR_MODE_P (op0_mode))
5601 6382827 : gcc_assert (GET_MODE_INNER (mode)
5602 : == GET_MODE_INNER (op0_mode));
5603 : else
5604 3926334 : gcc_assert (GET_MODE_INNER (mode) == op0_mode);
5605 :
5606 4090776 : if (VECTOR_MODE_P (op1_mode))
5607 6382827 : gcc_assert (GET_MODE_INNER (mode)
5608 : == GET_MODE_INNER (op1_mode));
5609 : else
5610 3926334 : gcc_assert (GET_MODE_INNER (mode) == op1_mode);
5611 :
5612 4090776 : unsigned int n_elts, in_n_elts;
5613 4090776 : if ((GET_CODE (trueop0) == CONST_VECTOR
5614 4090776 : || CONST_SCALAR_INT_P (trueop0)
5615 4064001 : || CONST_DOUBLE_AS_FLOAT_P (trueop0))
5616 28225 : && (GET_CODE (trueop1) == CONST_VECTOR
5617 28225 : || CONST_SCALAR_INT_P (trueop1)
5618 28225 : || CONST_DOUBLE_AS_FLOAT_P (trueop1))
5619 0 : && GET_MODE_NUNITS (mode).is_constant (&n_elts)
5620 4090776 : && GET_MODE_NUNITS (op0_mode).is_constant (&in_n_elts))
5621 : {
5622 0 : rtvec v = rtvec_alloc (n_elts);
5623 0 : unsigned int i;
5624 0 : for (i = 0; i < n_elts; i++)
5625 : {
5626 0 : if (i < in_n_elts)
5627 : {
5628 0 : if (!VECTOR_MODE_P (op0_mode))
5629 0 : RTVEC_ELT (v, i) = trueop0;
5630 : else
5631 0 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
5632 : }
5633 : else
5634 : {
5635 0 : if (!VECTOR_MODE_P (op1_mode))
5636 0 : RTVEC_ELT (v, i) = trueop1;
5637 : else
5638 0 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
5639 : i - in_n_elts);
5640 : }
5641 : }
5642 :
5643 0 : return gen_rtx_CONST_VECTOR (mode, v);
5644 : }
5645 :
5646 : /* Try to merge two VEC_SELECTs from the same vector into a single one.
5647 : Restrict the transformation to avoid generating a VEC_SELECT with a
5648 : mode unrelated to its operand. */
5649 4090776 : if (GET_CODE (trueop0) == VEC_SELECT
5650 180046 : && GET_CODE (trueop1) == VEC_SELECT
5651 36098 : && rtx_equal_p (XEXP (trueop0, 0), XEXP (trueop1, 0))
5652 4109406 : && GET_MODE_INNER (GET_MODE (XEXP (trueop0, 0)))
5653 37260 : == GET_MODE_INNER(mode))
5654 : {
5655 18630 : rtx par0 = XEXP (trueop0, 1);
5656 18630 : rtx par1 = XEXP (trueop1, 1);
5657 18630 : int len0 = XVECLEN (par0, 0);
5658 18630 : int len1 = XVECLEN (par1, 0);
5659 18630 : rtvec vec = rtvec_alloc (len0 + len1);
5660 131358 : for (int i = 0; i < len0; i++)
5661 94098 : RTVEC_ELT (vec, i) = XVECEXP (par0, 0, i);
5662 112728 : for (int i = 0; i < len1; i++)
5663 94098 : RTVEC_ELT (vec, len0 + i) = XVECEXP (par1, 0, i);
5664 18630 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (trueop0, 0),
5665 18630 : gen_rtx_PARALLEL (VOIDmode, vec));
5666 : }
5667 : /* (vec_concat:N
5668 : (subreg:N/2 OP 0)
5669 : (subreg:N/2 OP N/2)) --> OP
5670 : i.e. where concatenating the first and second halves of the
5671 : same object OP. */
5672 4072146 : {
5673 4072146 : poly_uint64 offset = 0u;
5674 4072146 : rtx base0 = get_ref_base_and_offset (trueop0, &offset);
5675 4072146 : if (known_eq (offset, 0u)
5676 12214778 : && known_eq (GET_MODE_SIZE (GET_MODE (base0)),
5677 : GET_MODE_SIZE (mode)))
5678 : {
5679 68034 : rtx base1 = get_ref_base_and_offset (trueop1, &offset);
5680 68034 : if (rtx_equal_p (base0, base1)
5681 1190 : && known_eq (offset, GET_MODE_SIZE (op0_mode))
5682 1149 : && !side_effects_p (trueop0)
5683 69183 : && !side_effects_p (trueop1))
5684 : {
5685 1149 : tem = rtl_hooks.gen_lowpart_no_emit (mode, base0);
5686 1149 : if (tem)
5687 1149 : return tem;
5688 : }
5689 : }
5690 : }
5691 : }
5692 4070997 : return 0;
5693 :
5694 0 : default:
5695 0 : gcc_unreachable ();
5696 : }
5697 :
5698 391467705 : if (mode == GET_MODE (op0)
5699 336248378 : && mode == GET_MODE (op1)
5700 106992271 : && vec_duplicate_p (op0, &elt0)
5701 391599251 : && vec_duplicate_p (op1, &elt1))
5702 : {
5703 : /* Try applying the operator to ELT and see if that simplifies.
5704 : We can duplicate the result if so.
5705 :
5706 : The reason we don't use simplify_gen_binary is that it isn't
5707 : necessarily a win to convert things like:
5708 :
5709 : (plus:V (vec_duplicate:V (reg:S R1))
5710 : (vec_duplicate:V (reg:S R2)))
5711 :
5712 : to:
5713 :
5714 : (vec_duplicate:V (plus:S (reg:S R1) (reg:S R2)))
5715 :
5716 : The first might be done entirely in vector registers while the
5717 : second might need a move between register files. */
5718 172 : tem = simplify_binary_operation (code, GET_MODE_INNER (mode),
5719 : elt0, elt1);
5720 86 : if (tem)
5721 2 : return gen_vec_duplicate (mode, tem);
5722 : }
5723 :
5724 : return 0;
5725 : }
5726 :
5727 : /* Return true if binary operation OP distributes over addition in operand
5728 : OPNO, with the other operand being held constant. OPNO counts from 1. */
5729 :
5730 : static bool
5731 8291 : distributes_over_addition_p (rtx_code op, int opno)
5732 : {
5733 0 : switch (op)
5734 : {
5735 : case PLUS:
5736 : case MINUS:
5737 : case MULT:
5738 : return true;
5739 :
5740 0 : case ASHIFT:
5741 0 : return opno == 1;
5742 :
5743 0 : default:
5744 0 : return false;
5745 : }
5746 : }
5747 :
5748 : rtx
5749 500019432 : simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
5750 : rtx op0, rtx op1)
5751 : {
5752 500019432 : if (VECTOR_MODE_P (mode)
5753 16009398 : && code != VEC_CONCAT
5754 11904102 : && GET_CODE (op0) == CONST_VECTOR
5755 196087 : && GET_CODE (op1) == CONST_VECTOR)
5756 : {
5757 9000 : bool step_ok_p;
5758 9000 : if (CONST_VECTOR_STEPPED_P (op0)
5759 9000 : && CONST_VECTOR_STEPPED_P (op1))
5760 : /* We can operate directly on the encoding if:
5761 :
5762 : a3 - a2 == a2 - a1 && b3 - b2 == b2 - b1
5763 : implies
5764 : (a3 op b3) - (a2 op b2) == (a2 op b2) - (a1 op b1)
5765 :
5766 : Addition and subtraction are the supported operators
5767 : for which this is true. */
5768 709 : step_ok_p = (code == PLUS || code == MINUS);
5769 8291 : else if (CONST_VECTOR_STEPPED_P (op0))
5770 : /* We can operate directly on stepped encodings if:
5771 :
5772 : a3 - a2 == a2 - a1
5773 : implies:
5774 : (a3 op c) - (a2 op c) == (a2 op c) - (a1 op c)
5775 :
5776 : which is true if (x -> x op c) distributes over addition. */
5777 1313 : step_ok_p = distributes_over_addition_p (code, 1);
5778 : else
5779 : /* Similarly in reverse. */
5780 6978 : step_ok_p = distributes_over_addition_p (code, 2);
5781 9000 : rtx_vector_builder builder;
5782 9000 : if (!builder.new_binary_operation (mode, op0, op1, step_ok_p))
5783 : return 0;
5784 :
5785 9000 : unsigned int count = builder.encoded_nelts ();
5786 55219 : for (unsigned int i = 0; i < count; i++)
5787 : {
5788 92538 : rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
5789 : CONST_VECTOR_ELT (op0, i),
5790 46269 : CONST_VECTOR_ELT (op1, i));
5791 46269 : if (!x || !valid_for_const_vector_p (mode, x))
5792 50 : return 0;
5793 46219 : builder.quick_push (x);
5794 : }
5795 8950 : return builder.build ();
5796 9000 : }
5797 :
5798 500010432 : if (VECTOR_MODE_P (mode)
5799 16000398 : && code == VEC_CONCAT
5800 4105296 : && (CONST_SCALAR_INT_P (op0)
5801 4084578 : || CONST_FIXED_P (op0)
5802 4084578 : || CONST_DOUBLE_AS_FLOAT_P (op0)
5803 4080753 : || CONST_VECTOR_P (op0))
5804 42745 : && (CONST_SCALAR_INT_P (op1)
5805 39442 : || CONST_DOUBLE_AS_FLOAT_P (op1)
5806 37067 : || CONST_FIXED_P (op1)
5807 37067 : || CONST_VECTOR_P (op1)))
5808 : {
5809 : /* Both inputs have a constant number of elements, so the result
5810 : must too. */
5811 14520 : unsigned n_elts = GET_MODE_NUNITS (mode).to_constant ();
5812 14520 : rtvec v = rtvec_alloc (n_elts);
5813 :
5814 14520 : gcc_assert (n_elts >= 2);
5815 14520 : if (n_elts == 2)
5816 : {
5817 5678 : gcc_assert (GET_CODE (op0) != CONST_VECTOR);
5818 5678 : gcc_assert (GET_CODE (op1) != CONST_VECTOR);
5819 :
5820 5678 : RTVEC_ELT (v, 0) = op0;
5821 5678 : RTVEC_ELT (v, 1) = op1;
5822 : }
5823 : else
5824 : {
5825 8842 : unsigned op0_n_elts = GET_MODE_NUNITS (GET_MODE (op0)).to_constant ();
5826 8842 : unsigned op1_n_elts = GET_MODE_NUNITS (GET_MODE (op1)).to_constant ();
5827 8842 : unsigned i;
5828 :
5829 8842 : gcc_assert (GET_CODE (op0) == CONST_VECTOR);
5830 8842 : gcc_assert (GET_CODE (op1) == CONST_VECTOR);
5831 8842 : gcc_assert (op0_n_elts + op1_n_elts == n_elts);
5832 :
5833 53690 : for (i = 0; i < op0_n_elts; ++i)
5834 44848 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op0, i);
5835 53882 : for (i = 0; i < op1_n_elts; ++i)
5836 45040 : RTVEC_ELT (v, op0_n_elts+i) = CONST_VECTOR_ELT (op1, i);
5837 : }
5838 :
5839 14520 : return gen_rtx_CONST_VECTOR (mode, v);
5840 : }
5841 :
5842 487379411 : if (VECTOR_MODE_P (mode)
5843 15985878 : && GET_CODE (op0) == CONST_VECTOR
5844 196447 : && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1))
5845 499995912 : && (CONST_VECTOR_DUPLICATE_P (op0)
5846 124714 : || CONST_VECTOR_NUNITS (op0).is_constant ()))
5847 : {
5848 124714 : switch (code)
5849 : {
5850 124714 : case PLUS:
5851 124714 : case MINUS:
5852 124714 : case MULT:
5853 124714 : case DIV:
5854 124714 : case MOD:
5855 124714 : case UDIV:
5856 124714 : case UMOD:
5857 124714 : case AND:
5858 124714 : case IOR:
5859 124714 : case XOR:
5860 124714 : case SMIN:
5861 124714 : case SMAX:
5862 124714 : case UMIN:
5863 124714 : case UMAX:
5864 124714 : case LSHIFTRT:
5865 124714 : case ASHIFTRT:
5866 124714 : case ASHIFT:
5867 124714 : case ROTATE:
5868 124714 : case ROTATERT:
5869 124714 : case SS_PLUS:
5870 124714 : case US_PLUS:
5871 124714 : case SS_MINUS:
5872 124714 : case US_MINUS:
5873 124714 : case SS_ASHIFT:
5874 124714 : case US_ASHIFT:
5875 124714 : case COPYSIGN:
5876 124714 : break;
5877 : default:
5878 : return NULL_RTX;
5879 : }
5880 :
5881 124714 : unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op0)
5882 124714 : ? CONST_VECTOR_NPATTERNS (op0)
5883 132721 : : CONST_VECTOR_NUNITS (op0).to_constant ());
5884 124714 : rtx_vector_builder builder (mode, npatterns, 1);
5885 387309 : for (unsigned i = 0; i < npatterns; i++)
5886 : {
5887 275762 : rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
5888 137881 : CONST_VECTOR_ELT (op0, i), op1);
5889 137881 : if (!x || !valid_for_const_vector_p (mode, x))
5890 0 : return 0;
5891 137881 : builder.quick_push (x);
5892 : }
5893 124714 : return builder.build ();
5894 : }
5895 :
5896 499871198 : if (SCALAR_FLOAT_MODE_P (mode)
5897 6486076 : && CONST_DOUBLE_AS_FLOAT_P (op0)
5898 80992 : && CONST_DOUBLE_AS_FLOAT_P (op1)
5899 11617 : && mode == GET_MODE (op0) && mode == GET_MODE (op1))
5900 : {
5901 11617 : if (code == AND
5902 : || code == IOR
5903 11617 : || code == XOR)
5904 : {
5905 2538 : long tmp0[4];
5906 2538 : long tmp1[4];
5907 2538 : REAL_VALUE_TYPE r;
5908 2538 : int i;
5909 :
5910 2538 : real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0),
5911 2538 : GET_MODE (op0));
5912 2538 : real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1),
5913 2538 : GET_MODE (op1));
5914 12690 : for (i = 0; i < 4; i++)
5915 : {
5916 10152 : switch (code)
5917 : {
5918 5272 : case AND:
5919 5272 : tmp0[i] &= tmp1[i];
5920 5272 : break;
5921 2512 : case IOR:
5922 2512 : tmp0[i] |= tmp1[i];
5923 2512 : break;
5924 2368 : case XOR:
5925 2368 : tmp0[i] ^= tmp1[i];
5926 2368 : break;
5927 : default:
5928 : gcc_unreachable ();
5929 : }
5930 : }
5931 2538 : real_from_target (&r, tmp0, mode);
5932 2538 : return const_double_from_real_value (r, mode);
5933 : }
5934 9079 : else if (code == COPYSIGN)
5935 : {
5936 0 : REAL_VALUE_TYPE f0, f1;
5937 0 : real_convert (&f0, mode, CONST_DOUBLE_REAL_VALUE (op0));
5938 0 : real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (op1));
5939 0 : real_copysign (&f0, &f1);
5940 0 : return const_double_from_real_value (f0, mode);
5941 : }
5942 : else
5943 : {
5944 9079 : REAL_VALUE_TYPE f0, f1, value, result;
5945 9079 : const REAL_VALUE_TYPE *opr0, *opr1;
5946 9079 : bool inexact;
5947 :
5948 9079 : opr0 = CONST_DOUBLE_REAL_VALUE (op0);
5949 9079 : opr1 = CONST_DOUBLE_REAL_VALUE (op1);
5950 :
5951 9079 : if (HONOR_SNANS (mode)
5952 9079 : && (REAL_VALUE_ISSIGNALING_NAN (*opr0)
5953 803 : || REAL_VALUE_ISSIGNALING_NAN (*opr1)))
5954 : return 0;
5955 :
5956 9069 : real_convert (&f0, mode, opr0);
5957 9069 : real_convert (&f1, mode, opr1);
5958 :
5959 9069 : if (code == DIV
5960 4158 : && real_equal (&f1, &dconst0)
5961 12709 : && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
5962 : return 0;
5963 :
5964 27066 : if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
5965 5343 : && flag_trapping_math
5966 5265 : && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
5967 : {
5968 9 : int s0 = REAL_VALUE_NEGATIVE (f0);
5969 9 : int s1 = REAL_VALUE_NEGATIVE (f1);
5970 :
5971 9 : switch (code)
5972 : {
5973 0 : case PLUS:
5974 : /* Inf + -Inf = NaN plus exception. */
5975 0 : if (s0 != s1)
5976 : return 0;
5977 : break;
5978 0 : case MINUS:
5979 : /* Inf - Inf = NaN plus exception. */
5980 0 : if (s0 == s1)
5981 : return 0;
5982 : break;
5983 : case DIV:
5984 : /* Inf / Inf = NaN plus exception. */
5985 : return 0;
5986 : default:
5987 : break;
5988 : }
5989 : }
5990 :
5991 7938 : if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
5992 1949 : && flag_trapping_math
5993 7325 : && ((REAL_VALUE_ISINF (f0) && real_equal (&f1, &dconst0))
5994 1893 : || (REAL_VALUE_ISINF (f1)
5995 10 : && real_equal (&f0, &dconst0))))
5996 : /* Inf * 0 = NaN plus exception. */
5997 : return 0;
5998 :
5999 5406 : inexact = real_arithmetic (&value, rtx_to_tree_code (code),
6000 : &f0, &f1);
6001 5406 : real_convert (&result, mode, &value);
6002 :
6003 : /* Don't constant fold this floating point operation if
6004 : the result has overflowed and flag_trapping_math. */
6005 :
6006 5406 : if (flag_trapping_math
6007 20952 : && MODE_HAS_INFINITIES (mode)
6008 5238 : && REAL_VALUE_ISINF (result)
6009 1141 : && !REAL_VALUE_ISINF (f0)
6010 6533 : && !REAL_VALUE_ISINF (f1))
6011 : /* Overflow plus exception. */
6012 1127 : return 0;
6013 :
6014 : /* Don't constant fold this floating point operation if the
6015 : result may dependent upon the run-time rounding mode and
6016 : flag_rounding_math is set, or if GCC's software emulation
6017 : is unable to accurately represent the result. */
6018 :
6019 4279 : if ((flag_rounding_math
6020 27650 : || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
6021 4279 : && (inexact || !real_identical (&result, &value)))
6022 : return NULL_RTX;
6023 :
6024 3901 : return const_double_from_real_value (result, mode);
6025 : }
6026 : }
6027 :
6028 : /* We can fold some multi-word operations. */
6029 499859581 : scalar_int_mode int_mode;
6030 499859581 : if (is_a <scalar_int_mode> (mode, &int_mode)
6031 428067011 : && CONST_SCALAR_INT_P (op0)
6032 41551107 : && CONST_SCALAR_INT_P (op1)
6033 34459324 : && GET_MODE_PRECISION (int_mode) <= MAX_BITSIZE_MODE_ANY_INT)
6034 : {
6035 34459324 : wide_int result;
6036 34459324 : wi::overflow_type overflow;
6037 34459324 : rtx_mode_t pop0 = rtx_mode_t (op0, int_mode);
6038 34459324 : rtx_mode_t pop1 = rtx_mode_t (op1, int_mode);
6039 :
6040 : #if TARGET_SUPPORTS_WIDE_INT == 0
6041 : /* This assert keeps the simplification from producing a result
6042 : that cannot be represented in a CONST_DOUBLE but a lot of
6043 : upstream callers expect that this function never fails to
6044 : simplify something and so you if you added this to the test
6045 : above the code would die later anyway. If this assert
6046 : happens, you just need to make the port support wide int. */
6047 : gcc_assert (GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_DOUBLE_INT);
6048 : #endif
6049 34459324 : switch (code)
6050 : {
6051 1097075 : case MINUS:
6052 1097075 : result = wi::sub (pop0, pop1);
6053 1097075 : break;
6054 :
6055 26953555 : case PLUS:
6056 26953555 : result = wi::add (pop0, pop1);
6057 26953555 : break;
6058 :
6059 320564 : case MULT:
6060 320564 : result = wi::mul (pop0, pop1);
6061 320564 : break;
6062 :
6063 9023 : case DIV:
6064 9023 : result = wi::div_trunc (pop0, pop1, SIGNED, &overflow);
6065 9023 : if (overflow)
6066 : return NULL_RTX;
6067 : break;
6068 :
6069 1195 : case MOD:
6070 1195 : result = wi::mod_trunc (pop0, pop1, SIGNED, &overflow);
6071 1195 : if (overflow)
6072 : return NULL_RTX;
6073 : break;
6074 :
6075 6122 : case UDIV:
6076 6122 : result = wi::div_trunc (pop0, pop1, UNSIGNED, &overflow);
6077 6122 : if (overflow)
6078 : return NULL_RTX;
6079 : break;
6080 :
6081 16279 : case UMOD:
6082 16279 : result = wi::mod_trunc (pop0, pop1, UNSIGNED, &overflow);
6083 16279 : if (overflow)
6084 : return NULL_RTX;
6085 : break;
6086 :
6087 787187 : case AND:
6088 787187 : result = wi::bit_and (pop0, pop1);
6089 787187 : break;
6090 :
6091 265381 : case IOR:
6092 265381 : result = wi::bit_or (pop0, pop1);
6093 265381 : break;
6094 :
6095 44960 : case XOR:
6096 44960 : result = wi::bit_xor (pop0, pop1);
6097 44960 : break;
6098 :
6099 1763 : case SMIN:
6100 1763 : result = wi::smin (pop0, pop1);
6101 1763 : break;
6102 :
6103 1988 : case SMAX:
6104 1988 : result = wi::smax (pop0, pop1);
6105 1988 : break;
6106 :
6107 3219 : case UMIN:
6108 3219 : result = wi::umin (pop0, pop1);
6109 3219 : break;
6110 :
6111 2998 : case UMAX:
6112 2998 : result = wi::umax (pop0, pop1);
6113 2998 : break;
6114 :
6115 4907304 : case LSHIFTRT:
6116 4907304 : case ASHIFTRT:
6117 4907304 : case ASHIFT:
6118 4907304 : case SS_ASHIFT:
6119 4907304 : case US_ASHIFT:
6120 4907304 : {
6121 : /* The shift count might be in SImode while int_mode might
6122 : be narrower. On IA-64 it is even DImode. If the shift
6123 : count is too large and doesn't fit into int_mode, we'd
6124 : ICE. So, if int_mode is narrower than
6125 : HOST_BITS_PER_WIDE_INT, use DImode for the shift count. */
6126 4907304 : if (GET_MODE (op1) == VOIDmode
6127 4907304 : && GET_MODE_PRECISION (int_mode) < HOST_BITS_PER_WIDE_INT)
6128 1870276 : pop1 = rtx_mode_t (op1, DImode);
6129 :
6130 4907304 : wide_int wop1 = pop1;
6131 4907304 : if (SHIFT_COUNT_TRUNCATED)
6132 : wop1 = wi::umod_trunc (wop1, GET_MODE_PRECISION (int_mode));
6133 4907304 : else if (wi::geu_p (wop1, GET_MODE_PRECISION (int_mode)))
6134 64 : return NULL_RTX;
6135 :
6136 4907240 : switch (code)
6137 : {
6138 2767474 : case LSHIFTRT:
6139 2767474 : result = wi::lrshift (pop0, wop1);
6140 2767474 : break;
6141 :
6142 82614 : case ASHIFTRT:
6143 82614 : result = wi::arshift (pop0, wop1);
6144 82614 : break;
6145 :
6146 2057152 : case ASHIFT:
6147 2057152 : result = wi::lshift (pop0, wop1);
6148 2057152 : break;
6149 :
6150 0 : case SS_ASHIFT:
6151 0 : if (wi::leu_p (wop1, wi::clrsb (pop0)))
6152 0 : result = wi::lshift (pop0, wop1);
6153 0 : else if (wi::neg_p (pop0))
6154 0 : result = wi::min_value (int_mode, SIGNED);
6155 : else
6156 0 : result = wi::max_value (int_mode, SIGNED);
6157 : break;
6158 :
6159 0 : case US_ASHIFT:
6160 0 : if (wi::eq_p (pop0, 0))
6161 0 : result = pop0;
6162 0 : else if (wi::leu_p (wop1, wi::clz (pop0)))
6163 0 : result = wi::lshift (pop0, wop1);
6164 : else
6165 0 : result = wi::max_value (int_mode, UNSIGNED);
6166 : break;
6167 :
6168 : default:
6169 : gcc_unreachable ();
6170 : }
6171 4907240 : break;
6172 4907304 : }
6173 31429 : case ROTATE:
6174 31429 : case ROTATERT:
6175 31429 : {
6176 : /* The rotate count might be in SImode while int_mode might
6177 : be narrower. On IA-64 it is even DImode. If the shift
6178 : count is too large and doesn't fit into int_mode, we'd
6179 : ICE. So, if int_mode is narrower than
6180 : HOST_BITS_PER_WIDE_INT, use DImode for the shift count. */
6181 31429 : if (GET_MODE (op1) == VOIDmode
6182 31429 : && GET_MODE_PRECISION (int_mode) < HOST_BITS_PER_WIDE_INT)
6183 23759 : pop1 = rtx_mode_t (op1, DImode);
6184 :
6185 31429 : if (wi::neg_p (pop1))
6186 : return NULL_RTX;
6187 :
6188 31329 : switch (code)
6189 : {
6190 10361 : case ROTATE:
6191 10361 : result = wi::lrotate (pop0, pop1);
6192 10361 : break;
6193 :
6194 20968 : case ROTATERT:
6195 20968 : result = wi::rrotate (pop0, pop1);
6196 20968 : break;
6197 :
6198 : default:
6199 : gcc_unreachable ();
6200 : }
6201 : break;
6202 : }
6203 :
6204 2438 : case SS_PLUS:
6205 2438 : result = wi::add (pop0, pop1, SIGNED, &overflow);
6206 4820 : clamp_signed_saturation:
6207 4820 : if (overflow == wi::OVF_OVERFLOW)
6208 314 : result = wi::max_value (GET_MODE_PRECISION (int_mode), SIGNED);
6209 4506 : else if (overflow == wi::OVF_UNDERFLOW)
6210 278 : result = wi::min_value (GET_MODE_PRECISION (int_mode), SIGNED);
6211 4228 : else if (overflow != wi::OVF_NONE)
6212 : return NULL_RTX;
6213 : break;
6214 :
6215 2388 : case US_PLUS:
6216 2388 : result = wi::add (pop0, pop1, UNSIGNED, &overflow);
6217 2388 : clamp_unsigned_saturation:
6218 2388 : if (overflow != wi::OVF_NONE)
6219 502 : result = wi::max_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
6220 : break;
6221 :
6222 2382 : case SS_MINUS:
6223 2382 : result = wi::sub (pop0, pop1, SIGNED, &overflow);
6224 2382 : goto clamp_signed_saturation;
6225 :
6226 2068 : case US_MINUS:
6227 2068 : result = wi::sub (pop0, pop1, UNSIGNED, &overflow);
6228 2068 : if (overflow != wi::OVF_NONE)
6229 1350 : result = wi::min_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
6230 : break;
6231 :
6232 0 : case SS_MULT:
6233 0 : result = wi::mul (pop0, pop1, SIGNED, &overflow);
6234 0 : goto clamp_signed_saturation;
6235 :
6236 0 : case US_MULT:
6237 0 : result = wi::mul (pop0, pop1, UNSIGNED, &overflow);
6238 0 : goto clamp_unsigned_saturation;
6239 :
6240 6 : case SMUL_HIGHPART:
6241 6 : result = wi::mul_high (pop0, pop1, SIGNED);
6242 6 : break;
6243 :
6244 0 : case UMUL_HIGHPART:
6245 0 : result = wi::mul_high (pop0, pop1, UNSIGNED);
6246 0 : break;
6247 :
6248 : default:
6249 : return NULL_RTX;
6250 : }
6251 34457016 : return immed_wide_int_const (result, int_mode);
6252 34459324 : }
6253 :
6254 : /* Handle polynomial integers. */
6255 : if (NUM_POLY_INT_COEFFS > 1
6256 : && is_a <scalar_int_mode> (mode, &int_mode)
6257 : && poly_int_rtx_p (op0)
6258 : && poly_int_rtx_p (op1))
6259 : {
6260 : poly_wide_int result;
6261 : switch (code)
6262 : {
6263 : case PLUS:
6264 : result = wi::to_poly_wide (op0, mode) + wi::to_poly_wide (op1, mode);
6265 : break;
6266 :
6267 : case MINUS:
6268 : result = wi::to_poly_wide (op0, mode) - wi::to_poly_wide (op1, mode);
6269 : break;
6270 :
6271 : case MULT:
6272 : if (CONST_SCALAR_INT_P (op1))
6273 : result = wi::to_poly_wide (op0, mode) * rtx_mode_t (op1, mode);
6274 : else
6275 : return NULL_RTX;
6276 : break;
6277 :
6278 : case ASHIFT:
6279 : if (CONST_SCALAR_INT_P (op1))
6280 : {
6281 : wide_int shift
6282 : = rtx_mode_t (op1,
6283 : GET_MODE (op1) == VOIDmode
6284 : && (GET_MODE_PRECISION (int_mode)
6285 : < HOST_BITS_PER_WIDE_INT)
6286 : ? DImode : mode);
6287 : if (SHIFT_COUNT_TRUNCATED)
6288 : shift = wi::umod_trunc (shift, GET_MODE_PRECISION (int_mode));
6289 : else if (wi::geu_p (shift, GET_MODE_PRECISION (int_mode)))
6290 : return NULL_RTX;
6291 : result = wi::to_poly_wide (op0, mode) << shift;
6292 : }
6293 : else
6294 : return NULL_RTX;
6295 : break;
6296 :
6297 : case IOR:
6298 : if (!CONST_SCALAR_INT_P (op1)
6299 : || !can_ior_p (wi::to_poly_wide (op0, mode),
6300 : rtx_mode_t (op1, mode), &result))
6301 : return NULL_RTX;
6302 : break;
6303 :
6304 : default:
6305 : return NULL_RTX;
6306 : }
6307 : return immed_wide_int_const (result, int_mode);
6308 : }
6309 :
6310 : return NULL_RTX;
6311 : }
6312 :
6313 :
6314 :
6315 : /* Return a positive integer if X should sort after Y. The value
6316 : returned is 1 if and only if X and Y are both regs. */
6317 :
6318 : static int
6319 118636318 : simplify_plus_minus_op_data_cmp (rtx x, rtx y)
6320 : {
6321 118636318 : int result;
6322 :
6323 118636318 : result = (commutative_operand_precedence (y)
6324 118636318 : - commutative_operand_precedence (x));
6325 118636318 : if (result)
6326 82390365 : return result + result;
6327 :
6328 : /* Group together equal REGs to do more simplification. */
6329 36245953 : if (REG_P (x) && REG_P (y))
6330 9240836 : return REGNO (x) > REGNO (y);
6331 :
6332 : return 0;
6333 : }
6334 :
6335 : /* Simplify and canonicalize a PLUS or MINUS, at least one of whose
6336 : operands may be another PLUS or MINUS.
6337 :
6338 : Rather than test for specific case, we do this by a brute-force method
6339 : and do all possible simplifications until no more changes occur. Then
6340 : we rebuild the operation.
6341 :
6342 : May return NULL_RTX when no changes were made. */
6343 :
6344 : rtx
6345 39975008 : simplify_context::simplify_plus_minus (rtx_code code, machine_mode mode,
6346 : rtx op0, rtx op1)
6347 : {
6348 39975008 : struct simplify_plus_minus_op_data
6349 : {
6350 : rtx op;
6351 : short neg;
6352 : } ops[16];
6353 39975008 : rtx result, tem;
6354 39975008 : int n_ops = 2;
6355 39975008 : int changed, n_constants, canonicalized = 0;
6356 39975008 : int i, j;
6357 :
6358 39975008 : memset (ops, 0, sizeof ops);
6359 :
6360 : /* Set up the two operands and then expand them until nothing has been
6361 : changed. If we run out of room in our array, give up; this should
6362 : almost never happen. */
6363 :
6364 39975008 : ops[0].op = op0;
6365 39975008 : ops[0].neg = 0;
6366 39975008 : ops[1].op = op1;
6367 39975008 : ops[1].neg = (code == MINUS);
6368 :
6369 81280886 : do
6370 : {
6371 81280886 : changed = 0;
6372 81280886 : n_constants = 0;
6373 :
6374 328982837 : for (i = 0; i < n_ops; i++)
6375 : {
6376 247701967 : rtx this_op = ops[i].op;
6377 247701967 : int this_neg = ops[i].neg;
6378 247701967 : enum rtx_code this_code = GET_CODE (this_op);
6379 :
6380 247701967 : switch (this_code)
6381 : {
6382 40315282 : case PLUS:
6383 40315282 : case MINUS:
6384 40315282 : if (n_ops == ARRAY_SIZE (ops))
6385 : return NULL_RTX;
6386 :
6387 40315266 : ops[n_ops].op = XEXP (this_op, 1);
6388 40315266 : ops[n_ops].neg = (this_code == MINUS) ^ this_neg;
6389 40315266 : n_ops++;
6390 :
6391 40315266 : ops[i].op = XEXP (this_op, 0);
6392 40315266 : changed = 1;
6393 : /* If this operand was negated then we will potentially
6394 : canonicalize the expression. Similarly if we don't
6395 : place the operands adjacent we're re-ordering the
6396 : expression and thus might be performing a
6397 : canonicalization. Ignore register re-ordering.
6398 : ??? It might be better to shuffle the ops array here,
6399 : but then (plus (plus (A, B), plus (C, D))) wouldn't
6400 : be seen as non-canonical. */
6401 40315266 : if (this_neg
6402 39613358 : || (i != n_ops - 2
6403 39001802 : && !(REG_P (ops[i].op) && REG_P (ops[n_ops - 1].op))))
6404 247701951 : canonicalized = 1;
6405 : break;
6406 :
6407 2062 : case NEG:
6408 2062 : ops[i].op = XEXP (this_op, 0);
6409 2062 : ops[i].neg = ! this_neg;
6410 2062 : changed = 1;
6411 2062 : canonicalized = 1;
6412 2062 : break;
6413 :
6414 1608000 : case CONST:
6415 1608000 : if (n_ops != ARRAY_SIZE (ops)
6416 1608000 : && GET_CODE (XEXP (this_op, 0)) == PLUS
6417 1474394 : && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
6418 1453656 : && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
6419 : {
6420 1453656 : ops[i].op = XEXP (XEXP (this_op, 0), 0);
6421 1453656 : ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
6422 1453656 : ops[n_ops].neg = this_neg;
6423 1453656 : n_ops++;
6424 1453656 : changed = 1;
6425 1453656 : canonicalized = 1;
6426 : }
6427 : break;
6428 :
6429 68873 : case NOT:
6430 : /* ~a -> (-a - 1) */
6431 68873 : if (n_ops != ARRAY_SIZE (ops))
6432 : {
6433 68873 : ops[n_ops].op = CONSTM1_RTX (mode);
6434 68873 : ops[n_ops++].neg = this_neg;
6435 68873 : ops[i].op = XEXP (this_op, 0);
6436 68873 : ops[i].neg = !this_neg;
6437 68873 : changed = 1;
6438 68873 : canonicalized = 1;
6439 : }
6440 : break;
6441 :
6442 123255868 : CASE_CONST_SCALAR_INT:
6443 123255868 : case CONST_POLY_INT:
6444 123255868 : n_constants++;
6445 123255868 : if (this_neg)
6446 : {
6447 1210568 : ops[i].op = neg_poly_int_rtx (mode, this_op);
6448 1210568 : ops[i].neg = 0;
6449 1210568 : changed = 1;
6450 1210568 : canonicalized = 1;
6451 : }
6452 : break;
6453 :
6454 : default:
6455 : break;
6456 : }
6457 : }
6458 : }
6459 81280870 : while (changed);
6460 :
6461 39974992 : if (n_constants > 1)
6462 24458550 : canonicalized = 1;
6463 :
6464 39974992 : gcc_assert (n_ops >= 2);
6465 :
6466 : /* If we only have two operands, we can avoid the loops. */
6467 39974992 : if (n_ops == 2)
6468 : {
6469 0 : enum rtx_code code = ops[0].neg || ops[1].neg ? MINUS : PLUS;
6470 0 : rtx lhs, rhs;
6471 :
6472 : /* Get the two operands. Be careful with the order, especially for
6473 : the cases where code == MINUS. */
6474 0 : if (ops[0].neg && ops[1].neg)
6475 : {
6476 0 : lhs = gen_rtx_NEG (mode, ops[0].op);
6477 0 : rhs = ops[1].op;
6478 : }
6479 0 : else if (ops[0].neg)
6480 : {
6481 0 : lhs = ops[1].op;
6482 0 : rhs = ops[0].op;
6483 : }
6484 : else
6485 : {
6486 0 : lhs = ops[0].op;
6487 0 : rhs = ops[1].op;
6488 : }
6489 :
6490 0 : return simplify_const_binary_operation (code, mode, lhs, rhs);
6491 : }
6492 :
6493 : /* Now simplify each pair of operands until nothing changes. */
6494 65441938 : while (1)
6495 : {
6496 : /* Insertion sort is good enough for a small array. */
6497 173176274 : for (i = 1; i < n_ops; i++)
6498 : {
6499 107734336 : struct simplify_plus_minus_op_data save;
6500 107734336 : int cmp;
6501 :
6502 107734336 : j = i - 1;
6503 107734336 : cmp = simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op);
6504 107734336 : if (cmp <= 0)
6505 94670332 : continue;
6506 : /* Just swapping registers doesn't count as canonicalization. */
6507 13064004 : if (cmp != 1)
6508 9870218 : canonicalized = 1;
6509 :
6510 13064004 : save = ops[i];
6511 15529985 : do
6512 15529985 : ops[j + 1] = ops[j];
6513 15529985 : while (j--
6514 28593989 : && simplify_plus_minus_op_data_cmp (ops[j].op, save.op) > 0);
6515 13064004 : ops[j + 1] = save;
6516 : }
6517 :
6518 65441938 : changed = 0;
6519 173176274 : for (i = n_ops - 1; i > 0; i--)
6520 258486103 : for (j = i - 1; j >= 0; j--)
6521 : {
6522 151647734 : rtx lhs = ops[j].op, rhs = ops[i].op;
6523 151647734 : int lneg = ops[j].neg, rneg = ops[i].neg;
6524 :
6525 151647734 : if (lhs != 0 && rhs != 0)
6526 : {
6527 125436663 : enum rtx_code ncode = PLUS;
6528 :
6529 125436663 : if (lneg != rneg)
6530 : {
6531 11792820 : ncode = MINUS;
6532 11792820 : if (lneg)
6533 7429407 : std::swap (lhs, rhs);
6534 : }
6535 113643843 : else if (swap_commutative_operands_p (lhs, rhs))
6536 423249 : std::swap (lhs, rhs);
6537 :
6538 125436663 : if ((GET_CODE (lhs) == CONST || CONST_INT_P (lhs))
6539 29470933 : && (GET_CODE (rhs) == CONST || CONST_INT_P (rhs)))
6540 : {
6541 24614046 : rtx tem_lhs, tem_rhs;
6542 :
6543 24614046 : tem_lhs = GET_CODE (lhs) == CONST ? XEXP (lhs, 0) : lhs;
6544 24614046 : tem_rhs = GET_CODE (rhs) == CONST ? XEXP (rhs, 0) : rhs;
6545 24614046 : tem = simplify_binary_operation (ncode, mode, tem_lhs,
6546 : tem_rhs);
6547 :
6548 24614046 : if (tem && !CONSTANT_P (tem))
6549 1751 : tem = gen_rtx_CONST (GET_MODE (tem), tem);
6550 : }
6551 : else
6552 100822617 : tem = simplify_binary_operation (ncode, mode, lhs, rhs);
6553 :
6554 100824368 : if (tem)
6555 : {
6556 : /* Reject "simplifications" that just wrap the two
6557 : arguments in a CONST. Failure to do so can result
6558 : in infinite recursion with simplify_binary_operation
6559 : when it calls us to simplify CONST operations.
6560 : Also, if we find such a simplification, don't try
6561 : any more combinations with this rhs: We must have
6562 : something like symbol+offset, ie. one of the
6563 : trivial CONST expressions we handle later. */
6564 26794236 : if (GET_CODE (tem) == CONST
6565 897718 : && GET_CODE (XEXP (tem, 0)) == ncode
6566 897167 : && XEXP (XEXP (tem, 0), 0) == lhs
6567 895967 : && XEXP (XEXP (tem, 0), 1) == rhs)
6568 : break;
6569 25898269 : lneg &= rneg;
6570 25898269 : if (GET_CODE (tem) == NEG)
6571 45048 : tem = XEXP (tem, 0), lneg = !lneg;
6572 25898269 : if (poly_int_rtx_p (tem) && lneg)
6573 0 : tem = neg_poly_int_rtx (mode, tem), lneg = 0;
6574 :
6575 25898269 : ops[i].op = tem;
6576 25898269 : ops[i].neg = lneg;
6577 25898269 : ops[j].op = NULL_RTX;
6578 25898269 : changed = 1;
6579 25898269 : canonicalized = 1;
6580 : }
6581 : }
6582 : }
6583 :
6584 65441938 : if (!changed)
6585 : break;
6586 :
6587 : /* Pack all the operands to the lower-numbered entries. */
6588 102753934 : for (i = 0, j = 0; j < n_ops; j++)
6589 77286988 : if (ops[j].op)
6590 : {
6591 51388719 : ops[i] = ops[j];
6592 51388719 : i++;
6593 : }
6594 : n_ops = i;
6595 : }
6596 :
6597 : /* If nothing changed, check that rematerialization of rtl instructions
6598 : is still required. */
6599 39974992 : if (!canonicalized)
6600 : {
6601 : /* Perform rematerialization if only all operands are registers and
6602 : all operations are PLUS. */
6603 : /* ??? Also disallow (non-global, non-frame) fixed registers to work
6604 : around rs6000 and how it uses the CA register. See PR67145. */
6605 5447919 : for (i = 0; i < n_ops; i++)
6606 4364530 : if (ops[i].neg
6607 4078429 : || !REG_P (ops[i].op)
6608 7935143 : || (REGNO (ops[i].op) < FIRST_PSEUDO_REGISTER
6609 339536 : && fixed_regs[REGNO (ops[i].op)]
6610 235 : && !global_regs[REGNO (ops[i].op)]
6611 235 : && ops[i].op != frame_pointer_rtx
6612 109 : && ops[i].op != arg_pointer_rtx
6613 100 : && ops[i].op != stack_pointer_rtx))
6614 : return NULL_RTX;
6615 1083389 : goto gen_result;
6616 : }
6617 :
6618 : /* Create (minus -C X) instead of (neg (const (plus X C))). */
6619 38097686 : if (n_ops == 2
6620 23879936 : && CONST_INT_P (ops[1].op)
6621 23216330 : && CONSTANT_P (ops[0].op)
6622 164 : && ops[0].neg)
6623 58 : return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
6624 :
6625 : /* We suppressed creation of trivial CONST expressions in the
6626 : combination loop to avoid recursion. Create one manually now.
6627 : The combination loop should have ensured that there is exactly
6628 : one CONST_INT, and the sort will have ensured that it is last
6629 : in the array and that any other constant will be next-to-last. */
6630 :
6631 38097628 : if (n_ops > 1
6632 37596001 : && poly_int_rtx_p (ops[n_ops - 1].op)
6633 72932867 : && CONSTANT_P (ops[n_ops - 2].op))
6634 : {
6635 1529191 : rtx value = ops[n_ops - 1].op;
6636 1529191 : if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg)
6637 711777 : value = neg_poly_int_rtx (mode, value);
6638 1529191 : if (CONST_INT_P (value))
6639 : {
6640 3058382 : ops[n_ops - 2].op = plus_constant (mode, ops[n_ops - 2].op,
6641 1529191 : INTVAL (value));
6642 1529191 : n_ops--;
6643 : }
6644 : }
6645 :
6646 : /* Put a non-negated operand first, if possible. */
6647 :
6648 39845372 : for (i = 0; i < n_ops && ops[i].neg; i++)
6649 1747744 : continue;
6650 38097628 : if (i == n_ops)
6651 10237 : ops[0].op = gen_rtx_NEG (mode, ops[0].op);
6652 38087391 : else if (i != 0)
6653 : {
6654 1640585 : tem = ops[0].op;
6655 1640585 : ops[0] = ops[i];
6656 1640585 : ops[i].op = tem;
6657 1640585 : ops[i].neg = 1;
6658 : }
6659 :
6660 : /* Now make the result by performing the requested operations. */
6661 36446806 : gen_result:
6662 39181017 : result = ops[0].op;
6663 91969531 : for (i = 1; i < n_ops; i++)
6664 105577028 : result = gen_rtx_fmt_ee (ops[i].neg ? MINUS : PLUS,
6665 : mode, result, ops[i].op);
6666 :
6667 : return result;
6668 1747744 : }
6669 :
6670 : /* Check whether an operand is suitable for calling simplify_plus_minus. */
6671 : static bool
6672 546250907 : plus_minus_operand_p (const_rtx x)
6673 : {
6674 546250907 : return GET_CODE (x) == PLUS
6675 546250907 : || GET_CODE (x) == MINUS
6676 546250907 : || (GET_CODE (x) == CONST
6677 1970997 : && GET_CODE (XEXP (x, 0)) == PLUS
6678 1346963 : && CONSTANT_P (XEXP (XEXP (x, 0), 0))
6679 1273809 : && CONSTANT_P (XEXP (XEXP (x, 0), 1)));
6680 : }
6681 :
6682 : /* Like simplify_binary_operation except used for relational operators.
6683 : MODE is the mode of the result. If MODE is VOIDmode, both operands must
6684 : not also be VOIDmode.
6685 :
6686 : CMP_MODE specifies in which mode the comparison is done in, so it is
6687 : the mode of the operands. If CMP_MODE is VOIDmode, it is taken from
6688 : the operands or, if both are VOIDmode, the operands are compared in
6689 : "infinite precision". */
6690 : rtx
6691 134523356 : simplify_context::simplify_relational_operation (rtx_code code,
6692 : machine_mode mode,
6693 : machine_mode cmp_mode,
6694 : rtx op0, rtx op1)
6695 : {
6696 134523356 : rtx tem, trueop0, trueop1;
6697 :
6698 134523356 : if (cmp_mode == VOIDmode)
6699 29876666 : cmp_mode = GET_MODE (op0);
6700 29876666 : if (cmp_mode == VOIDmode)
6701 255442 : cmp_mode = GET_MODE (op1);
6702 :
6703 134523356 : tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
6704 134523356 : if (tem)
6705 785045 : return relational_result (mode, cmp_mode, tem);
6706 :
6707 : /* For the following tests, ensure const0_rtx is op1. */
6708 133738311 : if (swap_commutative_operands_p (op0, op1)
6709 133738311 : || (op0 == const0_rtx && op1 != const0_rtx))
6710 2650913 : std::swap (op0, op1), code = swap_condition (code);
6711 :
6712 : /* If op0 is a compare, extract the comparison arguments from it. */
6713 133738311 : if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
6714 14900065 : return simplify_gen_relational (code, mode, VOIDmode,
6715 14900065 : XEXP (op0, 0), XEXP (op0, 1));
6716 :
6717 118838246 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
6718 : return NULL_RTX;
6719 :
6720 87584844 : trueop0 = avoid_constant_pool_reference (op0);
6721 87584844 : trueop1 = avoid_constant_pool_reference (op1);
6722 87584844 : return simplify_relational_operation_1 (code, mode, cmp_mode,
6723 87584844 : trueop0, trueop1);
6724 : }
6725 :
6726 : /* This part of simplify_relational_operation is only used when CMP_MODE
6727 : is not in class MODE_CC (i.e. it is a real comparison).
6728 :
6729 : MODE is the mode of the result, while CMP_MODE specifies in which
6730 : mode the comparison is done in, so it is the mode of the operands. */
6731 :
6732 : rtx
6733 87584844 : simplify_context::simplify_relational_operation_1 (rtx_code code,
6734 : machine_mode mode,
6735 : machine_mode cmp_mode,
6736 : rtx op0, rtx op1)
6737 : {
6738 87584844 : enum rtx_code op0code = GET_CODE (op0);
6739 :
6740 87584844 : if (op1 == const0_rtx && COMPARISON_P (op0))
6741 : {
6742 : /* If op0 is a comparison, extract the comparison arguments
6743 : from it. */
6744 301620 : if (code == NE)
6745 : {
6746 133468 : if (GET_MODE (op0) == mode)
6747 178 : return simplify_rtx (op0);
6748 : else
6749 133290 : return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
6750 133290 : XEXP (op0, 0), XEXP (op0, 1));
6751 : }
6752 168152 : else if (code == EQ)
6753 : {
6754 135689 : enum rtx_code new_code = reversed_comparison_code (op0, NULL);
6755 135689 : if (new_code != UNKNOWN)
6756 135372 : return simplify_gen_relational (new_code, mode, VOIDmode,
6757 135372 : XEXP (op0, 0), XEXP (op0, 1));
6758 : }
6759 : }
6760 :
6761 : /* (LTU/GEU (PLUS a C) C), where C is constant, can be simplified to
6762 : (GEU/LTU a -C). Likewise for (LTU/GEU (PLUS a C) a). */
6763 87316004 : if ((code == LTU || code == GEU)
6764 5273683 : && GET_CODE (op0) == PLUS
6765 638391 : && CONST_INT_P (XEXP (op0, 1))
6766 420536 : && (rtx_equal_p (op1, XEXP (op0, 0))
6767 281579 : || rtx_equal_p (op1, XEXP (op0, 1)))
6768 : /* (LTU/GEU (PLUS a 0) 0) is not the same as (GEU/LTU a 0). */
6769 87521872 : && XEXP (op0, 1) != const0_rtx)
6770 : {
6771 205868 : rtx new_cmp
6772 205868 : = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
6773 207427 : return simplify_gen_relational ((code == LTU ? GEU : LTU), mode,
6774 205868 : cmp_mode, XEXP (op0, 0), new_cmp);
6775 : }
6776 :
6777 : /* (GTU (PLUS a C) (C - 1)) where C is a non-zero constant can be
6778 : transformed into (LTU a -C). */
6779 87110136 : if (code == GTU && GET_CODE (op0) == PLUS && CONST_INT_P (op1)
6780 325640 : && CONST_INT_P (XEXP (op0, 1))
6781 243613 : && (UINTVAL (op1) == UINTVAL (XEXP (op0, 1)) - 1)
6782 19064 : && XEXP (op0, 1) != const0_rtx)
6783 : {
6784 19064 : rtx new_cmp
6785 19064 : = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
6786 19064 : return simplify_gen_relational (LTU, mode, cmp_mode,
6787 19064 : XEXP (op0, 0), new_cmp);
6788 : }
6789 :
6790 : /* Canonicalize (LTU/GEU (PLUS a b) b) as (LTU/GEU (PLUS a b) a). */
6791 87091072 : if ((code == LTU || code == GEU)
6792 5067815 : && GET_CODE (op0) == PLUS
6793 432523 : && rtx_equal_p (op1, XEXP (op0, 1))
6794 : /* Don't recurse "infinitely" for (LTU/GEU (PLUS b b) b). */
6795 87097883 : && !rtx_equal_p (op1, XEXP (op0, 0)))
6796 6811 : return simplify_gen_relational (code, mode, cmp_mode, op0,
6797 6811 : copy_rtx (XEXP (op0, 0)));
6798 :
6799 87084261 : if (op1 == const0_rtx)
6800 : {
6801 : /* Canonicalize (GTU x 0) as (NE x 0). */
6802 38094493 : if (code == GTU)
6803 77079 : return simplify_gen_relational (NE, mode, cmp_mode, op0, op1);
6804 : /* Canonicalize (LEU x 0) as (EQ x 0). */
6805 38017414 : if (code == LEU)
6806 33309 : return simplify_gen_relational (EQ, mode, cmp_mode, op0, op1);
6807 :
6808 37984105 : if ((code == NE || code == EQ)
6809 : /* Verify op0 is IOR */
6810 34079712 : && GET_CODE (op0) == IOR
6811 : /* only enters if op1 is 0 */
6812 : /* Verify IOR operand is NE */
6813 584880 : && GET_CODE (XEXP (op0, 0)) == NE
6814 21441 : && GET_MODE (XEXP (XEXP (op0, 0), 0)) == cmp_mode
6815 : /* Verify second NE operand is 0 */
6816 374 : && XEXP (XEXP (op0, 0), 1) == CONST0_RTX (cmp_mode))
6817 : {
6818 31 : rtx t = gen_rtx_IOR (cmp_mode, XEXP (XEXP (op0, 0), 0), XEXP (op0, 1));
6819 31 : t = gen_rtx_fmt_ee (code, mode, t, CONST0_RTX (mode));
6820 31 : return t;
6821 : }
6822 :
6823 : }
6824 48989768 : else if (op1 == const1_rtx)
6825 : {
6826 3359593 : switch (code)
6827 : {
6828 9269 : case GE:
6829 : /* Canonicalize (GE x 1) as (GT x 0). */
6830 9269 : return simplify_gen_relational (GT, mode, cmp_mode,
6831 9269 : op0, const0_rtx);
6832 198373 : case GEU:
6833 : /* Canonicalize (GEU x 1) as (NE x 0). */
6834 198373 : return simplify_gen_relational (NE, mode, cmp_mode,
6835 198373 : op0, const0_rtx);
6836 6802 : case LT:
6837 : /* Canonicalize (LT x 1) as (LE x 0). */
6838 6802 : return simplify_gen_relational (LE, mode, cmp_mode,
6839 6802 : op0, const0_rtx);
6840 54027 : case LTU:
6841 : /* Canonicalize (LTU x 1) as (EQ x 0). */
6842 54027 : return simplify_gen_relational (EQ, mode, cmp_mode,
6843 54027 : op0, const0_rtx);
6844 : default:
6845 : break;
6846 : }
6847 : }
6848 45630175 : else if (op1 == constm1_rtx)
6849 : {
6850 : /* Canonicalize (LE x -1) as (LT x 0). */
6851 1192691 : if (code == LE)
6852 1575 : return simplify_gen_relational (LT, mode, cmp_mode, op0, const0_rtx);
6853 : /* Canonicalize (GT x -1) as (GE x 0). */
6854 1191116 : if (code == GT)
6855 5060 : return simplify_gen_relational (GE, mode, cmp_mode, op0, const0_rtx);
6856 : }
6857 :
6858 : /* (eq/ne (plus x cst1) cst2) simplifies to (eq/ne x (cst2 - cst1)) */
6859 82794343 : if ((code == EQ || code == NE)
6860 64691221 : && (op0code == PLUS || op0code == MINUS)
6861 2575078 : && CONSTANT_P (op1)
6862 929341 : && CONSTANT_P (XEXP (op0, 1))
6863 514057 : && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
6864 : {
6865 514023 : rtx x = XEXP (op0, 0);
6866 514023 : rtx c = XEXP (op0, 1);
6867 514023 : enum rtx_code invcode = op0code == PLUS ? MINUS : PLUS;
6868 514023 : rtx tem = simplify_gen_binary (invcode, cmp_mode, op1, c);
6869 :
6870 : /* Detect an infinite recursive condition, where we oscillate at this
6871 : simplification case between:
6872 : A + B == C <---> C - B == A,
6873 : where A, B, and C are all constants with non-simplifiable expressions,
6874 : usually SYMBOL_REFs. */
6875 514023 : if (GET_CODE (tem) == invcode
6876 57 : && CONSTANT_P (x)
6877 514041 : && rtx_equal_p (c, XEXP (tem, 1)))
6878 : return NULL_RTX;
6879 :
6880 514005 : return simplify_gen_relational (code, mode, cmp_mode, x, tem);
6881 : }
6882 :
6883 : /* (eq/ne (plus (x) (y)) y) simplifies to (eq/ne x 0). */
6884 64177198 : if ((code == EQ || code == NE)
6885 64177198 : && op0code == PLUS
6886 1709900 : && rtx_equal_p (XEXP (op0, 1), op1)
6887 250 : && !side_effects_p (op1)
6888 250 : && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
6889 226 : return simplify_gen_relational (code, mode, cmp_mode,
6890 226 : XEXP (op0, 0), CONST0_RTX (cmp_mode));
6891 :
6892 : /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is
6893 : the same as (zero_extract:SI FOO (const_int 1) BAR). */
6894 86184487 : scalar_int_mode int_mode, int_cmp_mode;
6895 86184487 : if (code == NE
6896 34429979 : && op1 == const0_rtx
6897 2298415 : && is_int_mode (mode, &int_mode)
6898 88407655 : && is_a <scalar_int_mode> (cmp_mode, &int_cmp_mode)
6899 : /* ??? Work-around BImode bugs in the ia64 backend. */
6900 2298415 : && int_mode != BImode
6901 2298391 : && int_cmp_mode != BImode
6902 2298391 : && nonzero_bits (op0, int_cmp_mode) == 1
6903 86184487 : && STORE_FLAG_VALUE == 1)
6904 150494 : return GET_MODE_SIZE (int_mode) > GET_MODE_SIZE (int_cmp_mode)
6905 75247 : ? simplify_gen_unary (ZERO_EXTEND, int_mode, op0, int_cmp_mode)
6906 19104 : : lowpart_subreg (int_mode, op0, int_cmp_mode);
6907 :
6908 : /* (eq/ne (xor x y) 0) simplifies to (eq/ne x y). */
6909 86109240 : if ((code == EQ || code == NE)
6910 64101725 : && op1 == const0_rtx
6911 33929208 : && op0code == XOR)
6912 14966 : return simplify_gen_relational (code, mode, cmp_mode,
6913 14966 : XEXP (op0, 0), XEXP (op0, 1));
6914 :
6915 : /* (eq/ne (xor x y) x) simplifies to (eq/ne y 0). */
6916 64086759 : if ((code == EQ || code == NE)
6917 64086759 : && op0code == XOR
6918 5382 : && rtx_equal_p (XEXP (op0, 0), op1)
6919 6 : && !side_effects_p (XEXP (op0, 0)))
6920 0 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 1),
6921 0 : CONST0_RTX (mode));
6922 :
6923 : /* Likewise (eq/ne (xor x y) y) simplifies to (eq/ne x 0). */
6924 86094274 : if ((code == EQ || code == NE)
6925 64086759 : && op0code == XOR
6926 5382 : && rtx_equal_p (XEXP (op0, 1), op1)
6927 86094458 : && !side_effects_p (XEXP (op0, 1)))
6928 184 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6929 184 : CONST0_RTX (mode));
6930 :
6931 : /* (eq/ne (xor x C1) C2) simplifies to (eq/ne x (C1^C2)). */
6932 86094090 : if ((code == EQ || code == NE)
6933 64086575 : && op0code == XOR
6934 5198 : && CONST_SCALAR_INT_P (op1)
6935 1479 : && CONST_SCALAR_INT_P (XEXP (op0, 1)))
6936 876 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6937 : simplify_gen_binary (XOR, cmp_mode,
6938 876 : XEXP (op0, 1), op1));
6939 :
6940 : /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or
6941 : constant folding if x/y is a constant. */
6942 64085699 : if ((code == EQ || code == NE)
6943 64085699 : && (op0code == AND || op0code == IOR)
6944 3654864 : && !side_effects_p (op1)
6945 3654758 : && op1 != CONST0_RTX (cmp_mode))
6946 : {
6947 : /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to
6948 : (eq/ne (and (not y) x) 0). */
6949 476541 : if ((op0code == AND && rtx_equal_p (XEXP (op0, 0), op1))
6950 950189 : || (op0code == IOR && rtx_equal_p (XEXP (op0, 1), op1)))
6951 : {
6952 24816 : rtx not_y = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 1),
6953 : cmp_mode);
6954 24816 : rtx lhs = simplify_gen_binary (AND, cmp_mode, not_y, XEXP (op0, 0));
6955 :
6956 24816 : return simplify_gen_relational (code, mode, cmp_mode, lhs,
6957 24816 : CONST0_RTX (cmp_mode));
6958 : }
6959 :
6960 : /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to
6961 : (eq/ne (and (not x) y) 0). */
6962 451827 : if ((op0code == AND && rtx_equal_p (XEXP (op0, 1), op1))
6963 878854 : || (op0code == IOR && rtx_equal_p (XEXP (op0, 0), op1)))
6964 : {
6965 46523 : rtx not_x = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 0),
6966 : cmp_mode);
6967 46523 : rtx lhs = simplify_gen_binary (AND, cmp_mode, not_x, XEXP (op0, 1));
6968 :
6969 46523 : return simplify_gen_relational (code, mode, cmp_mode, lhs,
6970 46523 : CONST0_RTX (cmp_mode));
6971 : }
6972 : }
6973 :
6974 : /* Optimize (cmp (and/ior x C1) C2) depending on the CMP and C1 and C2's
6975 : relationship. */
6976 86021875 : if ((op0code == AND || op0code == IOR)
6977 3832861 : && CONST_INT_P (op1)
6978 3656254 : && CONST_INT_P (XEXP (op0, 1)))
6979 : {
6980 2382030 : unsigned HOST_WIDE_INT c1 = UINTVAL (XEXP (op0, 1));
6981 2382030 : unsigned HOST_WIDE_INT c2 = UINTVAL (op1);
6982 :
6983 : /* For AND operations:
6984 : - (x & c1) == c2 when some bits are set in c2 but not in c1 -> false
6985 : - (x & c1) != c2 when some bits are set in c2 but not in c1 -> true
6986 : - (x & c1) >= c2 when c1 is less than c2 -> false
6987 : - (x & c1) < c2 when c1 is less than c2 -> true
6988 : - (x & c1) > c2 when c1 is less than or equal to c2 -> false
6989 : - (x & c1) <= c2 when c1 is less than or equal to c2 -> true
6990 :
6991 : For IOR operations:
6992 : - (x | c1) == c2 when some bits are set in c1 but not in c2 -> false
6993 : - (x | c1) != c2 when some bits are set in c1 but not in c2 -> true
6994 : - (x | c1) <= c2 when c1 is greater than c2 -> false
6995 : - (x | c1) > c2 when c1 is greater than c2 -> true
6996 : - (x | c1) < c2 when c1 is greater than or equal to c2 -> false
6997 : - (x | c1) >= c2 when c1 is greater than or equal to c2 -> true */
6998 2382030 : if ((op0code == AND
6999 2378455 : && ((code == EQ && (c1 & c2) != c2)
7000 2378437 : || (code == GEU && c1 < c2)
7001 2378437 : || (code == GTU && c1 <= c2)))
7002 2382012 : || ((op0code == IOR
7003 3575 : && ((code == EQ && (c1 & c2) != c1)
7004 3575 : || (code == LEU && c1 > c2)
7005 3575 : || (code == LTU && c1 >= c2)))))
7006 18 : return const0_rtx;
7007 :
7008 2382012 : if ((op0code == AND
7009 2378437 : && ((code == NE && (c1 & c2) != c2)
7010 2378356 : || (code == LTU && c1 < c2)
7011 2378356 : || (code == LEU && c1 <= c2)))
7012 2381931 : || ((op0code == IOR
7013 3575 : && ((code == NE && (c1 & c2) != c1)
7014 3515 : || (code == GTU && c1 > c2)
7015 3515 : || (code == GEU && c1 >= c2)))))
7016 141 : return const_true_rtx;
7017 : }
7018 :
7019 : /* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped. */
7020 86021716 : if ((code == EQ || code == NE)
7021 64014201 : && GET_CODE (op0) == BSWAP
7022 316 : && CONST_SCALAR_INT_P (op1))
7023 85 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
7024 : simplify_gen_unary (BSWAP, cmp_mode,
7025 85 : op1, cmp_mode));
7026 :
7027 : /* (eq/ne (bswap x) (bswap y)) simplifies to (eq/ne x y). */
7028 64014116 : if ((code == EQ || code == NE)
7029 64014116 : && GET_CODE (op0) == BSWAP
7030 231 : && GET_CODE (op1) == BSWAP)
7031 18 : return simplify_gen_relational (code, mode, cmp_mode,
7032 18 : XEXP (op0, 0), XEXP (op1, 0));
7033 :
7034 86021613 : if (op0code == POPCOUNT && op1 == const0_rtx)
7035 0 : switch (code)
7036 : {
7037 0 : case EQ:
7038 0 : case LE:
7039 0 : case LEU:
7040 : /* (eq (popcount x) (const_int 0)) -> (eq x (const_int 0)). */
7041 0 : return simplify_gen_relational (EQ, mode, GET_MODE (XEXP (op0, 0)),
7042 : XEXP (op0, 0),
7043 0 : CONST0_RTX (GET_MODE (XEXP (op0, 0))));
7044 :
7045 0 : case NE:
7046 0 : case GT:
7047 0 : case GTU:
7048 : /* (ne (popcount x) (const_int 0)) -> (ne x (const_int 0)). */
7049 0 : return simplify_gen_relational (NE, mode, GET_MODE (XEXP (op0, 0)),
7050 : XEXP (op0, 0),
7051 0 : CONST0_RTX (GET_MODE (XEXP (op0, 0))));
7052 :
7053 : default:
7054 : break;
7055 : }
7056 :
7057 : /* (ne:SI (subreg:QI (ashift:SI x 7) 0) 0) -> (and:SI x 1). */
7058 86021613 : if (code == NE
7059 34308064 : && op1 == const0_rtx
7060 17658691 : && (op0code == TRUNCATE
7061 156974 : || (partial_subreg_p (op0)
7062 156247 : && subreg_lowpart_p (op0)))
7063 132762 : && SCALAR_INT_MODE_P (mode)
7064 86021613 : && STORE_FLAG_VALUE == 1)
7065 : {
7066 34661 : rtx tmp = XEXP (op0, 0);
7067 34661 : if (GET_CODE (tmp) == ASHIFT
7068 2639 : && GET_MODE (tmp) == mode
7069 241 : && CONST_INT_P (XEXP (tmp, 1))
7070 241 : && is_int_mode (GET_MODE (op0), &int_mode)
7071 34902 : && INTVAL (XEXP (tmp, 1)) == GET_MODE_PRECISION (int_mode) - 1)
7072 241 : return simplify_gen_binary (AND, mode, XEXP (tmp, 0), const1_rtx);
7073 : }
7074 :
7075 : /* For two unsigned booleans A and B:
7076 :
7077 : A > B == ~B & A
7078 : A >= B == ~B | A
7079 : A < B == ~A & B
7080 : A <= B == ~A | B
7081 : A == B == ~A ^ B (== ~B ^ A)
7082 : A != B == A ^ B
7083 :
7084 : For signed comparisons, we have to take STORE_FLAG_VALUE into account,
7085 : with the rules above applying for positive STORE_FLAG_VALUE and with
7086 : the relations reversed for negative STORE_FLAG_VALUE. */
7087 86021372 : if (is_a<scalar_int_mode> (cmp_mode)
7088 83238767 : && COMPARISON_P (op0)
7089 86137113 : && COMPARISON_P (op1))
7090 : {
7091 9887 : rtx t = NULL_RTX;
7092 9887 : if (code == GTU || code == (STORE_FLAG_VALUE > 0 ? GT : LT))
7093 723 : t = simplify_logical_relational_operation (AND, mode, op1, op0, true);
7094 : else if (code == GEU || code == (STORE_FLAG_VALUE > 0 ? GE : LE))
7095 720 : t = simplify_logical_relational_operation (IOR, mode, op1, op0, true);
7096 : else if (code == LTU || code == (STORE_FLAG_VALUE > 0 ? LT : GT))
7097 720 : t = simplify_logical_relational_operation (AND, mode, op0, op1, true);
7098 : else if (code == LEU || code == (STORE_FLAG_VALUE > 0 ? LE : GE))
7099 720 : t = simplify_logical_relational_operation (IOR, mode, op0, op1, true);
7100 : else if (code == EQ)
7101 3145 : t = simplify_logical_relational_operation (XOR, mode, op0, op1, true);
7102 : else if (code == NE)
7103 3859 : t = simplify_logical_relational_operation (XOR, mode, op0, op1);
7104 : if (t)
7105 : return t;
7106 : }
7107 :
7108 : return NULL_RTX;
7109 : }
7110 :
7111 : enum
7112 : {
7113 : CMP_EQ = 1,
7114 : CMP_LT = 2,
7115 : CMP_GT = 4,
7116 : CMP_LTU = 8,
7117 : CMP_GTU = 16
7118 : };
7119 :
7120 :
7121 : /* Convert the known results for EQ, LT, GT, LTU, GTU contained in
7122 : KNOWN_RESULT to a CONST_INT, based on the requested comparison CODE
7123 : For KNOWN_RESULT to make sense it should be either CMP_EQ, or the
7124 : logical OR of one of (CMP_LT, CMP_GT) and one of (CMP_LTU, CMP_GTU).
7125 : For floating-point comparisons, assume that the operands were ordered. */
7126 :
7127 : static rtx
7128 721571 : comparison_result (enum rtx_code code, int known_results)
7129 : {
7130 721571 : switch (code)
7131 : {
7132 132416 : case EQ:
7133 132416 : case UNEQ:
7134 132416 : return (known_results & CMP_EQ) ? const_true_rtx : const0_rtx;
7135 453275 : case NE:
7136 453275 : case LTGT:
7137 453275 : return (known_results & CMP_EQ) ? const0_rtx : const_true_rtx;
7138 :
7139 9297 : case LT:
7140 9297 : case UNLT:
7141 9297 : return (known_results & CMP_LT) ? const_true_rtx : const0_rtx;
7142 8685 : case GE:
7143 8685 : case UNGE:
7144 8685 : return (known_results & CMP_LT) ? const0_rtx : const_true_rtx;
7145 :
7146 12064 : case GT:
7147 12064 : case UNGT:
7148 12064 : return (known_results & CMP_GT) ? const_true_rtx : const0_rtx;
7149 13181 : case LE:
7150 13181 : case UNLE:
7151 13181 : return (known_results & CMP_GT) ? const0_rtx : const_true_rtx;
7152 :
7153 24014 : case LTU:
7154 24014 : return (known_results & CMP_LTU) ? const_true_rtx : const0_rtx;
7155 8858 : case GEU:
7156 8858 : return (known_results & CMP_LTU) ? const0_rtx : const_true_rtx;
7157 :
7158 49365 : case GTU:
7159 49365 : return (known_results & CMP_GTU) ? const_true_rtx : const0_rtx;
7160 10350 : case LEU:
7161 10350 : return (known_results & CMP_GTU) ? const0_rtx : const_true_rtx;
7162 :
7163 0 : case ORDERED:
7164 0 : return const_true_rtx;
7165 66 : case UNORDERED:
7166 66 : return const0_rtx;
7167 0 : default:
7168 0 : gcc_unreachable ();
7169 : }
7170 : }
7171 :
7172 : /* Check if the given comparison (done in the given MODE) is actually
7173 : a tautology or a contradiction. If the mode is VOIDmode, the
7174 : comparison is done in "infinite precision". If no simplification
7175 : is possible, this function returns zero. Otherwise, it returns
7176 : either const_true_rtx or const0_rtx. */
7177 :
7178 : rtx
7179 134613500 : simplify_const_relational_operation (enum rtx_code code,
7180 : machine_mode mode,
7181 : rtx op0, rtx op1)
7182 : {
7183 141825390 : rtx tem;
7184 141825390 : rtx trueop0;
7185 141825390 : rtx trueop1;
7186 :
7187 141825390 : gcc_assert (mode != VOIDmode
7188 : || (GET_MODE (op0) == VOIDmode
7189 : && GET_MODE (op1) == VOIDmode));
7190 :
7191 : /* We only handle MODE_CC comparisons that are COMPARE against zero. */
7192 141825390 : if (GET_MODE_CLASS (mode) == MODE_CC
7193 46160211 : && (op1 != const0_rtx
7194 46160211 : || GET_CODE (op0) != COMPARE))
7195 : return NULL_RTX;
7196 :
7197 : /* If op0 is a compare, extract the comparison arguments from it. */
7198 110571988 : if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
7199 : {
7200 14906809 : op1 = XEXP (op0, 1);
7201 14906809 : op0 = XEXP (op0, 0);
7202 :
7203 14906809 : if (GET_MODE (op0) != VOIDmode)
7204 14775452 : mode = GET_MODE (op0);
7205 131357 : else if (GET_MODE (op1) != VOIDmode)
7206 98867 : mode = GET_MODE (op1);
7207 : else
7208 : return 0;
7209 : }
7210 :
7211 : /* We can't simplify MODE_CC values since we don't know what the
7212 : actual comparison is. */
7213 110539498 : if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
7214 : return 0;
7215 :
7216 : /* Make sure the constant is second. */
7217 110539498 : if (swap_commutative_operands_p (op0, op1))
7218 : {
7219 3040483 : std::swap (op0, op1);
7220 3040483 : code = swap_condition (code);
7221 : }
7222 :
7223 110539498 : trueop0 = avoid_constant_pool_reference (op0);
7224 110539498 : trueop1 = avoid_constant_pool_reference (op1);
7225 :
7226 : /* For integer comparisons of A and B maybe we can simplify A - B and can
7227 : then simplify a comparison of that with zero. If A and B are both either
7228 : a register or a CONST_INT, this can't help; testing for these cases will
7229 : prevent infinite recursion here and speed things up.
7230 :
7231 : We can only do this for EQ and NE comparisons as otherwise we may
7232 : lose or introduce overflow which we cannot disregard as undefined as
7233 : we do not know the signedness of the operation on either the left or
7234 : the right hand side of the comparison. */
7235 :
7236 110539498 : if (INTEGRAL_MODE_P (mode)
7237 107799322 : && trueop1 != CONST0_RTX (mode)
7238 55572825 : && (code == EQ || code == NE)
7239 35576308 : && ! ((REG_P (op0)
7240 10355862 : || CONST_SCALAR_INT_P (trueop0)
7241 10326453 : || CONST_VECTOR_P (trueop0))
7242 25249875 : && (REG_P (op1)
7243 15044419 : || CONST_SCALAR_INT_P (trueop1)
7244 3507305 : || CONST_VECTOR_P (trueop1)))
7245 13830667 : && (tem = simplify_binary_operation (MINUS, mode, op0, op1)) != 0
7246 : /* We cannot do this if tem is a nonzero address. */
7247 7211892 : && ! nonzero_address_p (tem))
7248 7211890 : return simplify_const_relational_operation (signed_condition (code),
7249 7211890 : mode, tem, CONST0_RTX (mode));
7250 :
7251 103327608 : if (! HONOR_NANS (mode) && code == ORDERED)
7252 0 : return const_true_rtx;
7253 :
7254 103327608 : if (! HONOR_NANS (mode) && code == UNORDERED)
7255 8 : return const0_rtx;
7256 :
7257 : /* For modes without NaNs, if the two operands are equal, we know the
7258 : result except if they have side-effects. Even with NaNs we know
7259 : the result of unordered comparisons and, if signaling NaNs are
7260 : irrelevant, also the result of LT/GT/LTGT. */
7261 103327600 : if ((! HONOR_NANS (trueop0)
7262 2248195 : || code == UNEQ || code == UNLE || code == UNGE
7263 : || ((code == LT || code == GT || code == LTGT)
7264 946185 : && ! HONOR_SNANS (trueop0)))
7265 102132915 : && rtx_equal_p (trueop0, trueop1)
7266 103844140 : && ! side_effects_p (trueop0))
7267 516447 : return comparison_result (code, CMP_EQ);
7268 :
7269 : /* If the operands are floating-point constants, see if we can fold
7270 : the result. */
7271 102811153 : if (CONST_DOUBLE_AS_FLOAT_P (trueop0)
7272 1498 : && CONST_DOUBLE_AS_FLOAT_P (trueop1)
7273 1498 : && SCALAR_FLOAT_MODE_P (GET_MODE (trueop0)))
7274 : {
7275 1498 : const REAL_VALUE_TYPE *d0 = CONST_DOUBLE_REAL_VALUE (trueop0);
7276 1498 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
7277 :
7278 : /* Comparisons are unordered iff at least one of the values is NaN. */
7279 1498 : if (REAL_VALUE_ISNAN (*d0) || REAL_VALUE_ISNAN (*d1))
7280 173 : switch (code)
7281 : {
7282 0 : case UNEQ:
7283 0 : case UNLT:
7284 0 : case UNGT:
7285 0 : case UNLE:
7286 0 : case UNGE:
7287 0 : case NE:
7288 0 : case UNORDERED:
7289 0 : return const_true_rtx;
7290 173 : case EQ:
7291 173 : case LT:
7292 173 : case GT:
7293 173 : case LE:
7294 173 : case GE:
7295 173 : case LTGT:
7296 173 : case ORDERED:
7297 173 : return const0_rtx;
7298 : default:
7299 : return 0;
7300 : }
7301 :
7302 1486 : return comparison_result (code,
7303 1486 : (real_equal (d0, d1) ? CMP_EQ :
7304 1486 : real_less (d0, d1) ? CMP_LT : CMP_GT));
7305 : }
7306 :
7307 : /* Otherwise, see if the operands are both integers. */
7308 102809655 : if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
7309 99616529 : && CONST_SCALAR_INT_P (trueop0) && CONST_SCALAR_INT_P (trueop1))
7310 : {
7311 : /* It would be nice if we really had a mode here. However, the
7312 : largest int representable on the target is as good as
7313 : infinite. */
7314 203799 : machine_mode cmode = (mode == VOIDmode) ? MAX_MODE_INT : mode;
7315 203799 : rtx_mode_t ptrueop0 = rtx_mode_t (trueop0, cmode);
7316 203799 : rtx_mode_t ptrueop1 = rtx_mode_t (trueop1, cmode);
7317 :
7318 203799 : if (wi::eq_p (ptrueop0, ptrueop1))
7319 0 : return comparison_result (code, CMP_EQ);
7320 : else
7321 : {
7322 203799 : int cr = wi::lts_p (ptrueop0, ptrueop1) ? CMP_LT : CMP_GT;
7323 203799 : cr |= wi::ltu_p (ptrueop0, ptrueop1) ? CMP_LTU : CMP_GTU;
7324 203799 : return comparison_result (code, cr);
7325 : }
7326 : }
7327 :
7328 : /* Optimize comparisons with upper and lower bounds. */
7329 102605856 : scalar_int_mode int_mode;
7330 102605856 : if (CONST_INT_P (trueop1)
7331 71710481 : && is_a <scalar_int_mode> (mode, &int_mode)
7332 71710481 : && HWI_COMPUTABLE_MODE_P (int_mode)
7333 173855404 : && !side_effects_p (trueop0))
7334 : {
7335 71098213 : int sign;
7336 71098213 : unsigned HOST_WIDE_INT nonzero = nonzero_bits (trueop0, int_mode);
7337 71098213 : HOST_WIDE_INT val = INTVAL (trueop1);
7338 71098213 : HOST_WIDE_INT mmin, mmax;
7339 :
7340 71098213 : if (code == GEU
7341 71098213 : || code == LEU
7342 67738384 : || code == GTU
7343 67738384 : || code == LTU)
7344 : sign = 0;
7345 : else
7346 71098213 : sign = 1;
7347 :
7348 : /* Get a reduced range if the sign bit is zero. */
7349 71098213 : if (nonzero <= (GET_MODE_MASK (int_mode) >> 1))
7350 : {
7351 6298827 : mmin = 0;
7352 6298827 : mmax = nonzero;
7353 : }
7354 : else
7355 : {
7356 64799386 : rtx mmin_rtx, mmax_rtx;
7357 64799386 : get_mode_bounds (int_mode, sign, int_mode, &mmin_rtx, &mmax_rtx);
7358 :
7359 64799386 : mmin = INTVAL (mmin_rtx);
7360 64799386 : mmax = INTVAL (mmax_rtx);
7361 64799386 : if (sign)
7362 : {
7363 58526166 : unsigned int sign_copies
7364 58526166 : = num_sign_bit_copies (trueop0, int_mode);
7365 :
7366 58526166 : mmin >>= (sign_copies - 1);
7367 58526166 : mmax >>= (sign_copies - 1);
7368 : }
7369 : }
7370 :
7371 71098213 : switch (code)
7372 : {
7373 : /* x >= y is always true for y <= mmin, always false for y > mmax. */
7374 547074 : case GEU:
7375 547074 : if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
7376 5715 : return const_true_rtx;
7377 541359 : if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
7378 48 : return const0_rtx;
7379 : break;
7380 975620 : case GE:
7381 975620 : if (val <= mmin)
7382 1966 : return const_true_rtx;
7383 973654 : if (val > mmax)
7384 0 : return const0_rtx;
7385 : break;
7386 :
7387 : /* x <= y is always true for y >= mmax, always false for y < mmin. */
7388 2812755 : case LEU:
7389 2812755 : if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
7390 15340 : return const_true_rtx;
7391 2797415 : if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
7392 0 : return const0_rtx;
7393 : break;
7394 2660205 : case LE:
7395 2660205 : if (val >= mmax)
7396 445 : return const_true_rtx;
7397 2659760 : if (val < mmin)
7398 0 : return const0_rtx;
7399 : break;
7400 :
7401 25872785 : case EQ:
7402 : /* x == y is always false for y out of range. */
7403 25872785 : if (val < mmin || val > mmax)
7404 448 : return const0_rtx;
7405 : break;
7406 :
7407 : /* x > y is always false for y >= mmax, always true for y < mmin. */
7408 2520426 : case GTU:
7409 2520426 : if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
7410 40324 : return const0_rtx;
7411 2480102 : if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
7412 0 : return const_true_rtx;
7413 : break;
7414 1913959 : case GT:
7415 1913959 : if (val >= mmax)
7416 243 : return const0_rtx;
7417 1913716 : if (val < mmin)
7418 2 : return const_true_rtx;
7419 : break;
7420 :
7421 : /* x < y is always false for y <= mmin, always true for y > mmax. */
7422 864219 : case LTU:
7423 864219 : if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
7424 3569 : return const0_rtx;
7425 860650 : if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
7426 78993 : return const_true_rtx;
7427 : break;
7428 1117474 : case LT:
7429 1117474 : if (val <= mmin)
7430 2307 : return const0_rtx;
7431 1115167 : if (val > mmax)
7432 3154 : return const_true_rtx;
7433 : break;
7434 :
7435 31813696 : case NE:
7436 : /* x != y is always true for y out of range. */
7437 31813696 : if (val < mmin || val > mmax)
7438 154 : return const_true_rtx;
7439 : break;
7440 :
7441 : default:
7442 : break;
7443 : }
7444 : }
7445 :
7446 : /* Optimize integer comparisons with zero. */
7447 102453148 : if (is_a <scalar_int_mode> (mode, &int_mode)
7448 99303103 : && trueop1 == const0_rtx
7449 51489733 : && !side_effects_p (trueop0))
7450 : {
7451 : /* Some addresses are known to be nonzero. We don't know
7452 : their sign, but equality comparisons are known. */
7453 51336361 : if (nonzero_address_p (trueop0))
7454 : {
7455 533 : if (code == EQ || code == LEU)
7456 278 : return const0_rtx;
7457 255 : if (code == NE || code == GTU)
7458 255 : return const_true_rtx;
7459 : }
7460 :
7461 : /* See if the first operand is an IOR with a constant. If so, we
7462 : may be able to determine the result of this comparison. */
7463 51335828 : if (GET_CODE (op0) == IOR)
7464 : {
7465 674257 : rtx inner_const = avoid_constant_pool_reference (XEXP (op0, 1));
7466 674257 : if (CONST_INT_P (inner_const) && inner_const != const0_rtx)
7467 : {
7468 207 : int sign_bitnum = GET_MODE_PRECISION (int_mode) - 1;
7469 414 : int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
7470 207 : && (UINTVAL (inner_const)
7471 207 : & (HOST_WIDE_INT_1U
7472 : << sign_bitnum)));
7473 :
7474 207 : switch (code)
7475 : {
7476 : case EQ:
7477 : case LEU:
7478 : return const0_rtx;
7479 0 : case NE:
7480 0 : case GTU:
7481 0 : return const_true_rtx;
7482 13 : case LT:
7483 13 : case LE:
7484 13 : if (has_sign)
7485 2 : return const_true_rtx;
7486 : break;
7487 192 : case GT:
7488 192 : case GE:
7489 192 : if (has_sign)
7490 : return const0_rtx;
7491 : break;
7492 : default:
7493 : break;
7494 : }
7495 : }
7496 : }
7497 : }
7498 :
7499 : /* Optimize comparison of ABS with zero. */
7500 51839549 : if (trueop1 == CONST0_RTX (mode) && !side_effects_p (trueop0)
7501 154138283 : && (GET_CODE (trueop0) == ABS
7502 51685301 : || (GET_CODE (trueop0) == FLOAT_EXTEND
7503 90 : && GET_CODE (XEXP (trueop0, 0)) == ABS)))
7504 : {
7505 563 : switch (code)
7506 : {
7507 60 : case LT:
7508 : /* Optimize abs(x) < 0.0. */
7509 60 : if (!INTEGRAL_MODE_P (mode) && !HONOR_SNANS (mode))
7510 0 : return const0_rtx;
7511 : break;
7512 :
7513 42 : case GE:
7514 : /* Optimize abs(x) >= 0.0. */
7515 42 : if (!INTEGRAL_MODE_P (mode) && !HONOR_NANS (mode))
7516 0 : return const_true_rtx;
7517 : break;
7518 :
7519 0 : case UNGE:
7520 : /* Optimize ! (abs(x) < 0.0). */
7521 0 : return const_true_rtx;
7522 :
7523 : default:
7524 : break;
7525 : }
7526 : }
7527 :
7528 : return 0;
7529 : }
7530 :
7531 : /* Recognize expressions of the form (X CMP 0) ? VAL : OP (X)
7532 : where OP is CLZ or CTZ and VAL is the value from CLZ_DEFINED_VALUE_AT_ZERO
7533 : or CTZ_DEFINED_VALUE_AT_ZERO respectively and return OP (X) if the expression
7534 : can be simplified to that or NULL_RTX if not.
7535 : Assume X is compared against zero with CMP_CODE and the true
7536 : arm is TRUE_VAL and the false arm is FALSE_VAL. */
7537 :
7538 : rtx
7539 31992514 : simplify_context::simplify_cond_clz_ctz (rtx x, rtx_code cmp_code,
7540 : rtx true_val, rtx false_val)
7541 : {
7542 31992514 : if (cmp_code != EQ && cmp_code != NE)
7543 : return NULL_RTX;
7544 :
7545 : /* Result on X == 0 and X !=0 respectively. */
7546 23012211 : rtx on_zero, on_nonzero;
7547 23012211 : if (cmp_code == EQ)
7548 : {
7549 : on_zero = true_val;
7550 : on_nonzero = false_val;
7551 : }
7552 : else
7553 : {
7554 12517903 : on_zero = false_val;
7555 12517903 : on_nonzero = true_val;
7556 : }
7557 :
7558 23012211 : rtx_code op_code = GET_CODE (on_nonzero);
7559 23012211 : if ((op_code != CLZ && op_code != CTZ)
7560 2175 : || !rtx_equal_p (XEXP (on_nonzero, 0), x)
7561 23013310 : || !CONST_INT_P (on_zero))
7562 : return NULL_RTX;
7563 :
7564 294 : HOST_WIDE_INT op_val;
7565 294 : scalar_int_mode mode ATTRIBUTE_UNUSED
7566 294 : = as_a <scalar_int_mode> (GET_MODE (XEXP (on_nonzero, 0)));
7567 8 : if (((op_code == CLZ && CLZ_DEFINED_VALUE_AT_ZERO (mode, op_val))
7568 580 : || (op_code == CTZ && CTZ_DEFINED_VALUE_AT_ZERO (mode, op_val)))
7569 326 : && op_val == INTVAL (on_zero))
7570 0 : return on_nonzero;
7571 :
7572 : return NULL_RTX;
7573 : }
7574 :
7575 : /* Try to simplify X given that it appears within operand OP of a
7576 : VEC_MERGE operation whose mask is MASK. X need not use the same
7577 : vector mode as the VEC_MERGE, but it must have the same number of
7578 : elements.
7579 :
7580 : Return the simplified X on success, otherwise return NULL_RTX. */
7581 :
7582 : rtx
7583 2135780 : simplify_context::simplify_merge_mask (rtx x, rtx mask, int op)
7584 : {
7585 2135780 : gcc_assert (VECTOR_MODE_P (GET_MODE (x)));
7586 4271560 : poly_uint64 nunits = GET_MODE_NUNITS (GET_MODE (x));
7587 2135780 : if (GET_CODE (x) == VEC_MERGE && rtx_equal_p (XEXP (x, 2), mask))
7588 : {
7589 5491 : if (side_effects_p (XEXP (x, 1 - op)))
7590 : return NULL_RTX;
7591 :
7592 5267 : return XEXP (x, op);
7593 : }
7594 2130289 : if (UNARY_P (x)
7595 372529 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
7596 2188037 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits))
7597 : {
7598 24228 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
7599 24228 : if (top0)
7600 448 : return simplify_gen_unary (GET_CODE (x), GET_MODE (x), top0,
7601 448 : GET_MODE (XEXP (x, 0)));
7602 : }
7603 2129841 : if (BINARY_P (x)
7604 208647 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
7605 416666 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
7606 181020 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
7607 2417987 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits))
7608 : {
7609 144073 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
7610 144073 : rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
7611 144073 : if (top0 || top1)
7612 : {
7613 952 : if (COMPARISON_P (x))
7614 0 : return simplify_gen_relational (GET_CODE (x), GET_MODE (x),
7615 0 : GET_MODE (XEXP (x, 0)) != VOIDmode
7616 : ? GET_MODE (XEXP (x, 0))
7617 0 : : GET_MODE (XEXP (x, 1)),
7618 : top0 ? top0 : XEXP (x, 0),
7619 0 : top1 ? top1 : XEXP (x, 1));
7620 : else
7621 952 : return simplify_gen_binary (GET_CODE (x), GET_MODE (x),
7622 : top0 ? top0 : XEXP (x, 0),
7623 952 : top1 ? top1 : XEXP (x, 1));
7624 : }
7625 : }
7626 2128889 : if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY
7627 61973 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
7628 123946 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
7629 61973 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
7630 123946 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits)
7631 61973 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 2)))
7632 2145621 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 2))), nunits))
7633 : {
7634 8366 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
7635 8366 : rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
7636 8366 : rtx top2 = simplify_merge_mask (XEXP (x, 2), mask, op);
7637 8366 : if (top0 || top1 || top2)
7638 448 : return simplify_gen_ternary (GET_CODE (x), GET_MODE (x),
7639 448 : GET_MODE (XEXP (x, 0)),
7640 : top0 ? top0 : XEXP (x, 0),
7641 : top1 ? top1 : XEXP (x, 1),
7642 448 : top2 ? top2 : XEXP (x, 2));
7643 : }
7644 : return NULL_RTX;
7645 : }
7646 :
7647 :
7648 : /* Simplify CODE, an operation with result mode MODE and three operands,
7649 : OP0, OP1, and OP2. OP0_MODE was the mode of OP0 before it became
7650 : a constant. Return 0 if no simplifications is possible. */
7651 :
7652 : rtx
7653 44755325 : simplify_context::simplify_ternary_operation (rtx_code code, machine_mode mode,
7654 : machine_mode op0_mode,
7655 : rtx op0, rtx op1, rtx op2)
7656 : {
7657 44755325 : bool any_change = false;
7658 44755325 : rtx tem, trueop2;
7659 44755325 : scalar_int_mode int_mode, int_op0_mode;
7660 44755325 : unsigned int n_elts;
7661 :
7662 44755325 : switch (code)
7663 : {
7664 334058 : case FMA:
7665 : /* Simplify negations around the multiplication. */
7666 : /* -a * -b + c => a * b + c. */
7667 334058 : if (GET_CODE (op0) == NEG)
7668 : {
7669 82764 : tem = simplify_unary_operation (NEG, mode, op1, mode);
7670 82764 : if (tem)
7671 280 : op1 = tem, op0 = XEXP (op0, 0), any_change = true;
7672 : }
7673 251294 : else if (GET_CODE (op1) == NEG)
7674 : {
7675 1072 : tem = simplify_unary_operation (NEG, mode, op0, mode);
7676 1072 : if (tem)
7677 0 : op0 = tem, op1 = XEXP (op1, 0), any_change = true;
7678 : }
7679 :
7680 : /* Canonicalize the two multiplication operands. */
7681 : /* a * -b + c => -b * a + c. */
7682 334058 : if (swap_commutative_operands_p (op0, op1))
7683 : std::swap (op0, op1), any_change = true;
7684 :
7685 303921 : if (any_change)
7686 30408 : return gen_rtx_FMA (mode, op0, op1, op2);
7687 : return NULL_RTX;
7688 :
7689 797094 : case SIGN_EXTRACT:
7690 797094 : case ZERO_EXTRACT:
7691 797094 : if (CONST_INT_P (op0)
7692 17400 : && CONST_INT_P (op1)
7693 17400 : && CONST_INT_P (op2)
7694 44755357 : && is_a <scalar_int_mode> (mode, &int_mode)
7695 32 : && INTVAL (op1) + INTVAL (op2) <= GET_MODE_PRECISION (int_mode)
7696 797126 : && HWI_COMPUTABLE_MODE_P (int_mode))
7697 : {
7698 : /* Extracting a bit-field from a constant */
7699 32 : unsigned HOST_WIDE_INT val = UINTVAL (op0);
7700 32 : HOST_WIDE_INT op1val = INTVAL (op1);
7701 32 : HOST_WIDE_INT op2val = INTVAL (op2);
7702 32 : if (!BITS_BIG_ENDIAN)
7703 32 : val >>= op2val;
7704 : else if (is_a <scalar_int_mode> (op0_mode, &int_op0_mode))
7705 : val >>= GET_MODE_PRECISION (int_op0_mode) - op2val - op1val;
7706 : else
7707 : /* Not enough information to calculate the bit position. */
7708 : break;
7709 :
7710 32 : if (HOST_BITS_PER_WIDE_INT != op1val)
7711 : {
7712 : /* First zero-extend. */
7713 29 : val &= (HOST_WIDE_INT_1U << op1val) - 1;
7714 : /* If desired, propagate sign bit. */
7715 29 : if (code == SIGN_EXTRACT
7716 5 : && (val & (HOST_WIDE_INT_1U << (op1val - 1)))
7717 5 : != 0)
7718 2 : val |= ~ ((HOST_WIDE_INT_1U << op1val) - 1);
7719 : }
7720 :
7721 32 : return gen_int_mode (val, int_mode);
7722 : }
7723 : break;
7724 :
7725 42557008 : case IF_THEN_ELSE:
7726 42557008 : if (CONST_INT_P (op0))
7727 202999 : return op0 != const0_rtx ? op1 : op2;
7728 :
7729 : /* Convert c ? a : a into "a". Beware that two rtx_equal_p MEMs can
7730 : still carry different memory attributes, in particular incompatible
7731 : alias sets; returning one of them would narrow the aliasing of the
7732 : result to that operand's, which is unsound (PR125683). When the
7733 : attributes differ, fold to a copy that keeps only what both operands
7734 : guarantee, like merge_memattrs does when cross-jumping commons two
7735 : memory references. */
7736 42354009 : if (rtx_equal_p (op1, op2) && ! side_effects_p (op0))
7737 : {
7738 5404 : if (op1 == op2
7739 2967 : || !MEM_P (op1)
7740 5426 : || (mem_attrs_eq_p (get_mem_attrs (op1), get_mem_attrs (op2))
7741 8 : && MEM_READONLY_P (op1) == MEM_READONLY_P (op2)
7742 8 : && MEM_NOTRAP_P (op1) == MEM_NOTRAP_P (op2)
7743 8 : && MEM_POINTER (op1) == MEM_POINTER (op2)))
7744 : return op1;
7745 :
7746 : /* For BLKmode the size in MEM_ATTRS describes the access itself,
7747 : so it cannot be dropped. Volatility is not merged either: it
7748 : constrains when the access happens rather than describing the
7749 : memory, so unlike the flags below it cannot be weakened to what
7750 : both operands allow. Dropping it would lose a required access;
7751 : merge_memattrs and noce_try_cmove_arith instead set it, which is
7752 : sound but claims more than either operand did. Those two have to
7753 : put something on a reference they are already committed to, while
7754 : this fold is free to do nothing, and if-conversion never reaches
7755 : it with a volatile operand in any case: side_effects_p is true
7756 : for one, so noce_operand_ok rejects it. Decline the fold. */
7757 14 : if (GET_MODE (op1) != BLKmode
7758 14 : && MEM_VOLATILE_P (op1) == MEM_VOLATILE_P (op2))
7759 : {
7760 14 : rtx mem = shallow_copy_rtx (op1);
7761 :
7762 14 : if (MEM_ALIAS_SET (op1) != MEM_ALIAS_SET (op2))
7763 1 : set_mem_alias_set (mem, 0);
7764 :
7765 14 : if (!mem_expr_equal_p (MEM_EXPR (op1), MEM_EXPR (op2)))
7766 : {
7767 14 : set_mem_expr (mem, NULL_TREE);
7768 14 : clear_mem_offset (mem);
7769 : }
7770 0 : else if (MEM_OFFSET_KNOWN_P (op1) != MEM_OFFSET_KNOWN_P (op2)
7771 0 : || (MEM_OFFSET_KNOWN_P (op1)
7772 0 : && maybe_ne (MEM_OFFSET (op1), MEM_OFFSET (op2))))
7773 0 : clear_mem_offset (mem);
7774 :
7775 : /* Unlike merge_memattrs, which fixes up two references that
7776 : both stay in the stream, this returns a single reference
7777 : that stands in for either arm, so keep the size only when
7778 : both agree rather than taking the larger one. */
7779 28 : if (!MEM_SIZE_KNOWN_P (op1) || !MEM_SIZE_KNOWN_P (op2)
7780 28 : || maybe_ne (MEM_SIZE (op1), MEM_SIZE (op2)))
7781 0 : clear_mem_size (mem);
7782 :
7783 14 : set_mem_align (mem, MIN (MEM_ALIGN (op1), MEM_ALIGN (op2)));
7784 :
7785 : /* MEM_READONLY_P, MEM_NOTRAP_P and MEM_POINTER are rtx flag
7786 : bits rather than MEM_ATTRS fields, so shallow_copy_rtx has
7787 : already taken them from OP1 and they need clearing by hand.
7788 : Each asserts something about the reference, so the copy may
7789 : only keep it when both operands do, as merge_memattrs does
7790 : for the first two. */
7791 14 : if (MEM_READONLY_P (op1) != MEM_READONLY_P (op2))
7792 0 : MEM_READONLY_P (mem) = 0;
7793 14 : if (MEM_NOTRAP_P (op1) != MEM_NOTRAP_P (op2))
7794 0 : MEM_NOTRAP_P (mem) = 0;
7795 14 : if (MEM_POINTER (op1) != MEM_POINTER (op2))
7796 0 : MEM_POINTER (mem) = 0;
7797 :
7798 : return mem;
7799 : }
7800 : }
7801 :
7802 : /* Convert a != b ? a : b into "a". */
7803 42348605 : if (GET_CODE (op0) == NE
7804 16485704 : && ! side_effects_p (op0)
7805 16436923 : && ! HONOR_NANS (mode)
7806 16246468 : && ! HONOR_SIGNED_ZEROS (mode)
7807 58595073 : && ((rtx_equal_p (XEXP (op0, 0), op1)
7808 114243 : && rtx_equal_p (XEXP (op0, 1), op2))
7809 16246151 : || (rtx_equal_p (XEXP (op0, 0), op2)
7810 3785 : && rtx_equal_p (XEXP (op0, 1), op1))))
7811 : return op1;
7812 :
7813 : /* Convert a == b ? a : b into "b". */
7814 42348059 : if (GET_CODE (op0) == EQ
7815 13238339 : && ! side_effects_p (op0)
7816 13219164 : && ! HONOR_NANS (mode)
7817 13194038 : && ! HONOR_SIGNED_ZEROS (mode)
7818 55542097 : && ((rtx_equal_p (XEXP (op0, 0), op1)
7819 15439 : && rtx_equal_p (XEXP (op0, 1), op2))
7820 13194035 : || (rtx_equal_p (XEXP (op0, 0), op2)
7821 8090 : && rtx_equal_p (XEXP (op0, 1), op1))))
7822 : return op2;
7823 :
7824 : /* Convert a != 0 ? -a : 0 into "-a". */
7825 42348038 : if (GET_CODE (op0) == NE
7826 16485158 : && ! side_effects_p (op0)
7827 16436377 : && ! HONOR_NANS (mode)
7828 16245922 : && ! HONOR_SIGNED_ZEROS (mode)
7829 16245922 : && XEXP (op0, 1) == CONST0_RTX (mode)
7830 12327382 : && op2 == CONST0_RTX (mode)
7831 189372 : && GET_CODE (op1) == NEG
7832 42348087 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0)))
7833 : return op1;
7834 :
7835 : /* Convert a == 0 ? 0 : -a into "-a". */
7836 42348029 : if (GET_CODE (op0) == EQ
7837 13238318 : && ! side_effects_p (op0)
7838 13219143 : && ! HONOR_NANS (mode)
7839 13194017 : && ! HONOR_SIGNED_ZEROS (mode)
7840 13194017 : && op1 == CONST0_RTX (mode)
7841 43285 : && XEXP (op0, 1) == CONST0_RTX (mode)
7842 22615 : && GET_CODE (op2) == NEG
7843 42348035 : && rtx_equal_p (XEXP (op0, 0), XEXP (op2, 0)))
7844 : return op2;
7845 :
7846 : /* Convert (!c) != {0,...,0} ? a : b into
7847 : c != {0,...,0} ? b : a for vector modes. */
7848 42348023 : if (VECTOR_MODE_P (GET_MODE (op1))
7849 14643 : && GET_CODE (op0) == NE
7850 373 : && GET_CODE (XEXP (op0, 0)) == NOT
7851 0 : && GET_CODE (XEXP (op0, 1)) == CONST_VECTOR)
7852 : {
7853 0 : rtx cv = XEXP (op0, 1);
7854 0 : int nunits;
7855 0 : bool ok = true;
7856 0 : if (!CONST_VECTOR_NUNITS (cv).is_constant (&nunits))
7857 : ok = false;
7858 : else
7859 0 : for (int i = 0; i < nunits; ++i)
7860 0 : if (CONST_VECTOR_ELT (cv, i) != const0_rtx)
7861 : {
7862 : ok = false;
7863 : break;
7864 : }
7865 0 : if (ok)
7866 : {
7867 0 : rtx new_op0 = gen_rtx_NE (GET_MODE (op0),
7868 : XEXP (XEXP (op0, 0), 0),
7869 : XEXP (op0, 1));
7870 0 : rtx retval = gen_rtx_IF_THEN_ELSE (mode, new_op0, op2, op1);
7871 0 : return retval;
7872 : }
7873 : }
7874 :
7875 : /* Convert x == 0 ? N : clz (x) into clz (x) when
7876 : CLZ_DEFINED_VALUE_AT_ZERO is defined to N for the mode of x.
7877 : Similarly for ctz (x). */
7878 42347028 : if (COMPARISON_P (op0) && !side_effects_p (op0)
7879 84594477 : && XEXP (op0, 1) == const0_rtx)
7880 : {
7881 31992514 : rtx simplified
7882 31992514 : = simplify_cond_clz_ctz (XEXP (op0, 0), GET_CODE (op0),
7883 : op1, op2);
7884 31992514 : if (simplified)
7885 : return simplified;
7886 : }
7887 :
7888 42348023 : if (COMPARISON_P (op0) && ! side_effects_p (op0))
7889 : {
7890 84574050 : machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
7891 42246454 : ? GET_MODE (XEXP (op0, 1))
7892 : : GET_MODE (XEXP (op0, 0)));
7893 42246454 : rtx temp;
7894 :
7895 : /* Look for happy constants in op1 and op2. */
7896 42246454 : if (CONST_INT_P (op1) && CONST_INT_P (op2))
7897 : {
7898 234793 : HOST_WIDE_INT t = INTVAL (op1);
7899 234793 : HOST_WIDE_INT f = INTVAL (op2);
7900 :
7901 234793 : if (t == STORE_FLAG_VALUE && f == 0)
7902 55240 : code = GET_CODE (op0);
7903 179553 : else if (t == 0 && f == STORE_FLAG_VALUE)
7904 : {
7905 31377 : enum rtx_code tmp;
7906 31377 : tmp = reversed_comparison_code (op0, NULL);
7907 31377 : if (tmp == UNKNOWN)
7908 : break;
7909 : code = tmp;
7910 : }
7911 : else
7912 : break;
7913 :
7914 81389 : return simplify_gen_relational (code, mode, cmp_mode,
7915 81389 : XEXP (op0, 0), XEXP (op0, 1));
7916 : }
7917 :
7918 42011661 : temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
7919 : cmp_mode, XEXP (op0, 0),
7920 : XEXP (op0, 1));
7921 :
7922 : /* See if any simplifications were possible. */
7923 42011661 : if (temp)
7924 : {
7925 7161 : if (CONST_INT_P (temp))
7926 827 : return temp == const0_rtx ? op2 : op1;
7927 6334 : else if (temp)
7928 6334 : return gen_rtx_IF_THEN_ELSE (mode, temp, op1, op2);
7929 : }
7930 : }
7931 : break;
7932 :
7933 1067165 : case VEC_MERGE:
7934 1067165 : gcc_assert (GET_MODE (op0) == mode);
7935 1067165 : gcc_assert (GET_MODE (op1) == mode);
7936 1067165 : gcc_assert (VECTOR_MODE_P (mode));
7937 1067165 : trueop2 = avoid_constant_pool_reference (op2);
7938 1067165 : if (CONST_INT_P (trueop2)
7939 1807787 : && GET_MODE_NUNITS (mode).is_constant (&n_elts))
7940 : {
7941 740622 : unsigned HOST_WIDE_INT sel = UINTVAL (trueop2);
7942 740622 : unsigned HOST_WIDE_INT mask;
7943 740622 : if (n_elts == HOST_BITS_PER_WIDE_INT)
7944 : mask = -1;
7945 : else
7946 738143 : mask = (HOST_WIDE_INT_1U << n_elts) - 1;
7947 :
7948 740622 : if (!(sel & mask) && !side_effects_p (op0))
7949 : return op1;
7950 740197 : if ((sel & mask) == mask && !side_effects_p (op1))
7951 : return op0;
7952 :
7953 729087 : rtx trueop0 = avoid_constant_pool_reference (op0);
7954 729087 : rtx trueop1 = avoid_constant_pool_reference (op1);
7955 729087 : if (GET_CODE (trueop0) == CONST_VECTOR
7956 11150 : && GET_CODE (trueop1) == CONST_VECTOR)
7957 : {
7958 6790 : rtvec v = rtvec_alloc (n_elts);
7959 6790 : unsigned int i;
7960 :
7961 66426 : for (i = 0; i < n_elts; i++)
7962 52846 : RTVEC_ELT (v, i) = ((sel & (HOST_WIDE_INT_1U << i))
7963 52846 : ? CONST_VECTOR_ELT (trueop0, i)
7964 31009 : : CONST_VECTOR_ELT (trueop1, i));
7965 6790 : return gen_rtx_CONST_VECTOR (mode, v);
7966 : }
7967 :
7968 722297 : if (swap_commutative_operands_p (op0, op1)
7969 : /* Two operands have same precedence, then first bit of mask
7970 : select first operand. */
7971 722297 : || (!swap_commutative_operands_p (op1, op0) && !(sel & 1)))
7972 34631 : return simplify_gen_ternary (code, mode, mode, op1, op0,
7973 69262 : GEN_INT (~sel & mask));
7974 :
7975 : /* Replace (vec_merge (vec_merge a b m) c n) with (vec_merge b c n)
7976 : if no element from a appears in the result. */
7977 687666 : if (GET_CODE (op0) == VEC_MERGE)
7978 : {
7979 51244 : tem = avoid_constant_pool_reference (XEXP (op0, 2));
7980 51244 : if (CONST_INT_P (tem))
7981 : {
7982 35521 : unsigned HOST_WIDE_INT sel0 = UINTVAL (tem);
7983 35521 : if (!(sel & sel0 & mask) && !side_effects_p (XEXP (op0, 0)))
7984 99 : return simplify_gen_ternary (code, mode, mode,
7985 99 : XEXP (op0, 1), op1, op2);
7986 35422 : if (!(sel & ~sel0 & mask) && !side_effects_p (XEXP (op0, 1)))
7987 815 : return simplify_gen_ternary (code, mode, mode,
7988 815 : XEXP (op0, 0), op1, op2);
7989 :
7990 : /* Replace (vec_merge (vec_merge a b m) a n) with
7991 : (vec_merge a b (m|~n)). */
7992 34607 : if (rtx_equal_p (XEXP (op0, 0), op1)
7993 34607 : && ! side_effects_p (op1))
7994 463 : return simplify_gen_ternary (code, mode, mode,
7995 : op1, XEXP (op0, 1),
7996 926 : GEN_INT ((sel0 | ~sel) & mask));
7997 : /* Replace (vec_merge (vec_merge b a m) a n) with
7998 : (vec_merge b a (m&n)). */
7999 34144 : if (rtx_equal_p (XEXP (op0, 1), op1)
8000 34144 : && ! side_effects_p (op1))
8001 57 : return simplify_gen_ternary (code, mode, mode,
8002 : XEXP (op0, 0), op1,
8003 57 : GEN_INT (sel & sel0 & mask));
8004 : }
8005 : }
8006 686232 : if (GET_CODE (op1) == VEC_MERGE)
8007 : {
8008 580 : tem = avoid_constant_pool_reference (XEXP (op1, 2));
8009 580 : if (CONST_INT_P (tem))
8010 : {
8011 549 : unsigned HOST_WIDE_INT sel1 = UINTVAL (tem);
8012 549 : if (!(~sel & sel1 & mask) && !side_effects_p (XEXP (op1, 0)))
8013 518 : return simplify_gen_ternary (code, mode, mode,
8014 518 : op0, XEXP (op1, 1), op2);
8015 31 : if (!(~sel & ~sel1 & mask) && !side_effects_p (XEXP (op1, 1)))
8016 4 : return simplify_gen_ternary (code, mode, mode,
8017 4 : op0, XEXP (op1, 0), op2);
8018 :
8019 : /* Replace (vec_merge a (vec_merge a b m) n) with
8020 : (vec_merge a b (m|n)). */
8021 27 : if (rtx_equal_p (XEXP (op1, 0), op0)
8022 27 : && ! side_effects_p (op0))
8023 1 : return simplify_gen_ternary (code, mode, mode,
8024 : op0, XEXP (op1, 1),
8025 1 : GEN_INT ((sel | sel1) & mask));
8026 :
8027 : /* Replace (vec_merge a (vec_merge b a m) n) with
8028 : (vec_merge a b (~m|n)). */
8029 26 : if (rtx_equal_p (XEXP (op1, 1), op0)
8030 26 : && ! side_effects_p (op0))
8031 0 : return simplify_gen_ternary (code, mode, mode,
8032 : op0, XEXP (op1, 0),
8033 0 : GEN_INT ((sel | ~sel1) & mask));
8034 : }
8035 : }
8036 :
8037 : /* Replace (vec_merge (vec_duplicate (vec_select a parallel (i))) a 1 << i)
8038 : with a. */
8039 685709 : if (GET_CODE (op0) == VEC_DUPLICATE
8040 375751 : && GET_CODE (XEXP (op0, 0)) == VEC_SELECT
8041 1351 : && GET_CODE (XEXP (XEXP (op0, 0), 1)) == PARALLEL
8042 688411 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (op0, 0))), 1))
8043 : {
8044 1283 : tem = XVECEXP ((XEXP (XEXP (op0, 0), 1)), 0, 0);
8045 1283 : if (CONST_INT_P (tem) && CONST_INT_P (op2))
8046 : {
8047 1283 : if (XEXP (XEXP (op0, 0), 0) == op1
8048 2 : && UINTVAL (op2) == HOST_WIDE_INT_1U << UINTVAL (tem))
8049 : return op1;
8050 : }
8051 : }
8052 : /* Replace (vec_merge (vec_duplicate (X)) (const_vector [A, B])
8053 : (const_int N))
8054 : with (vec_concat (X) (B)) if N == 1 or
8055 : (vec_concat (A) (X)) if N == 2. */
8056 685707 : if (GET_CODE (op0) == VEC_DUPLICATE
8057 375749 : && GET_CODE (op1) == CONST_VECTOR
8058 536608 : && known_eq (CONST_VECTOR_NUNITS (op1), 2)
8059 1800 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
8060 686607 : && IN_RANGE (sel, 1, 2))
8061 : {
8062 898 : rtx newop0 = XEXP (op0, 0);
8063 898 : rtx newop1 = CONST_VECTOR_ELT (op1, 2 - sel);
8064 898 : if (sel == 2)
8065 111 : std::swap (newop0, newop1);
8066 898 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
8067 : }
8068 : /* Replace (vec_merge (vec_duplicate x) (vec_concat (y) (z)) (const_int N))
8069 : with (vec_concat x z) if N == 1, or (vec_concat y x) if N == 2.
8070 : Only applies for vectors of two elements. */
8071 684809 : if (GET_CODE (op0) == VEC_DUPLICATE
8072 374851 : && GET_CODE (op1) == VEC_CONCAT
8073 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
8074 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
8075 684809 : && IN_RANGE (sel, 1, 2))
8076 : {
8077 0 : rtx newop0 = XEXP (op0, 0);
8078 0 : rtx newop1 = XEXP (op1, 2 - sel);
8079 0 : rtx otherop = XEXP (op1, sel - 1);
8080 0 : if (sel == 2)
8081 0 : std::swap (newop0, newop1);
8082 : /* Don't want to throw away the other part of the vec_concat if
8083 : it has side-effects. */
8084 0 : if (!side_effects_p (otherop))
8085 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
8086 : }
8087 :
8088 : /* Replace:
8089 :
8090 : (vec_merge:outer (vec_duplicate:outer x:inner)
8091 : (subreg:outer y:inner 0)
8092 : (const_int N))
8093 :
8094 : with (vec_concat:outer x:inner y:inner) if N == 1,
8095 : or (vec_concat:outer y:inner x:inner) if N == 2.
8096 :
8097 : Implicitly, this means we have a paradoxical subreg, but such
8098 : a check is cheap, so make it anyway.
8099 :
8100 : Only applies for vectors of two elements. */
8101 684809 : if (GET_CODE (op0) == VEC_DUPLICATE
8102 374851 : && GET_CODE (op1) == SUBREG
8103 35321 : && GET_MODE (op1) == GET_MODE (op0)
8104 35321 : && GET_MODE (SUBREG_REG (op1)) == GET_MODE (XEXP (op0, 0))
8105 0 : && paradoxical_subreg_p (op1)
8106 0 : && subreg_lowpart_p (op1)
8107 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
8108 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
8109 684809 : && IN_RANGE (sel, 1, 2))
8110 : {
8111 0 : rtx newop0 = XEXP (op0, 0);
8112 0 : rtx newop1 = SUBREG_REG (op1);
8113 0 : if (sel == 2)
8114 0 : std::swap (newop0, newop1);
8115 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
8116 : }
8117 :
8118 : /* Same as above but with switched operands:
8119 : Replace (vec_merge:outer (subreg:outer x:inner 0)
8120 : (vec_duplicate:outer y:inner)
8121 : (const_int N))
8122 :
8123 : with (vec_concat:outer x:inner y:inner) if N == 1,
8124 : or (vec_concat:outer y:inner x:inner) if N == 2. */
8125 684809 : if (GET_CODE (op1) == VEC_DUPLICATE
8126 57856 : && GET_CODE (op0) == SUBREG
8127 21064 : && GET_MODE (op0) == GET_MODE (op1)
8128 21064 : && GET_MODE (SUBREG_REG (op0)) == GET_MODE (XEXP (op1, 0))
8129 0 : && paradoxical_subreg_p (op0)
8130 0 : && subreg_lowpart_p (op0)
8131 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
8132 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
8133 684809 : && IN_RANGE (sel, 1, 2))
8134 : {
8135 0 : rtx newop0 = SUBREG_REG (op0);
8136 0 : rtx newop1 = XEXP (op1, 0);
8137 0 : if (sel == 2)
8138 0 : std::swap (newop0, newop1);
8139 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
8140 : }
8141 :
8142 : /* Replace (vec_merge (vec_duplicate x) (vec_duplicate y)
8143 : (const_int n))
8144 : with (vec_concat x y) or (vec_concat y x) depending on value
8145 : of N. */
8146 684809 : if (GET_CODE (op0) == VEC_DUPLICATE
8147 374851 : && GET_CODE (op1) == VEC_DUPLICATE
8148 208 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
8149 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
8150 684809 : && IN_RANGE (sel, 1, 2))
8151 : {
8152 0 : rtx newop0 = XEXP (op0, 0);
8153 0 : rtx newop1 = XEXP (op1, 0);
8154 0 : if (sel == 2)
8155 0 : std::swap (newop0, newop1);
8156 :
8157 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
8158 : }
8159 : }
8160 :
8161 1011352 : if (rtx_equal_p (op0, op1)
8162 1011352 : && !side_effects_p (op2) && !side_effects_p (op1))
8163 : return op0;
8164 :
8165 1011054 : if (!side_effects_p (op2))
8166 : {
8167 1007266 : rtx top0
8168 1007266 : = may_trap_p (op0) ? NULL_RTX : simplify_merge_mask (op0, op2, 0);
8169 1007266 : rtx top1
8170 1007266 : = may_trap_p (op1) ? NULL_RTX : simplify_merge_mask (op1, op2, 1);
8171 1007266 : if (top0 || top1)
8172 998 : return simplify_gen_ternary (code, mode, mode,
8173 : top0 ? top0 : op0,
8174 819 : top1 ? top1 : op1, op2);
8175 : }
8176 :
8177 : break;
8178 :
8179 0 : default:
8180 0 : gcc_unreachable ();
8181 : }
8182 :
8183 : return 0;
8184 : }
8185 :
8186 : /* Try to calculate NUM_BYTES bytes of the target memory image of X,
8187 : starting at byte FIRST_BYTE. Return true on success and add the
8188 : bytes to BYTES, such that each byte has BITS_PER_UNIT bits and such
8189 : that the bytes follow target memory order. Leave BYTES unmodified
8190 : on failure.
8191 :
8192 : MODE is the mode of X. The caller must reserve NUM_BYTES bytes in
8193 : BYTES before calling this function. */
8194 :
8195 : bool
8196 14083583 : native_encode_rtx (machine_mode mode, rtx x, vec<target_unit> &bytes,
8197 : unsigned int first_byte, unsigned int num_bytes)
8198 : {
8199 : /* Check the mode is sensible. */
8200 14083583 : gcc_assert (GET_MODE (x) == VOIDmode
8201 : ? is_a <scalar_int_mode> (mode)
8202 : : mode == GET_MODE (x));
8203 :
8204 14083583 : if (GET_CODE (x) == CONST_VECTOR)
8205 : {
8206 : /* CONST_VECTOR_ELT follows target memory order, so no shuffling
8207 : is necessary. The only complication is that MODE_VECTOR_BOOL
8208 : vectors can have several elements per byte. */
8209 1154438 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
8210 : GET_MODE_NUNITS (mode));
8211 577219 : unsigned int elt = first_byte * BITS_PER_UNIT / elt_bits;
8212 577219 : if (elt_bits < BITS_PER_UNIT)
8213 : {
8214 : /* This is the only case in which elements can be smaller than
8215 : a byte. */
8216 0 : gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
8217 0 : auto mask = GET_MODE_MASK (GET_MODE_INNER (mode));
8218 0 : for (unsigned int i = 0; i < num_bytes; ++i)
8219 : {
8220 0 : target_unit value = 0;
8221 0 : for (unsigned int j = 0; j < BITS_PER_UNIT; j += elt_bits)
8222 : {
8223 0 : if (INTVAL (CONST_VECTOR_ELT (x, elt)))
8224 0 : value |= mask << j;
8225 0 : elt += 1;
8226 : }
8227 0 : bytes.quick_push (value);
8228 : }
8229 : return true;
8230 : }
8231 :
8232 577219 : unsigned int start = bytes.length ();
8233 577219 : unsigned int elt_bytes = GET_MODE_UNIT_SIZE (mode);
8234 : /* Make FIRST_BYTE relative to ELT. */
8235 577219 : first_byte %= elt_bytes;
8236 2845846 : while (num_bytes > 0)
8237 : {
8238 : /* Work out how many bytes we want from element ELT. */
8239 2268627 : unsigned int chunk_bytes = MIN (num_bytes, elt_bytes - first_byte);
8240 4537254 : if (!native_encode_rtx (GET_MODE_INNER (mode),
8241 : CONST_VECTOR_ELT (x, elt), bytes,
8242 : first_byte, chunk_bytes))
8243 : {
8244 0 : bytes.truncate (start);
8245 0 : return false;
8246 : }
8247 2268627 : elt += 1;
8248 2268627 : first_byte = 0;
8249 2268627 : num_bytes -= chunk_bytes;
8250 : }
8251 : return true;
8252 : }
8253 :
8254 : /* All subsequent cases are limited to scalars. */
8255 13506364 : scalar_mode smode;
8256 13506364 : if (!is_a <scalar_mode> (mode, &smode))
8257 : return false;
8258 :
8259 : /* Make sure that the region is in range. */
8260 13506364 : unsigned int end_byte = first_byte + num_bytes;
8261 13506364 : unsigned int mode_bytes = GET_MODE_SIZE (smode);
8262 13506364 : gcc_assert (end_byte <= mode_bytes);
8263 :
8264 13506364 : if (CONST_SCALAR_INT_P (x))
8265 : {
8266 : /* The target memory layout is affected by both BYTES_BIG_ENDIAN
8267 : and WORDS_BIG_ENDIAN. Use the subreg machinery to get the lsb
8268 : position of each byte. */
8269 12823396 : rtx_mode_t value (x, smode);
8270 12823396 : wide_int_ref value_wi (value);
8271 67574777 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
8272 : {
8273 : /* Always constant because the inputs are. */
8274 41927985 : unsigned int lsb
8275 41927985 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
8276 : /* Operate directly on the encoding rather than using
8277 : wi::extract_uhwi, so that we preserve the sign or zero
8278 : extension for modes that are not a whole number of bits in
8279 : size. (Zero extension is only used for the combination of
8280 : innermode == BImode && STORE_FLAG_VALUE == 1). */
8281 41927985 : unsigned int elt = lsb / HOST_BITS_PER_WIDE_INT;
8282 41927985 : unsigned int shift = lsb % HOST_BITS_PER_WIDE_INT;
8283 41927985 : unsigned HOST_WIDE_INT uhwi = value_wi.elt (elt);
8284 41927985 : bytes.quick_push (uhwi >> shift);
8285 : }
8286 12823396 : return true;
8287 : }
8288 :
8289 682968 : if (CONST_DOUBLE_P (x))
8290 : {
8291 : /* real_to_target produces an array of integers in target memory order.
8292 : All integers before the last one have 32 bits; the last one may
8293 : have 32 bits or fewer, depending on whether the mode bitsize
8294 : is divisible by 32. Each of these integers is then laid out
8295 : in target memory as any other integer would be. */
8296 654766 : long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
8297 654766 : real_to_target (el32, CONST_DOUBLE_REAL_VALUE (x), smode);
8298 :
8299 : /* The (maximum) number of target bytes per element of el32. */
8300 654766 : unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
8301 654766 : gcc_assert (bytes_per_el32 != 0);
8302 :
8303 : /* Build up the integers in a similar way to the CONST_SCALAR_INT_P
8304 : handling above. */
8305 4483569 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
8306 : {
8307 3828803 : unsigned int index = byte / bytes_per_el32;
8308 3828803 : unsigned int subbyte = byte % bytes_per_el32;
8309 3828803 : unsigned int int_bytes = MIN (bytes_per_el32,
8310 : mode_bytes - index * bytes_per_el32);
8311 : /* Always constant because the inputs are. */
8312 3828803 : unsigned int lsb
8313 3828803 : = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
8314 3828803 : bytes.quick_push ((unsigned long) el32[index] >> lsb);
8315 : }
8316 654766 : return true;
8317 : }
8318 :
8319 28202 : if (GET_CODE (x) == CONST_FIXED)
8320 : {
8321 0 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
8322 : {
8323 : /* Always constant because the inputs are. */
8324 0 : unsigned int lsb
8325 0 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
8326 0 : unsigned HOST_WIDE_INT piece = CONST_FIXED_VALUE_LOW (x);
8327 0 : if (lsb >= HOST_BITS_PER_WIDE_INT)
8328 : {
8329 0 : lsb -= HOST_BITS_PER_WIDE_INT;
8330 0 : piece = CONST_FIXED_VALUE_HIGH (x);
8331 : }
8332 0 : bytes.quick_push (piece >> lsb);
8333 : }
8334 : return true;
8335 : }
8336 :
8337 : return false;
8338 : }
8339 :
8340 : /* Read a vector of mode MODE from the target memory image given by BYTES,
8341 : starting at byte FIRST_BYTE. The vector is known to be encodable using
8342 : NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each,
8343 : and BYTES is known to have enough bytes to supply NPATTERNS *
8344 : NELTS_PER_PATTERN vector elements. Each element of BYTES contains
8345 : BITS_PER_UNIT bits and the bytes are in target memory order.
8346 :
8347 : Return the vector on success, otherwise return NULL_RTX. */
8348 :
8349 : rtx
8350 309044 : native_decode_vector_rtx (machine_mode mode, const vec<target_unit> &bytes,
8351 : unsigned int first_byte, unsigned int npatterns,
8352 : unsigned int nelts_per_pattern)
8353 : {
8354 309044 : rtx_vector_builder builder (mode, npatterns, nelts_per_pattern);
8355 :
8356 618088 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
8357 : GET_MODE_NUNITS (mode));
8358 309044 : if (elt_bits < BITS_PER_UNIT)
8359 : {
8360 : /* This is the only case in which elements can be smaller than a byte.
8361 : Element 0 is always in the lsb of the containing byte. */
8362 0 : gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
8363 0 : for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
8364 : {
8365 0 : unsigned int bit_index = first_byte * BITS_PER_UNIT + i * elt_bits;
8366 0 : unsigned int byte_index = bit_index / BITS_PER_UNIT;
8367 0 : unsigned int lsb = bit_index % BITS_PER_UNIT;
8368 0 : unsigned int value = bytes[byte_index] >> lsb;
8369 0 : builder.quick_push (gen_int_mode (value, GET_MODE_INNER (mode)));
8370 : }
8371 : }
8372 : else
8373 : {
8374 1236107 : for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
8375 : {
8376 1854126 : rtx x = native_decode_rtx (GET_MODE_INNER (mode), bytes, first_byte);
8377 927063 : if (!x)
8378 0 : return NULL_RTX;
8379 927063 : builder.quick_push (x);
8380 927063 : first_byte += elt_bits / BITS_PER_UNIT;
8381 : }
8382 : }
8383 309044 : return builder.build ();
8384 309044 : }
8385 :
8386 : /* Extract a PRECISION-bit integer from bytes [FIRST_BYTE, FIRST_BYTE + SIZE)
8387 : of target memory image BYTES. */
8388 :
8389 : wide_int
8390 11948511 : native_decode_int (const vec<target_unit> &bytes, unsigned int first_byte,
8391 : unsigned int size, unsigned int precision)
8392 : {
8393 : /* Pull the bytes msb first, so that we can use simple
8394 : shift-and-insert wide_int operations. */
8395 11948511 : wide_int result (wi::zero (precision));
8396 55343487 : for (unsigned int i = 0; i < size; ++i)
8397 : {
8398 43394976 : unsigned int lsb = (size - i - 1) * BITS_PER_UNIT;
8399 : /* Always constant because the inputs are. */
8400 43394976 : unsigned int subbyte
8401 43394976 : = subreg_size_offset_from_lsb (1, size, lsb).to_constant ();
8402 43394976 : result <<= BITS_PER_UNIT;
8403 43394976 : result |= bytes[first_byte + subbyte];
8404 : }
8405 11948511 : return result;
8406 : }
8407 :
8408 : /* Read an rtx of mode MODE from the target memory image given by BYTES,
8409 : starting at byte FIRST_BYTE. Each element of BYTES contains BITS_PER_UNIT
8410 : bits and the bytes are in target memory order. The image has enough
8411 : values to specify all bytes of MODE.
8412 :
8413 : Return the rtx on success, otherwise return NULL_RTX. */
8414 :
8415 : rtx
8416 12288703 : native_decode_rtx (machine_mode mode, const vec<target_unit> &bytes,
8417 : unsigned int first_byte)
8418 : {
8419 12288703 : if (VECTOR_MODE_P (mode))
8420 : {
8421 : /* If we know at compile time how many elements there are,
8422 : pull each element directly from BYTES. */
8423 94494 : unsigned int nelts;
8424 188988 : if (GET_MODE_NUNITS (mode).is_constant (&nelts))
8425 94494 : return native_decode_vector_rtx (mode, bytes, first_byte, nelts, 1);
8426 : return NULL_RTX;
8427 : }
8428 :
8429 12194209 : scalar_int_mode imode;
8430 12194209 : if (is_a <scalar_int_mode> (mode, &imode)
8431 11948511 : && GET_MODE_PRECISION (imode) <= MAX_BITSIZE_MODE_ANY_INT)
8432 : {
8433 11948511 : auto result = native_decode_int (bytes, first_byte,
8434 11948511 : GET_MODE_SIZE (imode),
8435 23897022 : GET_MODE_PRECISION (imode));
8436 11948511 : return immed_wide_int_const (result, imode);
8437 11948511 : }
8438 :
8439 245698 : scalar_float_mode fmode;
8440 245698 : if (is_a <scalar_float_mode> (mode, &fmode))
8441 : {
8442 : /* We need to build an array of integers in target memory order.
8443 : All integers before the last one have 32 bits; the last one may
8444 : have 32 bits or fewer, depending on whether the mode bitsize
8445 : is divisible by 32. */
8446 245668 : long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
8447 245668 : unsigned int num_el32 = CEIL (GET_MODE_BITSIZE (fmode), 32);
8448 245668 : memset (el32, 0, num_el32 * sizeof (long));
8449 :
8450 : /* The (maximum) number of target bytes per element of el32. */
8451 245668 : unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
8452 245668 : gcc_assert (bytes_per_el32 != 0);
8453 :
8454 245668 : unsigned int mode_bytes = GET_MODE_SIZE (fmode);
8455 1708530 : for (unsigned int byte = 0; byte < mode_bytes; ++byte)
8456 : {
8457 1462862 : unsigned int index = byte / bytes_per_el32;
8458 1462862 : unsigned int subbyte = byte % bytes_per_el32;
8459 1462862 : unsigned int int_bytes = MIN (bytes_per_el32,
8460 : mode_bytes - index * bytes_per_el32);
8461 : /* Always constant because the inputs are. */
8462 1462862 : unsigned int lsb
8463 1462862 : = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
8464 1462862 : el32[index] |= (unsigned long) bytes[first_byte + byte] << lsb;
8465 : }
8466 245668 : REAL_VALUE_TYPE r;
8467 245668 : real_from_target (&r, el32, fmode);
8468 245668 : return const_double_from_real_value (r, fmode);
8469 : }
8470 :
8471 30 : if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
8472 : {
8473 0 : scalar_mode smode = as_a <scalar_mode> (mode);
8474 0 : FIXED_VALUE_TYPE f;
8475 0 : f.data.low = 0;
8476 0 : f.data.high = 0;
8477 0 : f.mode = smode;
8478 :
8479 0 : unsigned int mode_bytes = GET_MODE_SIZE (smode);
8480 0 : for (unsigned int byte = 0; byte < mode_bytes; ++byte)
8481 : {
8482 : /* Always constant because the inputs are. */
8483 0 : unsigned int lsb
8484 0 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
8485 0 : unsigned HOST_WIDE_INT unit = bytes[first_byte + byte];
8486 0 : if (lsb >= HOST_BITS_PER_WIDE_INT)
8487 0 : f.data.high |= unit << (lsb - HOST_BITS_PER_WIDE_INT);
8488 : else
8489 0 : f.data.low |= unit << lsb;
8490 : }
8491 0 : return CONST_FIXED_FROM_FIXED_VALUE (f, mode);
8492 : }
8493 :
8494 : return NULL_RTX;
8495 : }
8496 :
8497 : /* Simplify a byte offset BYTE into CONST_VECTOR X. The main purpose
8498 : is to convert a runtime BYTE value into a constant one. */
8499 :
8500 : static poly_uint64
8501 364304 : simplify_const_vector_byte_offset (rtx x, poly_uint64 byte)
8502 : {
8503 : /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
8504 364304 : machine_mode mode = GET_MODE (x);
8505 728608 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
8506 : GET_MODE_NUNITS (mode));
8507 : /* The number of bits needed to encode one element from each pattern. */
8508 364304 : unsigned int sequence_bits = CONST_VECTOR_NPATTERNS (x) * elt_bits;
8509 :
8510 : /* Identify the start point in terms of a sequence number and a byte offset
8511 : within that sequence. */
8512 364304 : poly_uint64 first_sequence;
8513 364304 : unsigned HOST_WIDE_INT subbit;
8514 364304 : if (can_div_trunc_p (byte * BITS_PER_UNIT, sequence_bits,
8515 : &first_sequence, &subbit))
8516 : {
8517 364304 : unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
8518 364304 : if (nelts_per_pattern == 1)
8519 : /* This is a duplicated vector, so the value of FIRST_SEQUENCE
8520 : doesn't matter. */
8521 280851 : byte = subbit / BITS_PER_UNIT;
8522 83453 : else if (nelts_per_pattern == 2 && known_gt (first_sequence, 0U))
8523 : {
8524 : /* The subreg drops the first element from each pattern and
8525 : only uses the second element. Find the first sequence
8526 : that starts on a byte boundary. */
8527 5568 : subbit += least_common_multiple (sequence_bits, BITS_PER_UNIT);
8528 5568 : byte = subbit / BITS_PER_UNIT;
8529 : }
8530 : }
8531 364304 : return byte;
8532 : }
8533 :
8534 : /* Subroutine of simplify_subreg in which:
8535 :
8536 : - X is known to be a CONST_VECTOR
8537 : - OUTERMODE is known to be a vector mode
8538 :
8539 : Try to handle the subreg by operating on the CONST_VECTOR encoding
8540 : rather than on each individual element of the CONST_VECTOR.
8541 :
8542 : Return the simplified subreg on success, otherwise return NULL_RTX. */
8543 :
8544 : static rtx
8545 222710 : simplify_const_vector_subreg (machine_mode outermode, rtx x,
8546 : machine_mode innermode, unsigned int first_byte)
8547 : {
8548 : /* Paradoxical subregs of vectors have dubious semantics. */
8549 222710 : if (paradoxical_subreg_p (outermode, innermode))
8550 : return NULL_RTX;
8551 :
8552 : /* We can only preserve the semantics of a stepped pattern if the new
8553 : vector element is the same as the original one. */
8554 222539 : if (CONST_VECTOR_STEPPED_P (x)
8555 243741 : && GET_MODE_INNER (outermode) != GET_MODE_INNER (innermode))
8556 : return NULL_RTX;
8557 :
8558 : /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
8559 214550 : unsigned int x_elt_bits
8560 214550 : = vector_element_size (GET_MODE_PRECISION (innermode),
8561 : GET_MODE_NUNITS (innermode));
8562 214550 : unsigned int out_elt_bits
8563 214550 : = vector_element_size (GET_MODE_PRECISION (outermode),
8564 : GET_MODE_NUNITS (outermode));
8565 :
8566 : /* The number of bits needed to encode one element from every pattern
8567 : of the original vector. */
8568 214550 : unsigned int x_sequence_bits = CONST_VECTOR_NPATTERNS (x) * x_elt_bits;
8569 :
8570 : /* The number of bits needed to encode one element from every pattern
8571 : of the result. */
8572 214550 : unsigned int out_sequence_bits
8573 214550 : = least_common_multiple (x_sequence_bits, out_elt_bits);
8574 :
8575 : /* Work out the number of interleaved patterns in the output vector
8576 : and the number of encoded elements per pattern. */
8577 214550 : unsigned int out_npatterns = out_sequence_bits / out_elt_bits;
8578 214550 : unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
8579 :
8580 : /* The encoding scheme requires the number of elements to be a multiple
8581 : of the number of patterns, so that each pattern appears at least once
8582 : and so that the same number of elements appear from each pattern. */
8583 429100 : bool ok_p = multiple_p (GET_MODE_NUNITS (outermode), out_npatterns);
8584 214550 : unsigned int const_nunits;
8585 429100 : if (GET_MODE_NUNITS (outermode).is_constant (&const_nunits)
8586 214550 : && (!ok_p || out_npatterns * nelts_per_pattern > const_nunits))
8587 : {
8588 : /* Either the encoding is invalid, or applying it would give us
8589 : more elements than we need. Just encode each element directly. */
8590 : out_npatterns = const_nunits;
8591 : nelts_per_pattern = 1;
8592 : }
8593 : else if (!ok_p)
8594 : return NULL_RTX;
8595 :
8596 : /* Get enough bytes of X to form the new encoding. */
8597 214550 : unsigned int buffer_bits = out_npatterns * nelts_per_pattern * out_elt_bits;
8598 214550 : unsigned int buffer_bytes = CEIL (buffer_bits, BITS_PER_UNIT);
8599 214550 : auto_vec<target_unit, 128> buffer (buffer_bytes);
8600 214550 : if (!native_encode_rtx (innermode, x, buffer, first_byte, buffer_bytes))
8601 : return NULL_RTX;
8602 :
8603 : /* Re-encode the bytes as OUTERMODE. */
8604 214550 : return native_decode_vector_rtx (outermode, buffer, 0, out_npatterns,
8605 214550 : nelts_per_pattern);
8606 214550 : }
8607 :
8608 : /* Try to simplify a subreg of a constant by encoding the subreg region
8609 : as a sequence of target bytes and reading them back in the new mode.
8610 : Return the new value on success, otherwise return null.
8611 :
8612 : The subreg has outer mode OUTERMODE, inner mode INNERMODE, inner value X
8613 : and byte offset FIRST_BYTE. */
8614 :
8615 : static rtx
8616 11065285 : simplify_immed_subreg (fixed_size_mode outermode, rtx x,
8617 : machine_mode innermode, unsigned int first_byte)
8618 : {
8619 11065285 : unsigned int buffer_bytes = GET_MODE_SIZE (outermode);
8620 11065285 : auto_vec<target_unit, 128> buffer (buffer_bytes);
8621 :
8622 : /* Some ports misuse CCmode. */
8623 11065285 : if (GET_MODE_CLASS (outermode) == MODE_CC && CONST_INT_P (x))
8624 : return x;
8625 :
8626 : /* Paradoxical subregs read undefined values for bytes outside of the
8627 : inner value. However, we have traditionally always sign-extended
8628 : integer constants and zero-extended others. */
8629 11063279 : unsigned int inner_bytes = buffer_bytes;
8630 11063279 : if (paradoxical_subreg_p (outermode, innermode))
8631 : {
8632 1091934 : if (!GET_MODE_SIZE (innermode).is_constant (&inner_bytes))
8633 0 : return NULL_RTX;
8634 :
8635 545967 : target_unit filler = 0;
8636 545967 : if (CONST_SCALAR_INT_P (x) && wi::neg_p (rtx_mode_t (x, innermode)))
8637 67918 : filler = -1;
8638 :
8639 : /* Add any leading bytes due to big-endian layout. The number of
8640 : bytes must be constant because both modes have constant size. */
8641 545967 : unsigned int leading_bytes
8642 545967 : = -byte_lowpart_offset (outermode, innermode).to_constant ();
8643 545967 : for (unsigned int i = 0; i < leading_bytes; ++i)
8644 0 : buffer.quick_push (filler);
8645 :
8646 545967 : if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
8647 0 : return NULL_RTX;
8648 :
8649 : /* Add any trailing bytes due to little-endian layout. */
8650 7142774 : while (buffer.length () < buffer_bytes)
8651 3025420 : buffer.quick_push (filler);
8652 : }
8653 10517312 : else if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
8654 : return NULL_RTX;
8655 11063279 : rtx ret = native_decode_rtx (outermode, buffer, 0);
8656 11063279 : if (ret && FLOAT_MODE_P (outermode))
8657 : {
8658 129941 : auto_vec<target_unit, 128> buffer2 (buffer_bytes);
8659 129941 : if (!native_encode_rtx (outermode, ret, buffer2, 0, buffer_bytes))
8660 : return NULL_RTX;
8661 1430040 : for (unsigned int i = 0; i < buffer_bytes; ++i)
8662 1300134 : if (buffer[i] != buffer2[i])
8663 : return NULL_RTX;
8664 129941 : }
8665 : return ret;
8666 11065285 : }
8667 :
8668 : /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
8669 : Return 0 if no simplifications are possible. */
8670 : rtx
8671 74901677 : simplify_context::simplify_subreg (machine_mode outermode, rtx op,
8672 : machine_mode innermode, poly_uint64 byte)
8673 : {
8674 : /* Little bit of sanity checking. */
8675 74901677 : gcc_assert (innermode != VOIDmode);
8676 74901677 : gcc_assert (outermode != VOIDmode);
8677 74901677 : gcc_assert (innermode != BLKmode);
8678 74901677 : gcc_assert (outermode != BLKmode);
8679 :
8680 74901677 : gcc_assert (GET_MODE (op) == innermode
8681 : || GET_MODE (op) == VOIDmode);
8682 :
8683 149803354 : poly_uint64 outersize = GET_MODE_SIZE (outermode);
8684 74901677 : if (!multiple_p (byte, outersize))
8685 : return NULL_RTX;
8686 :
8687 149803314 : poly_uint64 innersize = GET_MODE_SIZE (innermode);
8688 74901657 : if (maybe_ge (byte, innersize))
8689 : return NULL_RTX;
8690 :
8691 74901657 : if (outermode == innermode && known_eq (byte, 0U))
8692 4583707 : return op;
8693 :
8694 70317950 : if (GET_CODE (op) == CONST_VECTOR)
8695 364304 : byte = simplify_const_vector_byte_offset (op, byte);
8696 :
8697 140635900 : if (multiple_p (byte, GET_MODE_UNIT_SIZE (innermode)))
8698 : {
8699 64287798 : rtx elt;
8700 :
8701 54950524 : if (VECTOR_MODE_P (outermode)
8702 28011822 : && GET_MODE_INNER (outermode) == GET_MODE_INNER (innermode)
8703 66340937 : && vec_duplicate_p (op, &elt))
8704 13730 : return gen_vec_duplicate (outermode, elt);
8705 :
8706 64282342 : if (outermode == GET_MODE_INNER (innermode)
8707 64282342 : && vec_duplicate_p (op, &elt))
8708 8274 : return elt;
8709 : }
8710 :
8711 70304220 : if (CONST_SCALAR_INT_P (op)
8712 59437980 : || CONST_DOUBLE_AS_FLOAT_P (op)
8713 59380635 : || CONST_FIXED_P (op)
8714 59380635 : || GET_CODE (op) == CONST_VECTOR)
8715 : {
8716 11279835 : unsigned HOST_WIDE_INT cbyte;
8717 11279835 : if (byte.is_constant (&cbyte))
8718 : {
8719 11279835 : if (GET_CODE (op) == CONST_VECTOR && VECTOR_MODE_P (outermode))
8720 : {
8721 222710 : rtx tmp = simplify_const_vector_subreg (outermode, op,
8722 : innermode, cbyte);
8723 222710 : if (tmp)
8724 11279835 : return tmp;
8725 : }
8726 :
8727 11065285 : fixed_size_mode fs_outermode;
8728 11065285 : if (is_a <fixed_size_mode> (outermode, &fs_outermode))
8729 11065285 : return simplify_immed_subreg (fs_outermode, op, innermode, cbyte);
8730 : }
8731 : }
8732 :
8733 : /* Changing mode twice with SUBREG => just change it once,
8734 : or not at all if changing back op starting mode. */
8735 59024385 : if (GET_CODE (op) == SUBREG)
8736 : {
8737 1623608 : machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
8738 3247216 : poly_uint64 innermostsize = GET_MODE_SIZE (innermostmode);
8739 1623608 : rtx newx;
8740 :
8741 : /* Make sure that the relationship between the two subregs is
8742 : known at compile time. */
8743 1623608 : if (!ordered_p (outersize, innermostsize))
8744 : return NULL_RTX;
8745 :
8746 1623608 : if (outermode == innermostmode
8747 955884 : && known_eq (byte, subreg_lowpart_offset (outermode, innermode))
8748 2579485 : && known_eq (SUBREG_BYTE (op),
8749 : subreg_lowpart_offset (innermode, innermostmode)))
8750 955877 : return SUBREG_REG (op);
8751 :
8752 : /* Work out the memory offset of the final OUTERMODE value relative
8753 : to the inner value of OP. */
8754 667731 : poly_int64 mem_offset = subreg_memory_offset (outermode,
8755 : innermode, byte);
8756 667731 : poly_int64 op_mem_offset = subreg_memory_offset (op);
8757 667731 : poly_int64 final_offset = mem_offset + op_mem_offset;
8758 :
8759 : /* See whether resulting subreg will be paradoxical. */
8760 667731 : if (!paradoxical_subreg_p (outermode, innermostmode))
8761 : {
8762 : /* Bail out in case resulting subreg would be incorrect. */
8763 1061406 : if (maybe_lt (final_offset, 0)
8764 1061399 : || maybe_ge (poly_uint64 (final_offset), innermostsize)
8765 1061399 : || !multiple_p (final_offset, outersize))
8766 : return NULL_RTX;
8767 : }
8768 : else
8769 : {
8770 137028 : poly_int64 required_offset = subreg_memory_offset (outermode,
8771 : innermostmode, 0);
8772 137028 : if (maybe_ne (final_offset, required_offset))
8773 1 : return NULL_RTX;
8774 : /* Paradoxical subregs always have byte offset 0. */
8775 137027 : final_offset = 0;
8776 : }
8777 :
8778 : /* Recurse for further possible simplifications. */
8779 667715 : newx = simplify_subreg (outermode, SUBREG_REG (op), innermostmode,
8780 667715 : final_offset);
8781 667715 : if (newx)
8782 : return newx;
8783 667304 : if (validate_subreg (outermode, innermostmode,
8784 667304 : SUBREG_REG (op), final_offset))
8785 : {
8786 611622 : newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
8787 611622 : if (SUBREG_PROMOTED_VAR_P (op)
8788 738 : && SUBREG_PROMOTED_SIGN (op) >= 0
8789 738 : && GET_MODE_CLASS (outermode) == MODE_INT
8790 734 : && known_ge (outersize, innersize)
8791 315 : && known_le (outersize, innermostsize)
8792 611632 : && subreg_lowpart_p (newx))
8793 : {
8794 10 : SUBREG_PROMOTED_VAR_P (newx) = 1;
8795 10 : SUBREG_PROMOTED_SET (newx, SUBREG_PROMOTED_GET (op));
8796 : }
8797 : return newx;
8798 : }
8799 : return NULL_RTX;
8800 : }
8801 :
8802 : /* SUBREG of a hard register => just change the register number
8803 : and/or mode. If the hard register is not valid in that mode,
8804 : suppress this simplification. If the hard register is the stack,
8805 : frame, or argument pointer, leave this as a SUBREG. */
8806 :
8807 57400777 : if (REG_P (op) && HARD_REGISTER_P (op))
8808 : {
8809 11037339 : unsigned int regno, final_regno;
8810 :
8811 11037339 : regno = REGNO (op);
8812 11037339 : final_regno = simplify_subreg_regno (regno, innermode, byte, outermode);
8813 11037339 : if (HARD_REGISTER_NUM_P (final_regno))
8814 : {
8815 11012324 : rtx x = gen_rtx_REG_offset (op, outermode, final_regno,
8816 : subreg_memory_offset (outermode,
8817 : innermode, byte));
8818 :
8819 : /* Propagate original regno. We don't have any way to specify
8820 : the offset inside original regno, so do so only for lowpart.
8821 : The information is used only by alias analysis that cannot
8822 : grog partial register anyway. */
8823 :
8824 11012324 : if (known_eq (subreg_lowpart_offset (outermode, innermode), byte))
8825 8232878 : ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op);
8826 : return x;
8827 : }
8828 : }
8829 :
8830 : /* If we have a SUBREG of a register that we are replacing and we are
8831 : replacing it with a MEM, make a new MEM and try replacing the
8832 : SUBREG with it. Don't do this if the MEM has a mode-dependent address
8833 : or if we would be widening it. */
8834 :
8835 46388453 : if (MEM_P (op)
8836 1667628 : && ! mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op))
8837 : /* Allow splitting of volatile memory references in case we don't
8838 : have instruction to move the whole thing. */
8839 1667625 : && (! MEM_VOLATILE_P (op)
8840 45542 : || ! have_insn_for (SET, innermode))
8841 : && !(STRICT_ALIGNMENT && MEM_ALIGN (op) < GET_MODE_ALIGNMENT (outermode))
8842 1622083 : && known_le (outersize, innersize)
8843 : /* You can't get the Nth element of a vector of addresses (i.e.
8844 : gather/scatter) by adding an offset to the base. */
8845 47213157 : && !VECTOR_MODE_P (GET_MODE (XEXP (op, 0))))
8846 824704 : return adjust_address_nv (op, outermode, byte);
8847 :
8848 : /* Simplify (subreg:<m> (mem:<vec_m> (reg:<vec_p> addr)) x)
8849 : to (mem:<m> (subreg:<p> (reg:<vec_p>)) y) */
8850 45563749 : if (MEM_P (op)
8851 842924 : && VECTOR_MODE_P (innermode)
8852 12935 : && VECTOR_MODE_P (GET_MODE (XEXP (op, 0)))
8853 45563749 : && GET_MODE_INNER (innermode) == outermode)
8854 : {
8855 0 : poly_uint64 index;
8856 0 : if (multiple_p (byte, GET_MODE_SIZE (outermode), &index))
8857 : {
8858 0 : rtx addr = XEXP (op, 0);
8859 0 : machine_mode addrmode = GET_MODE (addr);
8860 0 : scalar_mode addr_elt_mode = GET_MODE_INNER (addrmode);
8861 0 : poly_uint64 addr_byte = index * GET_MODE_SIZE (addr_elt_mode);
8862 :
8863 0 : rtx new_addr = simplify_gen_subreg (addr_elt_mode, addr, addrmode,
8864 : addr_byte);
8865 0 : if (new_addr)
8866 0 : return change_address_nv (op, outermode, new_addr);
8867 : }
8868 : }
8869 :
8870 : /* Handle complex or vector values represented as CONCAT or VEC_CONCAT
8871 : of two parts. */
8872 45563749 : if (GET_CODE (op) == CONCAT
8873 45563749 : || GET_CODE (op) == VEC_CONCAT)
8874 : {
8875 257809 : poly_uint64 final_offset;
8876 257809 : rtx part, res;
8877 :
8878 257809 : machine_mode part_mode = GET_MODE (XEXP (op, 0));
8879 257809 : if (part_mode == VOIDmode)
8880 21 : part_mode = GET_MODE_INNER (GET_MODE (op));
8881 515618 : poly_uint64 part_size = GET_MODE_SIZE (part_mode);
8882 257809 : if (known_lt (byte, part_size))
8883 : {
8884 256319 : part = XEXP (op, 0);
8885 256319 : final_offset = byte;
8886 : }
8887 1490 : else if (known_ge (byte, part_size))
8888 : {
8889 1490 : part = XEXP (op, 1);
8890 1490 : final_offset = byte - part_size;
8891 : }
8892 : else
8893 : return NULL_RTX;
8894 :
8895 257809 : if (maybe_gt (final_offset + outersize, part_size))
8896 : return NULL_RTX;
8897 :
8898 128858 : part_mode = GET_MODE (part);
8899 128858 : if (part_mode == VOIDmode)
8900 0 : part_mode = GET_MODE_INNER (GET_MODE (op));
8901 128858 : res = simplify_subreg (outermode, part, part_mode, final_offset);
8902 128858 : if (res)
8903 : return res;
8904 333 : if (GET_MODE (part) != VOIDmode
8905 333 : && validate_subreg (outermode, part_mode, part, final_offset))
8906 333 : return gen_rtx_SUBREG (outermode, part, final_offset);
8907 : return NULL_RTX;
8908 : }
8909 :
8910 : /* Simplify
8911 : (subreg (vec_merge (X)
8912 : (vector)
8913 : (const_int ((1 << N) | M)))
8914 : (N * sizeof (outermode)))
8915 : to
8916 : (subreg (X) (N * sizeof (outermode)))
8917 : */
8918 45305940 : unsigned int idx;
8919 90611880 : if (constant_multiple_p (byte, GET_MODE_SIZE (outermode), &idx)
8920 45305940 : && idx < HOST_BITS_PER_WIDE_INT
8921 45305940 : && GET_CODE (op) == VEC_MERGE
8922 538506 : && GET_MODE_INNER (innermode) == outermode
8923 4849 : && CONST_INT_P (XEXP (op, 2))
8924 45310216 : && (UINTVAL (XEXP (op, 2)) & (HOST_WIDE_INT_1U << idx)) != 0)
8925 4267 : return simplify_gen_subreg (outermode, XEXP (op, 0), innermode, byte);
8926 :
8927 : /* A SUBREG resulting from a zero extension may fold to zero if
8928 : it extracts higher bits that the ZERO_EXTEND's source bits. */
8929 45301673 : if (GET_CODE (op) == ZERO_EXTEND && SCALAR_INT_MODE_P (innermode))
8930 : {
8931 233819 : poly_uint64 bitpos = subreg_lsb_1 (outermode, innermode, byte);
8932 233819 : if (known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (XEXP (op, 0)))))
8933 55623 : return CONST0_RTX (outermode);
8934 : }
8935 :
8936 : /* Optimize SUBREGS of scalar integral ASHIFT by a valid constant. */
8937 45246050 : if (GET_CODE (op) == ASHIFT
8938 1076174 : && SCALAR_INT_MODE_P (innermode)
8939 993257 : && CONST_INT_P (XEXP (op, 1))
8940 911458 : && INTVAL (XEXP (op, 1)) > 0
8941 47233682 : && known_gt (GET_MODE_BITSIZE (innermode), INTVAL (XEXP (op, 1))))
8942 : {
8943 911458 : HOST_WIDE_INT val = INTVAL (XEXP (op, 1));
8944 : /* A lowpart SUBREG of a ASHIFT by a constant may fold to zero. */
8945 911458 : if (known_eq (subreg_lowpart_offset (outermode, innermode), byte)
8946 1785410 : && known_le (GET_MODE_BITSIZE (outermode), val))
8947 194118 : return CONST0_RTX (outermode);
8948 : /* Optimize the highpart SUBREG of a suitable ASHIFT (ZERO_EXTEND). */
8949 751630 : if (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
8950 34952 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == outermode
8951 69546 : && known_eq (GET_MODE_BITSIZE (outermode), val)
8952 68580 : && known_eq (GET_MODE_BITSIZE (innermode), 2 * val)
8953 786582 : && known_eq (subreg_highpart_offset (outermode, innermode), byte))
8954 34290 : return XEXP (XEXP (op, 0), 0);
8955 : }
8956 :
8957 46662975 : auto distribute_subreg = [&](rtx op)
8958 : {
8959 1611043 : return simplify_subreg (outermode, op, innermode, byte);
8960 45051932 : };
8961 :
8962 : /* Try distributing the subreg through logic operations, if that
8963 : leads to all subexpressions being simplified. For example,
8964 : distributing the outer subreg in:
8965 :
8966 : (subreg:SI (not:QI (subreg:QI (reg:SI X) <lowpart>)) 0)
8967 :
8968 : gives:
8969 :
8970 : (not:SI (reg:SI X))
8971 :
8972 : This should be a win if the outermode is word_mode, since logical
8973 : operations on word_mode should (a) be no more expensive than logical
8974 : operations on subword modes and (b) are likely to be cheaper than
8975 : logical operations on multiword modes.
8976 :
8977 : Otherwise, handle the case where the subreg is non-narrowing and does
8978 : not change the number of words. The non-narrowing condition ensures
8979 : that we don't convert word_mode operations to subword operations. */
8980 45051932 : scalar_int_mode int_outermode, int_innermode;
8981 45051932 : if (is_a <scalar_int_mode> (outermode, &int_outermode)
8982 37959789 : && is_a <scalar_int_mode> (innermode, &int_innermode)
8983 81496593 : && (outermode == word_mode
8984 22213945 : || ((GET_MODE_PRECISION (int_outermode)
8985 22213945 : >= GET_MODE_PRECISION (int_innermode))
8986 4372186 : && (CEIL (GET_MODE_SIZE (int_outermode), UNITS_PER_WORD)
8987 4302496 : <= CEIL (GET_MODE_SIZE (int_innermode), UNITS_PER_WORD)))))
8988 18472672 : switch (GET_CODE (op))
8989 : {
8990 34938 : case NOT:
8991 34938 : if (rtx op0 = distribute_subreg (XEXP (op, 0)))
8992 1893 : return simplify_gen_unary (GET_CODE (op), outermode, op0, outermode);
8993 : break;
8994 :
8995 469760 : case AND:
8996 469760 : case IOR:
8997 469760 : case XOR:
8998 469760 : if (rtx op0 = distribute_subreg (XEXP (op, 0)))
8999 207181 : if (rtx op1 = distribute_subreg (XEXP (op, 1)))
9000 202554 : return simplify_gen_binary (GET_CODE (op), outermode, op0, op1);
9001 : break;
9002 :
9003 : default:
9004 : break;
9005 : }
9006 :
9007 44847485 : if (is_a <scalar_int_mode> (outermode)
9008 37755342 : && is_a <scalar_int_mode> (innermode)
9009 82602827 : && known_eq (byte,
9010 : subreg_lowpart_offset (as_a <scalar_int_mode> (outermode),
9011 : as_a <scalar_int_mode> (innermode))))
9012 : {
9013 33976693 : scalar_int_mode int_outermode = as_a <scalar_int_mode> (outermode);
9014 33976693 : scalar_int_mode int_innermode = as_a <scalar_int_mode> (innermode);
9015 :
9016 : /* Handle polynomial integers. The upper bits of a paradoxical
9017 : subreg are undefined, so this is safe regardless of whether
9018 : we're truncating or extending. */
9019 33976693 : if (CONST_POLY_INT_P (op))
9020 : {
9021 : poly_wide_int val
9022 : = poly_wide_int::from (const_poly_int_value (op),
9023 : GET_MODE_PRECISION (int_outermode),
9024 : SIGNED);
9025 : return immed_wide_int_const (val, int_outermode);
9026 : }
9027 :
9028 33976693 : if (GET_MODE_PRECISION (int_outermode)
9029 33976693 : < GET_MODE_PRECISION (int_innermode))
9030 : {
9031 21390711 : rtx tem = simplify_truncation (int_outermode, op, int_innermode);
9032 21390711 : if (tem)
9033 : return tem;
9034 : }
9035 : }
9036 :
9037 : /* If the outer mode is not integral, try taking a subreg with the equivalent
9038 : integer outer mode and then bitcasting the result.
9039 : Other simplifications rely on integer to integer subregs and we'd
9040 : potentially miss out on optimizations otherwise. */
9041 86095932 : if (known_gt (GET_MODE_SIZE (innermode),
9042 : GET_MODE_SIZE (outermode))
9043 23208359 : && SCALAR_INT_MODE_P (innermode)
9044 21931836 : && !SCALAR_INT_MODE_P (outermode)
9045 66410571 : && int_mode_for_size (GET_MODE_BITSIZE (outermode),
9046 77123 : 0).exists (&int_outermode))
9047 : {
9048 77123 : rtx tem = simplify_subreg (int_outermode, op, innermode, byte);
9049 77123 : if (tem)
9050 1974 : return lowpart_subreg (outermode, tem, int_outermode);
9051 : }
9052 :
9053 : /* If OP is a vector comparison and the subreg is not changing the
9054 : number of elements or the size of the elements, change the result
9055 : of the comparison to the new mode. */
9056 43045992 : if (COMPARISON_P (op)
9057 305477 : && VECTOR_MODE_P (outermode)
9058 216696 : && VECTOR_MODE_P (innermode)
9059 650064 : && known_eq (GET_MODE_NUNITS (outermode), GET_MODE_NUNITS (innermode))
9060 43447206 : && known_eq (GET_MODE_UNIT_SIZE (outermode),
9061 : GET_MODE_UNIT_SIZE (innermode)))
9062 133394 : return simplify_gen_relational (GET_CODE (op), outermode, innermode,
9063 133394 : XEXP (op, 0), XEXP (op, 1));
9064 :
9065 : /* Distribute non-paradoxical subregs through logic ops in cases where
9066 : one term disappears.
9067 :
9068 : (subreg:M1 (and:M2 X C1)) -> (subreg:M1 X)
9069 : (subreg:M1 (ior:M2 X C1)) -> (subreg:M1 C1)
9070 : (subreg:M1 (xor:M2 X C1)) -> (subreg:M1 (not:M2 X))
9071 :
9072 : if M2 is no smaller than M1 and (subreg:M1 C1) is all-ones.
9073 :
9074 : (subreg:M1 (and:M2 X C2)) -> (subreg:M1 C2)
9075 : (subreg:M1 (ior/xor:M2 X C2)) -> (subreg:M1 X)
9076 :
9077 : if M2 is no smaller than M1 and (subreg:M1 C2) is zero. */
9078 42912598 : if (known_ge (innersize, outersize)
9079 29744590 : && GET_MODE_CLASS (outermode) == GET_MODE_CLASS (innermode)
9080 27411352 : && (GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR)
9081 44627722 : && CONSTANT_P (XEXP (op, 1)))
9082 : {
9083 891884 : rtx op1_subreg = distribute_subreg (XEXP (op, 1));
9084 891884 : if (op1_subreg == CONSTM1_RTX (outermode))
9085 : {
9086 121609 : if (GET_CODE (op) == IOR)
9087 : return op1_subreg;
9088 121375 : rtx op0 = XEXP (op, 0);
9089 121375 : if (GET_CODE (op) == XOR)
9090 889 : op0 = simplify_gen_unary (NOT, innermode, op0, innermode);
9091 121375 : return simplify_gen_subreg (outermode, op0, innermode, byte);
9092 : }
9093 :
9094 770275 : if (op1_subreg == CONST0_RTX (outermode))
9095 12435 : return (GET_CODE (op) == AND
9096 12435 : ? op1_subreg
9097 7280 : : distribute_subreg (XEXP (op, 0)));
9098 : }
9099 :
9100 : return NULL_RTX;
9101 : }
9102 :
9103 : /* Make a SUBREG operation or equivalent if it folds. */
9104 :
9105 : rtx
9106 46260194 : simplify_context::simplify_gen_subreg (machine_mode outermode, rtx op,
9107 : machine_mode innermode,
9108 : poly_uint64 byte)
9109 : {
9110 46260194 : rtx newx;
9111 :
9112 46260194 : newx = simplify_subreg (outermode, op, innermode, byte);
9113 46260194 : if (newx)
9114 : return newx;
9115 :
9116 21864275 : if (GET_CODE (op) == SUBREG
9117 21864275 : || GET_CODE (op) == CONCAT
9118 21830490 : || CONST_SCALAR_INT_P (op)
9119 21830464 : || CONST_DOUBLE_AS_FLOAT_P (op)
9120 21830464 : || CONST_FIXED_P (op)
9121 21830464 : || GET_CODE (op) == CONST_VECTOR)
9122 : return NULL_RTX;
9123 :
9124 21830454 : if (validate_subreg (outermode, innermode, op, byte))
9125 21798300 : return gen_rtx_SUBREG (outermode, op, byte);
9126 :
9127 : return NULL_RTX;
9128 : }
9129 :
9130 : /* Generates a subreg to get the least significant part of EXPR (in mode
9131 : INNER_MODE) to OUTER_MODE. */
9132 :
9133 : rtx
9134 34030853 : simplify_context::lowpart_subreg (machine_mode outer_mode, rtx expr,
9135 : machine_mode inner_mode)
9136 : {
9137 34030853 : return simplify_gen_subreg (outer_mode, expr, inner_mode,
9138 34030853 : subreg_lowpart_offset (outer_mode, inner_mode));
9139 : }
9140 :
9141 : /* Generate RTX to select element at INDEX out of vector OP. */
9142 :
9143 : rtx
9144 678362 : simplify_context::simplify_gen_vec_select (rtx op, unsigned int index)
9145 : {
9146 678362 : gcc_assert (VECTOR_MODE_P (GET_MODE (op)));
9147 :
9148 678362 : scalar_mode imode = GET_MODE_INNER (GET_MODE (op));
9149 :
9150 1356724 : if (known_eq (index * GET_MODE_SIZE (imode),
9151 : subreg_lowpart_offset (imode, GET_MODE (op))))
9152 : {
9153 678212 : rtx res = lowpart_subreg (imode, op, GET_MODE (op));
9154 678212 : if (res)
9155 : return res;
9156 : }
9157 :
9158 671 : rtx tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, GEN_INT (index)));
9159 671 : return gen_rtx_VEC_SELECT (imode, op, tmp);
9160 : }
9161 :
9162 :
9163 : /* Simplify X, an rtx expression.
9164 :
9165 : Return the simplified expression or NULL if no simplifications
9166 : were possible.
9167 :
9168 : This is the preferred entry point into the simplification routines;
9169 : however, we still allow passes to call the more specific routines.
9170 :
9171 : Right now GCC has three (yes, three) major bodies of RTL simplification
9172 : code that need to be unified.
9173 :
9174 : 1. fold_rtx in cse.cc. This code uses various CSE specific
9175 : information to aid in RTL simplification.
9176 :
9177 : 2. simplify_rtx in combine.cc. Similar to fold_rtx, except that
9178 : it uses combine specific information to aid in RTL
9179 : simplification.
9180 :
9181 : 3. The routines in this file.
9182 :
9183 :
9184 : Long term we want to only have one body of simplification code; to
9185 : get to that state I recommend the following steps:
9186 :
9187 : 1. Pour over fold_rtx & simplify_rtx and move any simplifications
9188 : which are not pass dependent state into these routines.
9189 :
9190 : 2. As code is moved by #1, change fold_rtx & simplify_rtx to
9191 : use this routine whenever possible.
9192 :
9193 : 3. Allow for pass dependent state to be provided to these
9194 : routines and add simplifications based on the pass dependent
9195 : state. Remove code from cse.cc & combine.cc that becomes
9196 : redundant/dead.
9197 :
9198 : It will take time, but ultimately the compiler will be easier to
9199 : maintain and improve. It's totally silly that when we add a
9200 : simplification that it needs to be added to 4 places (3 for RTL
9201 : simplification and 1 for tree simplification. */
9202 :
9203 : rtx
9204 48079032 : simplify_rtx (const_rtx x)
9205 : {
9206 48079032 : const enum rtx_code code = GET_CODE (x);
9207 48079032 : const machine_mode mode = GET_MODE (x);
9208 :
9209 48079032 : switch (GET_RTX_CLASS (code))
9210 : {
9211 782621 : case RTX_UNARY:
9212 1565242 : return simplify_unary_operation (code, mode,
9213 782621 : XEXP (x, 0), GET_MODE (XEXP (x, 0)));
9214 27536857 : case RTX_COMM_ARITH:
9215 27536857 : if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
9216 432781 : return simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
9217 :
9218 : /* Fall through. */
9219 :
9220 33837349 : case RTX_BIN_ARITH:
9221 33837349 : return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
9222 :
9223 84255 : case RTX_TERNARY:
9224 84255 : case RTX_BITFIELD_OPS:
9225 84255 : return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
9226 84255 : XEXP (x, 0), XEXP (x, 1),
9227 84255 : XEXP (x, 2));
9228 :
9229 207577 : case RTX_COMPARE:
9230 207577 : case RTX_COMM_COMPARE:
9231 207577 : return simplify_relational_operation (code, mode,
9232 207577 : ((GET_MODE (XEXP (x, 0))
9233 : != VOIDmode)
9234 : ? GET_MODE (XEXP (x, 0))
9235 354 : : GET_MODE (XEXP (x, 1))),
9236 207577 : XEXP (x, 0),
9237 415154 : XEXP (x, 1));
9238 :
9239 226600 : case RTX_EXTRA:
9240 226600 : if (code == SUBREG)
9241 2135 : return simplify_subreg (mode, SUBREG_REG (x),
9242 2135 : GET_MODE (SUBREG_REG (x)),
9243 2135 : SUBREG_BYTE (x));
9244 : break;
9245 :
9246 6727634 : case RTX_OBJ:
9247 6727634 : if (code == LO_SUM)
9248 : {
9249 : /* Convert (lo_sum (high FOO) FOO) to FOO. */
9250 0 : if (GET_CODE (XEXP (x, 0)) == HIGH
9251 0 : && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
9252 0 : return XEXP (x, 1);
9253 : }
9254 : break;
9255 :
9256 : default:
9257 : break;
9258 : }
9259 : return NULL;
9260 : }
9261 :
9262 : #if CHECKING_P
9263 :
9264 : namespace selftest {
9265 :
9266 : /* Make a unique pseudo REG of mode MODE for use by selftests. */
9267 :
9268 : static rtx
9269 2672 : make_test_reg (machine_mode mode)
9270 : {
9271 2672 : static int test_reg_num = LAST_VIRTUAL_REGISTER + 1;
9272 :
9273 2672 : return gen_rtx_REG (mode, test_reg_num++);
9274 : }
9275 :
9276 : static void
9277 40 : test_scalar_int_ops (machine_mode mode)
9278 : {
9279 40 : rtx op0 = make_test_reg (mode);
9280 40 : rtx op1 = make_test_reg (mode);
9281 40 : rtx six = GEN_INT (6);
9282 :
9283 40 : rtx neg_op0 = simplify_gen_unary (NEG, mode, op0, mode);
9284 40 : rtx not_op0 = simplify_gen_unary (NOT, mode, op0, mode);
9285 40 : rtx bswap_op0 = simplify_gen_unary (BSWAP, mode, op0, mode);
9286 :
9287 40 : rtx and_op0_op1 = simplify_gen_binary (AND, mode, op0, op1);
9288 40 : rtx ior_op0_op1 = simplify_gen_binary (IOR, mode, op0, op1);
9289 40 : rtx xor_op0_op1 = simplify_gen_binary (XOR, mode, op0, op1);
9290 :
9291 40 : rtx and_op0_6 = simplify_gen_binary (AND, mode, op0, six);
9292 40 : rtx and_op1_6 = simplify_gen_binary (AND, mode, op1, six);
9293 :
9294 : /* Test some binary identities. */
9295 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, op0, const0_rtx));
9296 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, const0_rtx, op0));
9297 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MINUS, mode, op0, const0_rtx));
9298 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, op0, const1_rtx));
9299 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, const1_rtx, op0));
9300 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (DIV, mode, op0, const1_rtx));
9301 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, constm1_rtx));
9302 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, constm1_rtx, op0));
9303 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, const0_rtx));
9304 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, const0_rtx, op0));
9305 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, op0, const0_rtx));
9306 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, const0_rtx, op0));
9307 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFT, mode, op0, const0_rtx));
9308 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATE, mode, op0, const0_rtx));
9309 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFTRT, mode, op0, const0_rtx));
9310 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (LSHIFTRT, mode, op0, const0_rtx));
9311 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATERT, mode, op0, const0_rtx));
9312 :
9313 : /* Test some self-inverse operations. */
9314 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (NEG, mode, neg_op0, mode));
9315 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (NOT, mode, not_op0, mode));
9316 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (BSWAP, mode, bswap_op0, mode));
9317 :
9318 : /* Test some reflexive operations. */
9319 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, op0));
9320 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, op0));
9321 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (SMIN, mode, op0, op0));
9322 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (SMAX, mode, op0, op0));
9323 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (UMIN, mode, op0, op0));
9324 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (UMAX, mode, op0, op0));
9325 :
9326 40 : ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (MINUS, mode, op0, op0));
9327 40 : ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (XOR, mode, op0, op0));
9328 :
9329 : /* Test simplify_distributive_operation. */
9330 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, xor_op0_op1, six),
9331 : simplify_gen_binary (XOR, mode, and_op0_6, and_op1_6));
9332 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, ior_op0_op1, six),
9333 : simplify_gen_binary (IOR, mode, and_op0_6, and_op1_6));
9334 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, and_op0_op1, six),
9335 : simplify_gen_binary (AND, mode, and_op0_6, and_op1_6));
9336 :
9337 : /* Test useless extensions are eliminated. */
9338 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (TRUNCATE, mode, op0, mode));
9339 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (ZERO_EXTEND, mode, op0, mode));
9340 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (SIGN_EXTEND, mode, op0, mode));
9341 40 : ASSERT_RTX_EQ (op0, lowpart_subreg (mode, op0, mode));
9342 40 : }
9343 :
9344 : /* Verify some simplifications of integer extension/truncation.
9345 : Machine mode BMODE is the guaranteed wider than SMODE. */
9346 :
9347 : static void
9348 24 : test_scalar_int_ext_ops (machine_mode bmode, machine_mode smode)
9349 : {
9350 24 : rtx sreg = make_test_reg (smode);
9351 :
9352 : /* Check truncation of extension. */
9353 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9354 : simplify_gen_unary (ZERO_EXTEND, bmode,
9355 : sreg, smode),
9356 : bmode),
9357 : sreg);
9358 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9359 : simplify_gen_unary (SIGN_EXTEND, bmode,
9360 : sreg, smode),
9361 : bmode),
9362 : sreg);
9363 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9364 : lowpart_subreg (bmode, sreg, smode),
9365 : bmode),
9366 : sreg);
9367 :
9368 : /* Test extensions, followed by logic ops, followed by truncations. */
9369 24 : rtx bsubreg = lowpart_subreg (bmode, sreg, smode);
9370 24 : rtx smask = gen_int_mode (GET_MODE_MASK (smode), bmode);
9371 24 : rtx inv_smask = gen_int_mode (~GET_MODE_MASK (smode), bmode);
9372 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9373 : simplify_gen_binary (AND, bmode,
9374 : bsubreg, smask),
9375 : bmode),
9376 : sreg);
9377 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9378 : simplify_gen_binary (AND, bmode,
9379 : bsubreg, inv_smask),
9380 : bmode),
9381 : const0_rtx);
9382 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9383 : simplify_gen_binary (IOR, bmode,
9384 : bsubreg, smask),
9385 : bmode),
9386 : constm1_rtx);
9387 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9388 : simplify_gen_binary (IOR, bmode,
9389 : bsubreg, inv_smask),
9390 : bmode),
9391 : sreg);
9392 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9393 : simplify_gen_binary (XOR, bmode,
9394 : bsubreg, smask),
9395 : bmode),
9396 : lowpart_subreg (smode,
9397 : gen_rtx_NOT (bmode, bsubreg),
9398 : bmode));
9399 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
9400 : simplify_gen_binary (XOR, bmode,
9401 : bsubreg, inv_smask),
9402 : bmode),
9403 : sreg);
9404 :
9405 24 : if (known_le (GET_MODE_PRECISION (bmode), BITS_PER_WORD))
9406 : {
9407 24 : rtx breg1 = make_test_reg (bmode);
9408 24 : rtx breg2 = make_test_reg (bmode);
9409 24 : rtx ssubreg1 = lowpart_subreg (smode, breg1, bmode);
9410 24 : rtx ssubreg2 = lowpart_subreg (smode, breg2, bmode);
9411 24 : rtx not_1 = simplify_gen_unary (NOT, smode, ssubreg1, smode);
9412 24 : rtx and_12 = simplify_gen_binary (AND, smode, ssubreg1, ssubreg2);
9413 24 : rtx ior_12 = simplify_gen_binary (IOR, smode, ssubreg1, ssubreg2);
9414 24 : rtx xor_12 = simplify_gen_binary (XOR, smode, ssubreg1, ssubreg2);
9415 24 : rtx and_n12 = simplify_gen_binary (AND, smode, not_1, ssubreg2);
9416 24 : rtx ior_n12 = simplify_gen_binary (IOR, smode, not_1, ssubreg2);
9417 24 : rtx xor_12_c = simplify_gen_binary (XOR, smode, xor_12, const1_rtx);
9418 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, not_1, smode),
9419 : gen_rtx_NOT (bmode, breg1));
9420 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, and_12, smode),
9421 : gen_rtx_AND (bmode, breg1, breg2));
9422 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, ior_12, smode),
9423 : gen_rtx_IOR (bmode, breg1, breg2));
9424 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, xor_12, smode),
9425 : gen_rtx_XOR (bmode, breg1, breg2));
9426 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, and_n12, smode),
9427 : gen_rtx_AND (bmode, gen_rtx_NOT (bmode, breg1), breg2));
9428 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, ior_n12, smode),
9429 : gen_rtx_IOR (bmode, gen_rtx_NOT (bmode, breg1), breg2));
9430 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, xor_12_c, smode),
9431 : gen_rtx_XOR (bmode,
9432 : gen_rtx_XOR (bmode, breg1, breg2),
9433 : const1_rtx));
9434 : }
9435 24 : }
9436 :
9437 : /* Verify more simplifications of integer extension/truncation.
9438 : BMODE is wider than MMODE which is wider than SMODE. */
9439 :
9440 : static void
9441 16 : test_scalar_int_ext_ops2 (machine_mode bmode, machine_mode mmode,
9442 : machine_mode smode)
9443 : {
9444 16 : rtx breg = make_test_reg (bmode);
9445 16 : rtx mreg = make_test_reg (mmode);
9446 16 : rtx sreg = make_test_reg (smode);
9447 :
9448 : /* Check truncate of truncate. */
9449 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9450 : simplify_gen_unary (TRUNCATE, mmode,
9451 : breg, bmode),
9452 : mmode),
9453 : simplify_gen_unary (TRUNCATE, smode, breg, bmode));
9454 :
9455 : /* Check extension of extension. */
9456 16 : ASSERT_RTX_EQ (simplify_gen_unary (ZERO_EXTEND, bmode,
9457 : simplify_gen_unary (ZERO_EXTEND, mmode,
9458 : sreg, smode),
9459 : mmode),
9460 : simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
9461 16 : ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
9462 : simplify_gen_unary (SIGN_EXTEND, mmode,
9463 : sreg, smode),
9464 : mmode),
9465 : simplify_gen_unary (SIGN_EXTEND, bmode, sreg, smode));
9466 16 : ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
9467 : simplify_gen_unary (ZERO_EXTEND, mmode,
9468 : sreg, smode),
9469 : mmode),
9470 : simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
9471 :
9472 : /* Check truncation of extension. */
9473 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9474 : simplify_gen_unary (ZERO_EXTEND, bmode,
9475 : mreg, mmode),
9476 : bmode),
9477 : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
9478 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9479 : simplify_gen_unary (SIGN_EXTEND, bmode,
9480 : mreg, mmode),
9481 : bmode),
9482 : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
9483 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
9484 : lowpart_subreg (bmode, mreg, mmode),
9485 : bmode),
9486 : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
9487 16 : }
9488 :
9489 : /* Test comparisons of comparisons, with the inner comparisons being
9490 : between values of mode MODE2 and producing results of mode MODE1,
9491 : and with the outer comparisons producing results of mode MODE0. */
9492 :
9493 : static void
9494 4 : test_comparisons (machine_mode mode0, machine_mode mode1, machine_mode mode2)
9495 : {
9496 4 : rtx reg0 = make_test_reg (mode2);
9497 4 : rtx reg1 = make_test_reg (mode2);
9498 :
9499 4 : static const rtx_code codes[] = {
9500 : EQ, NE, LT, LTU, LE, LEU, GE, GEU, GT, GTU
9501 : };
9502 4 : constexpr auto num_codes = ARRAY_SIZE (codes);
9503 4 : rtx cmps[num_codes];
9504 4 : rtx vals[] = { constm1_rtx, const0_rtx, const1_rtx };
9505 :
9506 44 : for (unsigned int i = 0; i < num_codes; ++i)
9507 40 : cmps[i] = gen_rtx_fmt_ee (codes[i], mode1, reg0, reg1);
9508 :
9509 44 : for (auto code : codes)
9510 440 : for (unsigned int i0 = 0; i0 < num_codes; ++i0)
9511 4400 : for (unsigned int i1 = 0; i1 < num_codes; ++i1)
9512 : {
9513 4000 : rtx cmp_res = simplify_relational_operation (code, mode0, mode1,
9514 : cmps[i0], cmps[i1]);
9515 4000 : if (i0 >= 2 && i1 >= 2 && (i0 ^ i1) & 1)
9516 1280 : ASSERT_TRUE (cmp_res == NULL_RTX);
9517 : else
9518 : {
9519 2720 : ASSERT_TRUE (cmp_res != NULL_RTX
9520 : && (CONSTANT_P (cmp_res)
9521 : || (COMPARISON_P (cmp_res)
9522 : && GET_MODE (cmp_res) == mode0
9523 : && REG_P (XEXP (cmp_res, 0))
9524 : && REG_P (XEXP (cmp_res, 1)))));
9525 10880 : for (rtx reg0_val : vals)
9526 32640 : for (rtx reg1_val : vals)
9527 : {
9528 24480 : rtx val0 = simplify_const_relational_operation
9529 24480 : (codes[i0], mode1, reg0_val, reg1_val);
9530 24480 : rtx val1 = simplify_const_relational_operation
9531 24480 : (codes[i1], mode1, reg0_val, reg1_val);
9532 24480 : rtx val = simplify_const_relational_operation
9533 24480 : (code, mode0, val0, val1);
9534 24480 : rtx folded = cmp_res;
9535 24480 : if (COMPARISON_P (cmp_res))
9536 16704 : folded = simplify_const_relational_operation
9537 16704 : (GET_CODE (cmp_res), mode0,
9538 16704 : XEXP (cmp_res, 0) == reg0 ? reg0_val : reg1_val,
9539 16704 : XEXP (cmp_res, 1) == reg0 ? reg0_val : reg1_val);
9540 24480 : ASSERT_RTX_EQ (val, folded);
9541 : }
9542 : }
9543 : }
9544 4 : }
9545 :
9546 :
9547 : /* Verify some simplifications involving scalar expressions. */
9548 :
9549 : static void
9550 4 : test_scalar_ops ()
9551 : {
9552 500 : for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
9553 : {
9554 496 : machine_mode mode = (machine_mode) i;
9555 496 : if (SCALAR_INT_MODE_P (mode) && mode != BImode)
9556 40 : test_scalar_int_ops (mode);
9557 : }
9558 :
9559 4 : test_scalar_int_ext_ops (HImode, QImode);
9560 4 : test_scalar_int_ext_ops (SImode, QImode);
9561 4 : test_scalar_int_ext_ops (SImode, HImode);
9562 4 : test_scalar_int_ext_ops (DImode, QImode);
9563 4 : test_scalar_int_ext_ops (DImode, HImode);
9564 4 : test_scalar_int_ext_ops (DImode, SImode);
9565 :
9566 4 : test_scalar_int_ext_ops2 (SImode, HImode, QImode);
9567 4 : test_scalar_int_ext_ops2 (DImode, HImode, QImode);
9568 4 : test_scalar_int_ext_ops2 (DImode, SImode, QImode);
9569 4 : test_scalar_int_ext_ops2 (DImode, SImode, HImode);
9570 :
9571 4 : test_comparisons (QImode, HImode, SImode);
9572 4 : }
9573 :
9574 : /* Test vector simplifications involving VEC_DUPLICATE in which the
9575 : operands and result have vector mode MODE. SCALAR_REG is a pseudo
9576 : register that holds one element of MODE. */
9577 :
9578 : static void
9579 224 : test_vector_ops_duplicate (machine_mode mode, rtx scalar_reg)
9580 : {
9581 224 : scalar_mode inner_mode = GET_MODE_INNER (mode);
9582 224 : rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
9583 448 : poly_uint64 nunits = GET_MODE_NUNITS (mode);
9584 224 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
9585 : {
9586 : /* Test some simple unary cases with VEC_DUPLICATE arguments. */
9587 124 : rtx not_scalar_reg = gen_rtx_NOT (inner_mode, scalar_reg);
9588 124 : rtx duplicate_not = gen_rtx_VEC_DUPLICATE (mode, not_scalar_reg);
9589 124 : ASSERT_RTX_EQ (duplicate,
9590 : simplify_unary_operation (NOT, mode,
9591 : duplicate_not, mode));
9592 :
9593 124 : rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
9594 124 : rtx duplicate_neg = gen_rtx_VEC_DUPLICATE (mode, neg_scalar_reg);
9595 124 : ASSERT_RTX_EQ (duplicate,
9596 : simplify_unary_operation (NEG, mode,
9597 : duplicate_neg, mode));
9598 :
9599 : /* Test some simple binary cases with VEC_DUPLICATE arguments. */
9600 124 : ASSERT_RTX_EQ (duplicate,
9601 : simplify_binary_operation (PLUS, mode, duplicate,
9602 : CONST0_RTX (mode)));
9603 :
9604 124 : ASSERT_RTX_EQ (duplicate,
9605 : simplify_binary_operation (MINUS, mode, duplicate,
9606 : CONST0_RTX (mode)));
9607 :
9608 124 : ASSERT_RTX_PTR_EQ (CONST0_RTX (mode),
9609 : simplify_binary_operation (MINUS, mode, duplicate,
9610 : duplicate));
9611 : }
9612 :
9613 : /* Test a scalar VEC_SELECT of a VEC_DUPLICATE. */
9614 224 : rtx zero_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const0_rtx));
9615 224 : ASSERT_RTX_PTR_EQ (scalar_reg,
9616 : simplify_binary_operation (VEC_SELECT, inner_mode,
9617 : duplicate, zero_par));
9618 :
9619 224 : unsigned HOST_WIDE_INT const_nunits;
9620 224 : if (nunits.is_constant (&const_nunits))
9621 : {
9622 : /* And again with the final element. */
9623 224 : rtx last_index = gen_int_mode (const_nunits - 1, word_mode);
9624 224 : rtx last_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, last_index));
9625 224 : ASSERT_RTX_PTR_EQ (scalar_reg,
9626 : simplify_binary_operation (VEC_SELECT, inner_mode,
9627 : duplicate, last_par));
9628 :
9629 : /* Test a scalar subreg of a VEC_MERGE of a VEC_DUPLICATE. */
9630 : /* Skip this test for vectors of booleans, because offset is in bytes,
9631 : while vec_merge indices are in elements (usually bits). */
9632 224 : if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
9633 : {
9634 224 : rtx vector_reg = make_test_reg (mode);
9635 3732 : for (unsigned HOST_WIDE_INT i = 0; i < const_nunits; i++)
9636 : {
9637 3288 : if (i >= HOST_BITS_PER_WIDE_INT)
9638 : break;
9639 3284 : rtx mask = GEN_INT ((HOST_WIDE_INT_1U << i) | (i + 1));
9640 3284 : rtx vm = gen_rtx_VEC_MERGE (mode, duplicate, vector_reg, mask);
9641 6568 : poly_uint64 offset = i * GET_MODE_SIZE (inner_mode);
9642 :
9643 3284 : ASSERT_RTX_EQ (scalar_reg,
9644 : simplify_gen_subreg (inner_mode, vm,
9645 : mode, offset));
9646 : }
9647 : }
9648 : }
9649 :
9650 : /* Test a scalar subreg of a VEC_DUPLICATE. */
9651 224 : poly_uint64 offset = subreg_lowpart_offset (inner_mode, mode);
9652 224 : ASSERT_RTX_EQ (scalar_reg,
9653 : simplify_gen_subreg (inner_mode, duplicate,
9654 : mode, offset));
9655 :
9656 224 : machine_mode narrower_mode;
9657 224 : if (maybe_ne (nunits, 2U)
9658 184 : && multiple_p (nunits, 2)
9659 396 : && mode_for_vector (inner_mode, 2).exists (&narrower_mode)
9660 396 : && VECTOR_MODE_P (narrower_mode))
9661 : {
9662 : /* Test VEC_DUPLICATE of a vector. */
9663 172 : rtx_vector_builder nbuilder (narrower_mode, 2, 1);
9664 172 : nbuilder.quick_push (const0_rtx);
9665 172 : nbuilder.quick_push (const1_rtx);
9666 172 : rtx_vector_builder builder (mode, 2, 1);
9667 172 : builder.quick_push (const0_rtx);
9668 172 : builder.quick_push (const1_rtx);
9669 172 : ASSERT_RTX_EQ (builder.build (),
9670 : simplify_unary_operation (VEC_DUPLICATE, mode,
9671 : nbuilder.build (),
9672 : narrower_mode));
9673 :
9674 : /* Test VEC_SELECT of a vector. */
9675 172 : rtx vec_par
9676 172 : = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, const1_rtx, const0_rtx));
9677 172 : rtx narrower_duplicate
9678 172 : = gen_rtx_VEC_DUPLICATE (narrower_mode, scalar_reg);
9679 172 : ASSERT_RTX_EQ (narrower_duplicate,
9680 : simplify_binary_operation (VEC_SELECT, narrower_mode,
9681 : duplicate, vec_par));
9682 :
9683 : /* Test a vector subreg of a VEC_DUPLICATE. */
9684 172 : poly_uint64 offset = subreg_lowpart_offset (narrower_mode, mode);
9685 172 : ASSERT_RTX_EQ (narrower_duplicate,
9686 : simplify_gen_subreg (narrower_mode, duplicate,
9687 : mode, offset));
9688 172 : }
9689 224 : }
9690 :
9691 : /* Test vector simplifications involving VEC_SERIES in which the
9692 : operands and result have vector mode MODE. SCALAR_REG is a pseudo
9693 : register that holds one element of MODE. */
9694 :
9695 : static void
9696 92 : test_vector_ops_series (machine_mode mode, rtx scalar_reg)
9697 : {
9698 : /* Test unary cases with VEC_SERIES arguments. */
9699 92 : scalar_mode inner_mode = GET_MODE_INNER (mode);
9700 92 : rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
9701 92 : rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
9702 92 : rtx series_0_r = gen_rtx_VEC_SERIES (mode, const0_rtx, scalar_reg);
9703 92 : rtx series_0_nr = gen_rtx_VEC_SERIES (mode, const0_rtx, neg_scalar_reg);
9704 92 : rtx series_nr_1 = gen_rtx_VEC_SERIES (mode, neg_scalar_reg, const1_rtx);
9705 92 : rtx series_r_m1 = gen_rtx_VEC_SERIES (mode, scalar_reg, constm1_rtx);
9706 92 : rtx series_r_r = gen_rtx_VEC_SERIES (mode, scalar_reg, scalar_reg);
9707 92 : rtx series_nr_nr = gen_rtx_VEC_SERIES (mode, neg_scalar_reg,
9708 : neg_scalar_reg);
9709 92 : ASSERT_RTX_EQ (series_0_r,
9710 : simplify_unary_operation (NEG, mode, series_0_nr, mode));
9711 92 : ASSERT_RTX_EQ (series_r_m1,
9712 : simplify_unary_operation (NEG, mode, series_nr_1, mode));
9713 92 : ASSERT_RTX_EQ (series_r_r,
9714 : simplify_unary_operation (NEG, mode, series_nr_nr, mode));
9715 :
9716 : /* Test that a VEC_SERIES with a zero step is simplified away. */
9717 92 : ASSERT_RTX_EQ (duplicate,
9718 : simplify_binary_operation (VEC_SERIES, mode,
9719 : scalar_reg, const0_rtx));
9720 :
9721 : /* Test PLUS and MINUS with VEC_SERIES. */
9722 92 : rtx series_0_1 = gen_const_vec_series (mode, const0_rtx, const1_rtx);
9723 92 : rtx series_0_m1 = gen_const_vec_series (mode, const0_rtx, constm1_rtx);
9724 92 : rtx series_r_1 = gen_rtx_VEC_SERIES (mode, scalar_reg, const1_rtx);
9725 92 : ASSERT_RTX_EQ (series_r_r,
9726 : simplify_binary_operation (PLUS, mode, series_0_r,
9727 : duplicate));
9728 92 : ASSERT_RTX_EQ (series_r_1,
9729 : simplify_binary_operation (PLUS, mode, duplicate,
9730 : series_0_1));
9731 92 : ASSERT_RTX_EQ (series_r_m1,
9732 : simplify_binary_operation (PLUS, mode, duplicate,
9733 : series_0_m1));
9734 92 : ASSERT_RTX_EQ (series_0_r,
9735 : simplify_binary_operation (MINUS, mode, series_r_r,
9736 : duplicate));
9737 92 : ASSERT_RTX_EQ (series_r_m1,
9738 : simplify_binary_operation (MINUS, mode, duplicate,
9739 : series_0_1));
9740 92 : ASSERT_RTX_EQ (series_r_1,
9741 : simplify_binary_operation (MINUS, mode, duplicate,
9742 : series_0_m1));
9743 92 : ASSERT_RTX_EQ (series_0_m1,
9744 : simplify_binary_operation (VEC_SERIES, mode, const0_rtx,
9745 : constm1_rtx));
9746 :
9747 : /* Test NEG on constant vector series. */
9748 92 : ASSERT_RTX_EQ (series_0_m1,
9749 : simplify_unary_operation (NEG, mode, series_0_1, mode));
9750 92 : ASSERT_RTX_EQ (series_0_1,
9751 : simplify_unary_operation (NEG, mode, series_0_m1, mode));
9752 :
9753 : /* Test PLUS and MINUS on constant vector series. */
9754 92 : rtx scalar2 = gen_int_mode (2, inner_mode);
9755 92 : rtx scalar3 = gen_int_mode (3, inner_mode);
9756 92 : rtx series_1_1 = gen_const_vec_series (mode, const1_rtx, const1_rtx);
9757 92 : rtx series_0_2 = gen_const_vec_series (mode, const0_rtx, scalar2);
9758 92 : rtx series_1_3 = gen_const_vec_series (mode, const1_rtx, scalar3);
9759 92 : ASSERT_RTX_EQ (series_1_1,
9760 : simplify_binary_operation (PLUS, mode, series_0_1,
9761 : CONST1_RTX (mode)));
9762 92 : ASSERT_RTX_EQ (series_0_m1,
9763 : simplify_binary_operation (PLUS, mode, CONST0_RTX (mode),
9764 : series_0_m1));
9765 92 : ASSERT_RTX_EQ (series_1_3,
9766 : simplify_binary_operation (PLUS, mode, series_1_1,
9767 : series_0_2));
9768 92 : ASSERT_RTX_EQ (series_0_1,
9769 : simplify_binary_operation (MINUS, mode, series_1_1,
9770 : CONST1_RTX (mode)));
9771 92 : ASSERT_RTX_EQ (series_1_1,
9772 : simplify_binary_operation (MINUS, mode, CONST1_RTX (mode),
9773 : series_0_m1));
9774 92 : ASSERT_RTX_EQ (series_1_1,
9775 : simplify_binary_operation (MINUS, mode, series_1_3,
9776 : series_0_2));
9777 :
9778 : /* Test MULT between constant vectors. */
9779 92 : rtx vec2 = gen_const_vec_duplicate (mode, scalar2);
9780 92 : rtx vec3 = gen_const_vec_duplicate (mode, scalar3);
9781 92 : rtx scalar9 = gen_int_mode (9, inner_mode);
9782 92 : rtx series_3_9 = gen_const_vec_series (mode, scalar3, scalar9);
9783 92 : ASSERT_RTX_EQ (series_0_2,
9784 : simplify_binary_operation (MULT, mode, series_0_1, vec2));
9785 92 : ASSERT_RTX_EQ (series_3_9,
9786 : simplify_binary_operation (MULT, mode, vec3, series_1_3));
9787 92 : if (!GET_MODE_NUNITS (mode).is_constant ())
9788 : ASSERT_FALSE (simplify_binary_operation (MULT, mode, series_0_1,
9789 : series_0_1));
9790 :
9791 : /* Test ASHIFT between constant vectors. */
9792 92 : ASSERT_RTX_EQ (series_0_2,
9793 : simplify_binary_operation (ASHIFT, mode, series_0_1,
9794 : CONST1_RTX (mode)));
9795 92 : if (!GET_MODE_NUNITS (mode).is_constant ())
9796 : ASSERT_FALSE (simplify_binary_operation (ASHIFT, mode, CONST1_RTX (mode),
9797 : series_0_1));
9798 92 : }
9799 :
9800 : static rtx
9801 3136 : simplify_merge_mask (rtx x, rtx mask, int op)
9802 : {
9803 0 : return simplify_context ().simplify_merge_mask (x, mask, op);
9804 : }
9805 :
9806 : /* Verify simplify_merge_mask works correctly. */
9807 :
9808 : static void
9809 224 : test_vec_merge (machine_mode mode)
9810 : {
9811 224 : rtx op0 = make_test_reg (mode);
9812 224 : rtx op1 = make_test_reg (mode);
9813 224 : rtx op2 = make_test_reg (mode);
9814 224 : rtx op3 = make_test_reg (mode);
9815 224 : rtx op4 = make_test_reg (mode);
9816 224 : rtx op5 = make_test_reg (mode);
9817 224 : rtx mask1 = make_test_reg (SImode);
9818 224 : rtx mask2 = make_test_reg (SImode);
9819 224 : rtx vm1 = gen_rtx_VEC_MERGE (mode, op0, op1, mask1);
9820 224 : rtx vm2 = gen_rtx_VEC_MERGE (mode, op2, op3, mask1);
9821 224 : rtx vm3 = gen_rtx_VEC_MERGE (mode, op4, op5, mask1);
9822 :
9823 : /* Simple vec_merge. */
9824 224 : ASSERT_EQ (op0, simplify_merge_mask (vm1, mask1, 0));
9825 224 : ASSERT_EQ (op1, simplify_merge_mask (vm1, mask1, 1));
9826 224 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 0));
9827 224 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 1));
9828 :
9829 : /* Nested vec_merge.
9830 : It's tempting to make this simplify right down to opN, but we don't
9831 : because all the simplify_* functions assume that the operands have
9832 : already been simplified. */
9833 224 : rtx nvm = gen_rtx_VEC_MERGE (mode, vm1, vm2, mask1);
9834 224 : ASSERT_EQ (vm1, simplify_merge_mask (nvm, mask1, 0));
9835 224 : ASSERT_EQ (vm2, simplify_merge_mask (nvm, mask1, 1));
9836 :
9837 : /* Intermediate unary op. */
9838 224 : rtx unop = gen_rtx_NOT (mode, vm1);
9839 224 : ASSERT_RTX_EQ (gen_rtx_NOT (mode, op0),
9840 : simplify_merge_mask (unop, mask1, 0));
9841 224 : ASSERT_RTX_EQ (gen_rtx_NOT (mode, op1),
9842 : simplify_merge_mask (unop, mask1, 1));
9843 :
9844 : /* Intermediate binary op. */
9845 224 : rtx binop = gen_rtx_PLUS (mode, vm1, vm2);
9846 224 : ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op0, op2),
9847 : simplify_merge_mask (binop, mask1, 0));
9848 224 : ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op1, op3),
9849 : simplify_merge_mask (binop, mask1, 1));
9850 :
9851 : /* Intermediate ternary op. */
9852 224 : rtx tenop = gen_rtx_FMA (mode, vm1, vm2, vm3);
9853 224 : ASSERT_RTX_EQ (gen_rtx_FMA (mode, op0, op2, op4),
9854 : simplify_merge_mask (tenop, mask1, 0));
9855 224 : ASSERT_RTX_EQ (gen_rtx_FMA (mode, op1, op3, op5),
9856 : simplify_merge_mask (tenop, mask1, 1));
9857 :
9858 : /* Side effects. */
9859 224 : rtx badop0 = gen_rtx_PRE_INC (mode, op0);
9860 224 : rtx badvm = gen_rtx_VEC_MERGE (mode, badop0, op1, mask1);
9861 224 : ASSERT_EQ (badop0, simplify_merge_mask (badvm, mask1, 0));
9862 224 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (badvm, mask1, 1));
9863 :
9864 : /* Called indirectly. */
9865 224 : ASSERT_RTX_EQ (gen_rtx_VEC_MERGE (mode, op0, op3, mask1),
9866 : simplify_rtx (nvm));
9867 224 : }
9868 :
9869 : /* Test that vector rotate formation works at RTL level. Try various
9870 : combinations of (REG << C) [|,^,+] (REG >> (<bitwidth> - C)). */
9871 :
9872 : static void
9873 92 : test_vector_rotate (rtx reg)
9874 : {
9875 92 : machine_mode mode = GET_MODE (reg);
9876 92 : unsigned bitwidth = GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT;
9877 92 : rtx plus_rtx = gen_rtx_PLUS (mode, reg, reg);
9878 92 : rtx lshftrt_amnt = GEN_INT (bitwidth - 1);
9879 92 : lshftrt_amnt = gen_const_vec_duplicate (mode, lshftrt_amnt);
9880 92 : rtx lshiftrt_rtx = gen_rtx_LSHIFTRT (mode, reg, lshftrt_amnt);
9881 92 : rtx rotate_rtx = gen_rtx_ROTATE (mode, reg, CONST1_RTX (mode));
9882 : /* Test explicitly the case where ASHIFT (x, 1) is a PLUS (x, x). */
9883 92 : ASSERT_RTX_EQ (rotate_rtx,
9884 : simplify_rtx (gen_rtx_IOR (mode, plus_rtx, lshiftrt_rtx)));
9885 92 : ASSERT_RTX_EQ (rotate_rtx,
9886 : simplify_rtx (gen_rtx_XOR (mode, plus_rtx, lshiftrt_rtx)));
9887 92 : ASSERT_RTX_EQ (rotate_rtx,
9888 : simplify_rtx (gen_rtx_PLUS (mode, plus_rtx, lshiftrt_rtx)));
9889 :
9890 : /* Don't go through every possible rotate amount to save execution time.
9891 : Multiple of BITS_PER_UNIT amounts could conceivably be simplified to
9892 : other bswap operations sometimes. Go through just the odd amounts. */
9893 1380 : for (unsigned i = 3; i < bitwidth - 2; i += 2)
9894 : {
9895 1288 : rtx rot_amnt = gen_const_vec_duplicate (mode, GEN_INT (i));
9896 1288 : rtx ashift_rtx = gen_rtx_ASHIFT (mode, reg, rot_amnt);
9897 1288 : lshftrt_amnt = gen_const_vec_duplicate (mode, GEN_INT (bitwidth - i));
9898 1288 : lshiftrt_rtx = gen_rtx_LSHIFTRT (mode, reg, lshftrt_amnt);
9899 1288 : rotate_rtx = gen_rtx_ROTATE (mode, reg, rot_amnt);
9900 1288 : ASSERT_RTX_EQ (rotate_rtx,
9901 : simplify_rtx (gen_rtx_IOR (mode, ashift_rtx, lshiftrt_rtx)));
9902 1288 : ASSERT_RTX_EQ (rotate_rtx,
9903 : simplify_rtx (gen_rtx_XOR (mode, ashift_rtx, lshiftrt_rtx)));
9904 1288 : ASSERT_RTX_EQ (rotate_rtx,
9905 : simplify_rtx (gen_rtx_PLUS (mode, ashift_rtx, lshiftrt_rtx)));
9906 : }
9907 92 : }
9908 :
9909 : /* Test subregs of integer vector constant X, trying elements in
9910 : the range [ELT_BIAS, ELT_BIAS + constant_lower_bound (NELTS)),
9911 : where NELTS is the number of elements in X. Subregs involving
9912 : elements [ELT_BIAS, ELT_BIAS + FIRST_VALID) are expected to fail. */
9913 :
9914 : static void
9915 276 : test_vector_subregs_modes (rtx x, poly_uint64 elt_bias = 0,
9916 : unsigned int first_valid = 0)
9917 : {
9918 276 : machine_mode inner_mode = GET_MODE (x);
9919 276 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9920 :
9921 34500 : for (unsigned int modei = 0; modei < NUM_MACHINE_MODES; ++modei)
9922 : {
9923 34224 : machine_mode outer_mode = (machine_mode) modei;
9924 34224 : if (!VECTOR_MODE_P (outer_mode))
9925 18768 : continue;
9926 :
9927 15456 : unsigned int outer_nunits;
9928 15456 : if (GET_MODE_INNER (outer_mode) == int_mode
9929 1932 : && GET_MODE_NUNITS (outer_mode).is_constant (&outer_nunits)
9930 20412 : && multiple_p (GET_MODE_NUNITS (inner_mode), outer_nunits))
9931 : {
9932 : /* Test subregs in which the outer mode is a smaller,
9933 : constant-sized vector of the same element type. */
9934 1092 : unsigned int limit
9935 1092 : = constant_lower_bound (GET_MODE_NUNITS (inner_mode));
9936 8028 : for (unsigned int elt = 0; elt < limit; elt += outer_nunits)
9937 : {
9938 6936 : rtx expected = NULL_RTX;
9939 6936 : if (elt >= first_valid)
9940 : {
9941 6936 : rtx_vector_builder builder (outer_mode, outer_nunits, 1);
9942 46704 : for (unsigned int i = 0; i < outer_nunits; ++i)
9943 32832 : builder.quick_push (CONST_VECTOR_ELT (x, elt + i));
9944 6936 : expected = builder.build ();
9945 6936 : }
9946 13872 : poly_uint64 byte = (elt_bias + elt) * GET_MODE_SIZE (int_mode);
9947 6936 : ASSERT_RTX_EQ (expected,
9948 : simplify_subreg (outer_mode, x,
9949 : inner_mode, byte));
9950 : }
9951 : }
9952 28728 : else if (known_eq (GET_MODE_SIZE (outer_mode),
9953 : GET_MODE_SIZE (inner_mode))
9954 2040 : && known_eq (elt_bias, 0U)
9955 2040 : && (GET_MODE_CLASS (outer_mode) != MODE_VECTOR_BOOL
9956 0 : || known_eq (GET_MODE_BITSIZE (outer_mode),
9957 : GET_MODE_NUNITS (outer_mode)))
9958 2040 : && (!FLOAT_MODE_P (outer_mode)
9959 15876 : || (FLOAT_MODE_FORMAT (outer_mode)->ieee_bits
9960 1104 : == GET_MODE_UNIT_PRECISION (outer_mode)))
9961 14364 : && (GET_MODE_SIZE (inner_mode).is_constant ()
9962 : || !CONST_VECTOR_STEPPED_P (x)))
9963 : {
9964 : /* Try converting to OUTER_MODE and back. */
9965 1800 : rtx outer_x = simplify_subreg (outer_mode, x, inner_mode, 0);
9966 1800 : ASSERT_TRUE (outer_x != NULL_RTX);
9967 1800 : ASSERT_RTX_EQ (x, simplify_subreg (inner_mode, outer_x,
9968 : outer_mode, 0));
9969 : }
9970 : }
9971 :
9972 276 : if (BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
9973 : {
9974 : /* Test each byte in the element range. */
9975 276 : unsigned int limit
9976 276 : = constant_lower_bound (GET_MODE_SIZE (inner_mode));
9977 14604 : for (unsigned int i = 0; i < limit; ++i)
9978 : {
9979 14328 : unsigned int elt = i / GET_MODE_SIZE (int_mode);
9980 14328 : rtx expected = NULL_RTX;
9981 14328 : if (elt >= first_valid)
9982 : {
9983 14328 : unsigned int byte_shift = i % GET_MODE_SIZE (int_mode);
9984 14328 : if (BYTES_BIG_ENDIAN)
9985 : byte_shift = GET_MODE_SIZE (int_mode) - byte_shift - 1;
9986 14328 : rtx_mode_t vec_elt (CONST_VECTOR_ELT (x, elt), int_mode);
9987 14328 : wide_int shifted_elt
9988 14328 : = wi::lrshift (vec_elt, byte_shift * BITS_PER_UNIT);
9989 14328 : expected = immed_wide_int_const (shifted_elt, QImode);
9990 14328 : }
9991 28656 : poly_uint64 byte = elt_bias * GET_MODE_SIZE (int_mode) + i;
9992 14328 : ASSERT_RTX_EQ (expected,
9993 : simplify_subreg (QImode, x, inner_mode, byte));
9994 : }
9995 : }
9996 276 : }
9997 :
9998 : /* Test constant subregs of integer vector mode INNER_MODE, using 1
9999 : element per pattern. */
10000 :
10001 : static void
10002 92 : test_vector_subregs_repeating (machine_mode inner_mode)
10003 : {
10004 184 : poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
10005 92 : unsigned int min_nunits = constant_lower_bound (nunits);
10006 92 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
10007 92 : unsigned int count = gcd (min_nunits, 8);
10008 :
10009 92 : rtx_vector_builder builder (inner_mode, count, 1);
10010 776 : for (unsigned int i = 0; i < count; ++i)
10011 592 : builder.quick_push (gen_int_mode (8 - i, int_mode));
10012 92 : rtx x = builder.build ();
10013 :
10014 92 : test_vector_subregs_modes (x);
10015 92 : if (!nunits.is_constant ())
10016 : test_vector_subregs_modes (x, nunits - min_nunits);
10017 92 : }
10018 :
10019 : /* Test constant subregs of integer vector mode INNER_MODE, using 2
10020 : elements per pattern. */
10021 :
10022 : static void
10023 92 : test_vector_subregs_fore_back (machine_mode inner_mode)
10024 : {
10025 184 : poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
10026 92 : unsigned int min_nunits = constant_lower_bound (nunits);
10027 92 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
10028 92 : unsigned int count = gcd (min_nunits, 4);
10029 :
10030 92 : rtx_vector_builder builder (inner_mode, count, 2);
10031 536 : for (unsigned int i = 0; i < count; ++i)
10032 352 : builder.quick_push (gen_int_mode (i, int_mode));
10033 444 : for (unsigned int i = 0; i < count; ++i)
10034 352 : builder.quick_push (gen_int_mode (-1 - (int) i, int_mode));
10035 92 : rtx x = builder.build ();
10036 :
10037 92 : test_vector_subregs_modes (x);
10038 92 : if (!nunits.is_constant ())
10039 : test_vector_subregs_modes (x, nunits - min_nunits, count);
10040 92 : }
10041 :
10042 : /* Test constant subregs of integer vector mode INNER_MODE, using 3
10043 : elements per pattern. */
10044 :
10045 : static void
10046 92 : test_vector_subregs_stepped (machine_mode inner_mode)
10047 : {
10048 : /* Build { 0, 1, 2, 3, ... }. */
10049 92 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
10050 92 : rtx_vector_builder builder (inner_mode, 1, 3);
10051 460 : for (unsigned int i = 0; i < 3; ++i)
10052 276 : builder.quick_push (gen_int_mode (i, int_mode));
10053 92 : rtx x = builder.build ();
10054 :
10055 92 : test_vector_subregs_modes (x);
10056 92 : }
10057 :
10058 : /* Test constant subregs of integer vector mode INNER_MODE. */
10059 :
10060 : static void
10061 92 : test_vector_subregs (machine_mode inner_mode)
10062 : {
10063 92 : test_vector_subregs_repeating (inner_mode);
10064 92 : test_vector_subregs_fore_back (inner_mode);
10065 92 : test_vector_subregs_stepped (inner_mode);
10066 92 : }
10067 :
10068 : /* Verify some simplifications involving vectors. */
10069 :
10070 : static void
10071 4 : test_vector_ops ()
10072 : {
10073 500 : for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
10074 : {
10075 496 : machine_mode mode = (machine_mode) i;
10076 496 : if (VECTOR_MODE_P (mode))
10077 : {
10078 448 : rtx scalar_reg = make_test_reg (GET_MODE_INNER (mode));
10079 224 : test_vector_ops_duplicate (mode, scalar_reg);
10080 224 : rtx vector_reg = make_test_reg (mode);
10081 224 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
10082 348 : && maybe_gt (GET_MODE_NUNITS (mode), 2))
10083 : {
10084 92 : test_vector_ops_series (mode, scalar_reg);
10085 92 : test_vector_subregs (mode);
10086 92 : test_vector_rotate (vector_reg);
10087 : }
10088 224 : test_vec_merge (mode);
10089 : }
10090 : }
10091 4 : }
10092 :
10093 : template<unsigned int N>
10094 : struct simplify_const_poly_int_tests
10095 : {
10096 : static void run ();
10097 : };
10098 :
10099 : template<>
10100 : struct simplify_const_poly_int_tests<1>
10101 : {
10102 : static void run () {}
10103 : };
10104 :
10105 : /* Test various CONST_POLY_INT properties. */
10106 :
10107 : template<unsigned int N>
10108 : void
10109 : simplify_const_poly_int_tests<N>::run ()
10110 : {
10111 : using poly_int64 = poly_int<N, HOST_WIDE_INT>;
10112 : rtx x1 = gen_int_mode (poly_int64 (1, 1), QImode);
10113 : rtx x2 = gen_int_mode (poly_int64 (-80, 127), QImode);
10114 : rtx x3 = gen_int_mode (poly_int64 (-79, -128), QImode);
10115 : rtx x4 = gen_int_mode (poly_int64 (5, 4), QImode);
10116 : rtx x5 = gen_int_mode (poly_int64 (30, 24), QImode);
10117 : rtx x6 = gen_int_mode (poly_int64 (20, 16), QImode);
10118 : rtx x7 = gen_int_mode (poly_int64 (7, 4), QImode);
10119 : rtx x8 = gen_int_mode (poly_int64 (30, 24), HImode);
10120 : rtx x9 = gen_int_mode (poly_int64 (-30, -24), HImode);
10121 : rtx x10 = gen_int_mode (poly_int64 (-31, -24), HImode);
10122 : rtx two = GEN_INT (2);
10123 : rtx six = GEN_INT (6);
10124 : poly_uint64 offset = subreg_lowpart_offset (QImode, HImode);
10125 :
10126 : /* These tests only try limited operation combinations. Fuller arithmetic
10127 : testing is done directly on poly_ints. */
10128 : ASSERT_EQ (simplify_unary_operation (NEG, HImode, x8, HImode), x9);
10129 : ASSERT_EQ (simplify_unary_operation (NOT, HImode, x8, HImode), x10);
10130 : ASSERT_EQ (simplify_unary_operation (TRUNCATE, QImode, x8, HImode), x5);
10131 : ASSERT_EQ (simplify_binary_operation (PLUS, QImode, x1, x2), x3);
10132 : ASSERT_EQ (simplify_binary_operation (MINUS, QImode, x3, x1), x2);
10133 : ASSERT_EQ (simplify_binary_operation (MULT, QImode, x4, six), x5);
10134 : ASSERT_EQ (simplify_binary_operation (MULT, QImode, six, x4), x5);
10135 : ASSERT_EQ (simplify_binary_operation (ASHIFT, QImode, x4, two), x6);
10136 : ASSERT_EQ (simplify_binary_operation (IOR, QImode, x4, two), x7);
10137 : ASSERT_EQ (simplify_subreg (HImode, x5, QImode, 0), x8);
10138 : ASSERT_EQ (simplify_subreg (QImode, x8, HImode, offset), x5);
10139 : }
10140 :
10141 : /* Run all of the selftests within this file. */
10142 :
10143 : void
10144 4 : simplify_rtx_cc_tests ()
10145 : {
10146 4 : test_scalar_ops ();
10147 4 : test_vector_ops ();
10148 4 : simplify_const_poly_int_tests<NUM_POLY_INT_COEFFS>::run ();
10149 4 : }
10150 :
10151 : } // namespace selftest
10152 :
10153 : #endif /* CHECKING_P */
|