Branch data Line data Source code
1 : : /* RTL simplification functions for GNU compiler.
2 : : Copyright (C) 1987-2024 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 : 7323827 : neg_poly_int_rtx (machine_mode mode, const_rtx i)
56 : : {
57 : 7323827 : 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 : 5686942 : mode_signbit_p (machine_mode mode, const_rtx x)
65 : : {
66 : 5686942 : unsigned HOST_WIDE_INT val;
67 : 5686942 : unsigned int width;
68 : 5686942 : scalar_int_mode int_mode;
69 : :
70 : 5686942 : if (!is_int_mode (mode, &int_mode))
71 : : return false;
72 : :
73 : 5686934 : width = GET_MODE_PRECISION (int_mode);
74 : 5686934 : if (width == 0)
75 : : return false;
76 : :
77 : 5686934 : if (width <= HOST_BITS_PER_WIDE_INT
78 : 5685423 : && CONST_INT_P (x))
79 : 5575194 : val = INTVAL (x);
80 : : #if TARGET_SUPPORTS_WIDE_INT
81 : 111740 : else if (CONST_WIDE_INT_P (x))
82 : : {
83 : 473 : unsigned int i;
84 : 473 : unsigned int elts = CONST_WIDE_INT_NUNITS (x);
85 : 473 : if (elts != (width + HOST_BITS_PER_WIDE_INT - 1) / HOST_BITS_PER_WIDE_INT)
86 : : return false;
87 : 887 : for (i = 0; i < elts - 1; i++)
88 : 473 : if (CONST_WIDE_INT_ELT (x, i) != 0)
89 : : return false;
90 : 414 : val = CONST_WIDE_INT_ELT (x, elts - 1);
91 : 414 : width %= HOST_BITS_PER_WIDE_INT;
92 : 414 : if (width == 0)
93 : : width = HOST_BITS_PER_WIDE_INT;
94 : : }
95 : : #else
96 : : else if (width <= HOST_BITS_PER_DOUBLE_INT
97 : : && CONST_DOUBLE_AS_INT_P (x)
98 : : && CONST_DOUBLE_LOW (x) == 0)
99 : : {
100 : : val = CONST_DOUBLE_HIGH (x);
101 : : width -= HOST_BITS_PER_WIDE_INT;
102 : : }
103 : : #endif
104 : : else
105 : : /* X is not an integer constant. */
106 : : return false;
107 : :
108 : 5575194 : if (width < HOST_BITS_PER_WIDE_INT)
109 : 5103232 : val &= (HOST_WIDE_INT_1U << width) - 1;
110 : 5575608 : 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 : 2989395 : val_signbit_p (machine_mode mode, unsigned HOST_WIDE_INT val)
119 : : {
120 : 2989395 : unsigned int width;
121 : 2989395 : scalar_int_mode int_mode;
122 : :
123 : 2989395 : if (!is_int_mode (mode, &int_mode))
124 : : return false;
125 : :
126 : 2989359 : width = GET_MODE_PRECISION (int_mode);
127 : 2989359 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
128 : : return false;
129 : :
130 : 2984802 : val &= GET_MODE_MASK (int_mode);
131 : 2984802 : 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 : 2597372 : val_signbit_known_set_p (machine_mode mode, unsigned HOST_WIDE_INT val)
138 : : {
139 : 2597372 : unsigned int width;
140 : :
141 : 2597372 : scalar_int_mode int_mode;
142 : 2597372 : if (!is_int_mode (mode, &int_mode))
143 : : return false;
144 : :
145 : 2570900 : width = GET_MODE_PRECISION (int_mode);
146 : 2570900 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
147 : : return false;
148 : :
149 : 2570900 : val &= HOST_WIDE_INT_1U << (width - 1);
150 : 2570900 : 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 : 7438893 : val_signbit_known_clear_p (machine_mode mode, unsigned HOST_WIDE_INT val)
157 : : {
158 : 7438893 : unsigned int width;
159 : :
160 : 7438893 : scalar_int_mode int_mode;
161 : 7438893 : if (!is_int_mode (mode, &int_mode))
162 : : return false;
163 : :
164 : 7169885 : width = GET_MODE_PRECISION (int_mode);
165 : 7169885 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
166 : : return false;
167 : :
168 : 7061045 : val &= HOST_WIDE_INT_1U << (width - 1);
169 : 7061045 : 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 : 96676809 : simplify_context::simplify_gen_binary (rtx_code code, machine_mode mode,
177 : : rtx op0, rtx op1)
178 : : {
179 : 96676809 : rtx tem;
180 : :
181 : : /* If this simplifies, do it. */
182 : 96676809 : tem = simplify_binary_operation (code, mode, op0, op1);
183 : 96676809 : if (tem)
184 : : return tem;
185 : :
186 : : /* Put complex operands first and constants second if commutative. */
187 : 60877072 : if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
188 : 60877072 : && swap_commutative_operands_p (op0, op1))
189 : : std::swap (op0, op1);
190 : :
191 : 60877072 : 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 : 2187080151 : avoid_constant_pool_reference (rtx x)
198 : : {
199 : 2187080151 : rtx c, tmp, addr;
200 : 2187080151 : machine_mode cmode;
201 : 2187080151 : poly_int64 offset = 0;
202 : :
203 : 2187080151 : switch (GET_CODE (x))
204 : : {
205 : 203009677 : case MEM:
206 : 203009677 : break;
207 : :
208 : 1282164 : case FLOAT_EXTEND:
209 : : /* Handle float extensions of constant pool references. */
210 : 1282164 : tmp = XEXP (x, 0);
211 : 1282164 : c = avoid_constant_pool_reference (tmp);
212 : 1282164 : if (c != tmp && CONST_DOUBLE_AS_FLOAT_P (c))
213 : 139732 : return const_double_from_real_value (*CONST_DOUBLE_REAL_VALUE (c),
214 : 139732 : GET_MODE (x));
215 : : return x;
216 : :
217 : : default:
218 : : return x;
219 : : }
220 : :
221 : 203009677 : if (GET_MODE (x) == BLKmode)
222 : : return x;
223 : :
224 : 200905750 : addr = XEXP (x, 0);
225 : :
226 : : /* Call target hook to avoid the effects of -fpic etc.... */
227 : 200905750 : addr = targetm.delegitimize_address (addr);
228 : :
229 : : /* Split the address into a base and integer offset. */
230 : 200905750 : addr = strip_offset (addr, &offset);
231 : :
232 : 200905750 : 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 : 200905750 : if (GET_CODE (addr) == SYMBOL_REF
238 : 200905750 : && CONSTANT_POOL_ADDRESS_P (addr))
239 : : {
240 : 4689861 : c = get_pool_constant (addr);
241 : 4689861 : 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 : 4689861 : if (known_eq (offset, 0) && cmode == GET_MODE (x))
247 : : return c;
248 : 25684 : else if (known_in_range_p (offset, 0, GET_MODE_SIZE (cmode)))
249 : : {
250 : 12842 : rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset);
251 : 12842 : if (tem && CONSTANT_P (tem))
252 : : return tem;
253 : : }
254 : : }
255 : :
256 : : return x;
257 : : }
258 : :
259 : : /* Simplify a MEM based on its attributes. This is the default
260 : : delegitimize_address target hook, and it's recommended that every
261 : : overrider call it. */
262 : :
263 : : rtx
264 : 3532187453 : 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 : 3532187453 : if (MEM_P (x)
269 : 58079312 : && MEM_EXPR (x)
270 : 3567750530 : && MEM_OFFSET_KNOWN_P (x))
271 : : {
272 : 32906252 : tree decl = MEM_EXPR (x);
273 : 32906252 : machine_mode mode = GET_MODE (x);
274 : 32906252 : poly_int64 offset = 0;
275 : :
276 : 32906252 : switch (TREE_CODE (decl))
277 : : {
278 : : default:
279 : : decl = NULL;
280 : : break;
281 : :
282 : : case VAR_DECL:
283 : : break;
284 : :
285 : 9909909 : case ARRAY_REF:
286 : 9909909 : case ARRAY_RANGE_REF:
287 : 9909909 : case COMPONENT_REF:
288 : 9909909 : case BIT_FIELD_REF:
289 : 9909909 : case REALPART_EXPR:
290 : 9909909 : case IMAGPART_EXPR:
291 : 9909909 : case VIEW_CONVERT_EXPR:
292 : 9909909 : {
293 : 9909909 : poly_int64 bitsize, bitpos, bytepos, toffset_val = 0;
294 : 9909909 : tree toffset;
295 : 9909909 : int unsignedp, reversep, volatilep = 0;
296 : :
297 : 9909909 : decl
298 : 9909909 : = get_inner_reference (decl, &bitsize, &bitpos, &toffset, &mode,
299 : : &unsignedp, &reversep, &volatilep);
300 : 19819818 : if (maybe_ne (bitsize, GET_MODE_BITSIZE (mode))
301 : 10179284 : || !multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
302 : 19167008 : || (toffset && !poly_int_tree_p (toffset, &toffset_val)))
303 : : decl = NULL;
304 : : else
305 : 8987724 : offset += bytepos + toffset_val;
306 : 9909909 : break;
307 : : }
308 : : }
309 : :
310 : 922185 : if (decl
311 : 19187941 : && mode == GET_MODE (x)
312 : 18919298 : && VAR_P (decl)
313 : 12128213 : && (TREE_STATIC (decl)
314 : 10964581 : || DECL_THREAD_LOCAL_P (decl))
315 : 1202216 : && DECL_RTL_SET_P (decl)
316 : 10189517 : && MEM_P (DECL_RTL (decl)))
317 : : {
318 : 1201793 : rtx newx;
319 : :
320 : 1201793 : offset += MEM_OFFSET (x);
321 : :
322 : 1201793 : newx = DECL_RTL (decl);
323 : :
324 : 1201793 : if (MEM_P (newx))
325 : : {
326 : 1201793 : rtx n = XEXP (newx, 0), o = XEXP (x, 0);
327 : 1201793 : 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 : 1201793 : n = strip_offset (n, &n_offset);
336 : 1201793 : o = strip_offset (o, &o_offset);
337 : 2376941 : if (!(known_eq (o_offset, n_offset + offset)
338 : 1175148 : && rtx_equal_p (o, n)))
339 : 207841 : 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 : 3532187453 : 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 : 4762648 : simplify_context::simplify_gen_unary (rtx_code code, machine_mode mode, rtx op,
355 : : machine_mode op_mode)
356 : : {
357 : 4762648 : rtx tem;
358 : :
359 : : /* If this simplifies, use it. */
360 : 4762648 : if ((tem = simplify_unary_operation (code, mode, op, op_mode)) != 0)
361 : : return tem;
362 : :
363 : 1690138 : return gen_rtx_fmt_e (code, mode, op);
364 : : }
365 : :
366 : : /* Likewise for ternary operations. */
367 : :
368 : : rtx
369 : 1902282 : 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 : 1902282 : rtx tem;
374 : :
375 : : /* If this simplifies, use it. */
376 : 1902282 : if ((tem = simplify_ternary_operation (code, mode, op0_mode,
377 : : op0, op1, op2)) != 0)
378 : : return tem;
379 : :
380 : 1682788 : 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 : 14294427 : simplify_context::simplify_gen_relational (rtx_code code, machine_mode mode,
388 : : machine_mode cmp_mode,
389 : : rtx op0, rtx op1)
390 : : {
391 : 14294427 : rtx tem;
392 : :
393 : 14294427 : if ((tem = simplify_relational_operation (code, mode, cmp_mode,
394 : : op0, op1)) != 0)
395 : : return tem;
396 : :
397 : 12290877 : 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 : 399785072 : simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
407 : : rtx (*fn) (rtx, const_rtx, void *), void *data)
408 : : {
409 : 399785072 : enum rtx_code code = GET_CODE (x);
410 : 399785072 : machine_mode mode = GET_MODE (x);
411 : 399785072 : machine_mode op_mode;
412 : 399785072 : const char *fmt;
413 : 399785072 : rtx op0, op1, op2, newx, op;
414 : 399785072 : rtvec vec, newvec;
415 : 399785072 : int i, j;
416 : :
417 : 399785072 : if (UNLIKELY (fn != NULL))
418 : : {
419 : 348313079 : newx = fn (x, old_rtx, data);
420 : 348313079 : if (newx)
421 : : return newx;
422 : : }
423 : 51471993 : else if (rtx_equal_p (x, old_rtx))
424 : 4307305 : return copy_rtx ((rtx) data);
425 : :
426 : 306606085 : switch (GET_RTX_CLASS (code))
427 : : {
428 : 1871060 : case RTX_UNARY:
429 : 1871060 : op0 = XEXP (x, 0);
430 : 1871060 : op_mode = GET_MODE (op0);
431 : 1871060 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
432 : 1871060 : if (op0 == XEXP (x, 0))
433 : : return x;
434 : 599215 : return simplify_gen_unary (code, mode, op0, op_mode);
435 : :
436 : 64438898 : case RTX_BIN_ARITH:
437 : 64438898 : case RTX_COMM_ARITH:
438 : 64438898 : op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
439 : 64438898 : op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
440 : 64438898 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
441 : : return x;
442 : 20521040 : return simplify_gen_binary (code, mode, op0, op1);
443 : :
444 : 8395583 : case RTX_COMPARE:
445 : 8395583 : case RTX_COMM_COMPARE:
446 : 8395583 : op0 = XEXP (x, 0);
447 : 8395583 : op1 = XEXP (x, 1);
448 : 8395583 : op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
449 : 8395583 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
450 : 8395583 : op1 = simplify_replace_fn_rtx (op1, old_rtx, fn, data);
451 : 8395583 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
452 : : return x;
453 : 2115611 : return simplify_gen_relational (code, mode, op_mode, op0, op1);
454 : :
455 : 5007500 : case RTX_TERNARY:
456 : 5007500 : case RTX_BITFIELD_OPS:
457 : 5007500 : op0 = XEXP (x, 0);
458 : 5007500 : op_mode = GET_MODE (op0);
459 : 5007500 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
460 : 5007500 : op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
461 : 5007500 : op2 = simplify_replace_fn_rtx (XEXP (x, 2), old_rtx, fn, data);
462 : 5007500 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2))
463 : : return x;
464 : 1506779 : if (op_mode == VOIDmode)
465 : 1483988 : op_mode = GET_MODE (op0);
466 : 1506779 : return simplify_gen_ternary (code, mode, op_mode, op0, op1, op2);
467 : :
468 : 59600001 : case RTX_EXTRA:
469 : 59600001 : if (code == SUBREG)
470 : : {
471 : 540652 : op0 = simplify_replace_fn_rtx (SUBREG_REG (x), old_rtx, fn, data);
472 : 540652 : if (op0 == SUBREG_REG (x))
473 : : return x;
474 : 83306 : op0 = simplify_gen_subreg (GET_MODE (x), op0,
475 : 41653 : GET_MODE (SUBREG_REG (x)),
476 : 41653 : SUBREG_BYTE (x));
477 : 41653 : return op0 ? op0 : x;
478 : : }
479 : : break;
480 : :
481 : 48452846 : case RTX_OBJ:
482 : 48452846 : if (code == MEM)
483 : : {
484 : 9295329 : op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
485 : 9295329 : if (op0 == XEXP (x, 0))
486 : : return x;
487 : 125381 : return replace_equiv_address_nv (x, op0);
488 : : }
489 : 39157517 : 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 : 217057063 : newx = x;
515 : 217057063 : fmt = GET_RTX_FORMAT (code);
516 : 468592648 : for (i = 0; fmt[i]; i++)
517 : 251535585 : switch (fmt[i])
518 : : {
519 : 2783937 : case 'E':
520 : 2783937 : vec = XVEC (x, i);
521 : 2783937 : newvec = XVEC (newx, i);
522 : 11083094 : for (j = 0; j < GET_NUM_ELEM (vec); j++)
523 : : {
524 : 8299157 : op = simplify_replace_fn_rtx (RTVEC_ELT (vec, j),
525 : : old_rtx, fn, data);
526 : 8299157 : if (op != RTVEC_ELT (vec, j))
527 : : {
528 : 328567 : if (newvec == vec)
529 : : {
530 : 321842 : newvec = shallow_copy_rtvec (vec);
531 : 321842 : if (x == newx)
532 : 321842 : newx = shallow_copy_rtx (x);
533 : 321842 : XVEC (newx, i) = newvec;
534 : : }
535 : 328567 : RTVEC_ELT (newvec, j) = op;
536 : : }
537 : : }
538 : : break;
539 : :
540 : 52688311 : case 'e':
541 : 52688311 : if (XEXP (x, i))
542 : : {
543 : 52688311 : op = simplify_replace_fn_rtx (XEXP (x, i), old_rtx, fn, data);
544 : 52688311 : if (op != XEXP (x, i))
545 : : {
546 : 2830496 : if (x == newx)
547 : 2827433 : newx = shallow_copy_rtx (x);
548 : 2830496 : 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 : 10962462 : simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx)
561 : : {
562 : 10962462 : 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 : 18545308 : simplify_context::simplify_truncation (machine_mode mode, rtx op,
614 : : machine_mode op_mode)
615 : : {
616 : 18545308 : unsigned int precision = GET_MODE_UNIT_PRECISION (mode);
617 : 18545308 : unsigned int op_precision = GET_MODE_UNIT_PRECISION (op_mode);
618 : 18545308 : scalar_int_mode int_mode, int_op_mode, subreg_mode;
619 : :
620 : 18545308 : gcc_assert (precision <= op_precision);
621 : :
622 : : /* Optimize truncations of zero and sign extended values. */
623 : 18545308 : if (GET_CODE (op) == ZERO_EXTEND
624 : 18545308 : || 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 : 294945 : machine_mode origmode = GET_MODE (XEXP (op, 0));
633 : 294945 : if (mode == origmode)
634 : : return XEXP (op, 0);
635 : 19380 : else if (precision <= GET_MODE_UNIT_PRECISION (origmode))
636 : 6707 : return simplify_gen_unary (TRUNCATE, mode,
637 : 6707 : XEXP (op, 0), origmode);
638 : : else
639 : 2983 : return simplify_gen_unary (GET_CODE (op), mode,
640 : 2983 : 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 : 18250363 : if (1
647 : : && (!WORD_REGISTER_OPERATIONS || precision >= BITS_PER_WORD)
648 : : && (GET_CODE (op) == PLUS
649 : : || GET_CODE (op) == MINUS
650 : 18250363 : || GET_CODE (op) == MULT))
651 : : {
652 : 805507 : rtx op0 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0), op_mode);
653 : 805507 : if (op0)
654 : : {
655 : 805507 : rtx op1 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 1), op_mode);
656 : 805507 : if (op1)
657 : 805507 : 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 : 17444856 : if ((GET_CODE (op) == LSHIFTRT
665 : 17444856 : || 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 : 1645328 : && 2 * precision <= op_precision
671 : 1645328 : && CONST_INT_P (XEXP (op, 1))
672 : 1546047 : && GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
673 : 19 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
674 : 19 : && UINTVAL (XEXP (op, 1)) < precision)
675 : 11 : return simplify_gen_binary (ASHIFTRT, mode,
676 : 11 : 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 : 17444845 : if ((GET_CODE (op) == LSHIFTRT
682 : : || GET_CODE (op) == ASHIFTRT)
683 : 1645317 : && CONST_INT_P (XEXP (op, 1))
684 : 1546036 : && GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
685 : 468 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
686 : 468 : && UINTVAL (XEXP (op, 1)) < precision)
687 : 458 : return simplify_gen_binary (LSHIFTRT, mode,
688 : 458 : 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 : 17444387 : if (GET_CODE (op) == ASHIFT
694 : 637522 : && CONST_INT_P (XEXP (op, 1))
695 : 585539 : && (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
696 : 585539 : || GET_CODE (XEXP (op, 0)) == SIGN_EXTEND)
697 : 658 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
698 : 649 : && UINTVAL (XEXP (op, 1)) < precision)
699 : 643 : return simplify_gen_binary (ASHIFT, mode,
700 : 643 : 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 : 17443744 : if (GET_CODE (op) == AND
706 : 606336 : && (GET_CODE (XEXP (op, 0)) == LSHIFTRT
707 : 606336 : || GET_CODE (XEXP (op, 0)) == ASHIFTRT)
708 : 47435 : && CONST_INT_P (XEXP (XEXP (op, 0), 1))
709 : 47340 : && CONST_INT_P (XEXP (op, 1)))
710 : : {
711 : 47340 : rtx op0 = (XEXP (XEXP (op, 0), 0));
712 : 47340 : rtx shift_op = XEXP (XEXP (op, 0), 1);
713 : 47340 : rtx mask_op = XEXP (op, 1);
714 : 47340 : unsigned HOST_WIDE_INT shift = UINTVAL (shift_op);
715 : 47340 : unsigned HOST_WIDE_INT mask = UINTVAL (mask_op);
716 : :
717 : 47340 : if (shift < precision
718 : : /* If doing this transform works for an X with all bits set,
719 : : it works for any X. */
720 : 34797 : && ((GET_MODE_MASK (mode) >> shift) & mask)
721 : 34797 : == ((GET_MODE_MASK (op_mode) >> shift) & mask)
722 : 3405 : && (op0 = simplify_gen_unary (TRUNCATE, mode, op0, op_mode))
723 : 50745 : && (op0 = simplify_gen_binary (LSHIFTRT, mode, op0, shift_op)))
724 : : {
725 : 3405 : mask_op = GEN_INT (trunc_int_for_mode (mask, mode));
726 : 3405 : return simplify_gen_binary (AND, mode, op0, mask_op);
727 : : }
728 : : }
729 : :
730 : : /* Turn (truncate:M1 (*_extract:M2 (reg:M2) (len) (pos))) into
731 : : (*_extract:M1 (truncate:M1 (reg:M2)) (len) (pos')) if possible without
732 : : changing len. */
733 : 17440339 : if ((GET_CODE (op) == ZERO_EXTRACT || GET_CODE (op) == SIGN_EXTRACT)
734 : 388985 : && REG_P (XEXP (op, 0))
735 : 269588 : && GET_MODE (XEXP (op, 0)) == GET_MODE (op)
736 : 268469 : && CONST_INT_P (XEXP (op, 1))
737 : 268469 : && CONST_INT_P (XEXP (op, 2)))
738 : : {
739 : 241817 : rtx op0 = XEXP (op, 0);
740 : 241817 : unsigned HOST_WIDE_INT len = UINTVAL (XEXP (op, 1));
741 : 241817 : unsigned HOST_WIDE_INT pos = UINTVAL (XEXP (op, 2));
742 : 241817 : if (BITS_BIG_ENDIAN && pos >= op_precision - precision)
743 : : {
744 : : op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
745 : : if (op0)
746 : : {
747 : : pos -= op_precision - precision;
748 : : return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
749 : : XEXP (op, 1), GEN_INT (pos));
750 : : }
751 : : }
752 : 241817 : else if (!BITS_BIG_ENDIAN && precision >= len + pos)
753 : : {
754 : 8672 : op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
755 : 8672 : if (op0)
756 : 8672 : return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
757 : 8672 : XEXP (op, 1), XEXP (op, 2));
758 : : }
759 : : }
760 : :
761 : : /* Recognize a word extraction from a multi-word subreg. */
762 : 17431667 : if ((GET_CODE (op) == LSHIFTRT
763 : 17431667 : || GET_CODE (op) == ASHIFTRT)
764 : 1644859 : && SCALAR_INT_MODE_P (mode)
765 : 1641810 : && SCALAR_INT_MODE_P (op_mode)
766 : 1771208 : && precision >= BITS_PER_WORD
767 : 56359 : && 2 * precision <= op_precision
768 : 56359 : && CONST_INT_P (XEXP (op, 1))
769 : 48736 : && (INTVAL (XEXP (op, 1)) & (precision - 1)) == 0
770 : 1898 : && UINTVAL (XEXP (op, 1)) < op_precision)
771 : : {
772 : 1898 : poly_int64 byte = subreg_lowpart_offset (mode, op_mode);
773 : 1898 : int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
774 : 1898 : return simplify_gen_subreg (mode, XEXP (op, 0), op_mode,
775 : : (WORDS_BIG_ENDIAN
776 : 1898 : ? byte - shifted_bytes
777 : 1898 : : 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 : 17429769 : if ((GET_CODE (op) == LSHIFTRT
784 : : || GET_CODE (op) == ASHIFTRT)
785 : 1642961 : && is_a <scalar_int_mode> (mode, &int_mode)
786 : 1639912 : && is_a <scalar_int_mode> (op_mode, &int_op_mode)
787 : 1639912 : && MEM_P (XEXP (op, 0))
788 : 5572 : && CONST_INT_P (XEXP (op, 1))
789 : 9288 : && INTVAL (XEXP (op, 1)) % GET_MODE_BITSIZE (int_mode) == 0
790 : 1151 : && INTVAL (XEXP (op, 1)) > 0
791 : 2302 : && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (int_op_mode)
792 : 1151 : && ! mode_dependent_address_p (XEXP (XEXP (op, 0), 0),
793 : 1151 : MEM_ADDR_SPACE (XEXP (op, 0)))
794 : 1151 : && ! MEM_VOLATILE_P (XEXP (op, 0))
795 : 17429769 : && (GET_MODE_SIZE (int_mode) >= UNITS_PER_WORD
796 : : || WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN))
797 : : {
798 : 1118 : poly_int64 byte = subreg_lowpart_offset (int_mode, int_op_mode);
799 : 1118 : int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
800 : 1118 : 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 : 17428651 : if ((GET_CODE (op) == ABS
809 : 17428651 : || GET_CODE (op) == NEG)
810 : 16913 : && (GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
811 : 16913 : || GET_CODE (XEXP (op, 0)) == ZERO_EXTEND)
812 : 19 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
813 : 3 : return simplify_gen_unary (GET_CODE (op), mode,
814 : 3 : XEXP (XEXP (op, 0), 0), mode);
815 : :
816 : : /* Simplifications of (truncate:A (subreg:B X 0)). */
817 : 17428648 : if (GET_CODE (op) == SUBREG
818 : 45386 : && is_a <scalar_int_mode> (mode, &int_mode)
819 : 44142 : && SCALAR_INT_MODE_P (op_mode)
820 : 44142 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &subreg_mode)
821 : 17472785 : && subreg_lowpart_p (op))
822 : : {
823 : : /* (truncate:A (subreg:B (truncate:C X) 0)) is (truncate:A X). */
824 : 44113 : 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 : 0 : 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 : 44113 : if (is_a <scalar_int_mode> (op_mode, &int_op_mode))
841 : : {
842 : 44113 : unsigned int int_op_prec = GET_MODE_PRECISION (int_op_mode);
843 : 44113 : unsigned int subreg_prec = GET_MODE_PRECISION (subreg_mode);
844 : 44113 : if (int_op_prec > subreg_prec)
845 : : {
846 : 1267 : if (int_mode == subreg_mode)
847 : : return SUBREG_REG (op);
848 : 60 : 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 : 42846 : else if (int_op_prec < subreg_prec
855 : 42846 : && GET_MODE_PRECISION (int_mode) < int_op_prec)
856 : 42846 : return simplify_gen_unary (TRUNCATE, int_mode,
857 : 42846 : SUBREG_REG (op), subreg_mode);
858 : : }
859 : : }
860 : :
861 : : /* (truncate:A (truncate:B X)) is (truncate:A X). */
862 : 17384568 : if (GET_CODE (op) == TRUNCATE)
863 : 1 : return simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0),
864 : 1 : 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 : 17384567 : if (GET_CODE (op) == IOR
869 : 75136 : && SCALAR_INT_MODE_P (mode)
870 : 75136 : && SCALAR_INT_MODE_P (op_mode)
871 : 75136 : && CONST_INT_P (XEXP (op, 1))
872 : 17392640 : && trunc_int_for_mode (INTVAL (XEXP (op, 1)), mode) == -1)
873 : 18 : 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 : 24180571 : simplify_context::simplify_unary_operation (rtx_code code, machine_mode mode,
883 : : rtx op, machine_mode op_mode)
884 : : {
885 : 24180571 : rtx trueop, tem;
886 : :
887 : 24180571 : trueop = avoid_constant_pool_reference (op);
888 : :
889 : 24180571 : tem = simplify_const_unary_operation (code, mode, trueop, op_mode);
890 : 24180571 : if (tem)
891 : : return tem;
892 : :
893 : 19471509 : 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 : 2916 : exact_int_to_float_conversion_p (const_rtx op)
901 : : {
902 : 2916 : 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 : 2916 : if (op0_mode == VOIDmode)
906 : : return false;
907 : 5830 : int out_bits = significand_size (GET_MODE_INNER (GET_MODE (op)));
908 : 2915 : int in_prec = GET_MODE_UNIT_PRECISION (op0_mode);
909 : 2915 : int in_bits = in_prec;
910 : 2915 : if (HWI_COMPUTABLE_MODE_P (op0_mode))
911 : : {
912 : 2861 : unsigned HOST_WIDE_INT nonzero = nonzero_bits (XEXP (op, 0), op0_mode);
913 : 2861 : if (GET_CODE (op) == FLOAT)
914 : 2713 : in_bits -= num_sign_bit_copies (XEXP (op, 0), op0_mode);
915 : 148 : else if (GET_CODE (op) == UNSIGNED_FLOAT)
916 : 148 : in_bits = wi::min_precision (wi::uhwi (nonzero, in_prec), UNSIGNED);
917 : : else
918 : 0 : gcc_unreachable ();
919 : 2861 : in_bits -= wi::ctz (wi::uhwi (nonzero, in_prec));
920 : : }
921 : 2915 : 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 : 19471509 : simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
928 : : rtx op)
929 : : {
930 : 19471509 : enum rtx_code reversed;
931 : 19471509 : rtx temp, elt, base, step;
932 : 19471509 : scalar_int_mode inner, int_mode, op_mode, op0_mode;
933 : :
934 : 19471509 : switch (code)
935 : : {
936 : 1497824 : case NOT:
937 : : /* (not (not X)) == X. */
938 : 1497824 : if (GET_CODE (op) == NOT)
939 : 1872 : 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 : 1495952 : if (COMPARISON_P (op)
944 : 17912 : && (mode == BImode || STORE_FLAG_VALUE == -1)
945 : 1495952 : && ((reversed = reversed_comparison_code (op, NULL)) != UNKNOWN))
946 : 0 : return simplify_gen_relational (reversed, mode, VOIDmode,
947 : 0 : XEXP (op, 0), XEXP (op, 1));
948 : :
949 : : /* (not (plus X -1)) can become (neg X). */
950 : 1495952 : if (GET_CODE (op) == PLUS
951 : 278895 : && XEXP (op, 1) == constm1_rtx)
952 : 6591 : return simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
953 : :
954 : : /* Similarly, (not (neg X)) is (plus X -1). Only do this for
955 : : modes that have CONSTM1_RTX, i.e. MODE_INT, MODE_PARTIAL_INT
956 : : and MODE_VECTOR_INT. */
957 : 1489361 : if (GET_CODE (op) == NEG && CONSTM1_RTX (mode))
958 : 63451 : return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
959 : 63451 : CONSTM1_RTX (mode));
960 : :
961 : : /* (not (xor X C)) for C constant is (xor X D) with D = ~C. */
962 : 1425910 : if (GET_CODE (op) == XOR
963 : 7120 : && CONST_INT_P (XEXP (op, 1))
964 : 1427370 : && (temp = simplify_unary_operation (NOT, mode,
965 : : XEXP (op, 1), mode)) != 0)
966 : 1460 : return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
967 : :
968 : : /* (not (plus X C)) for signbit C is (xor X D) with D = ~C. */
969 : 1424450 : if (GET_CODE (op) == PLUS
970 : 272304 : && CONST_INT_P (XEXP (op, 1))
971 : 159658 : && mode_signbit_p (mode, XEXP (op, 1))
972 : 1427215 : && (temp = simplify_unary_operation (NOT, mode,
973 : : XEXP (op, 1), mode)) != 0)
974 : 2765 : return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
975 : :
976 : :
977 : : /* (not (ashift 1 X)) is (rotate ~1 X). We used to do this for
978 : : operands other than 1, but that is not valid. We could do a
979 : : similar simplification for (not (lshiftrt C X)) where C is
980 : : just the sign bit, but this doesn't seem common enough to
981 : : bother with. */
982 : 1421685 : if (GET_CODE (op) == ASHIFT
983 : 25251 : && XEXP (op, 0) == const1_rtx)
984 : : {
985 : 895 : temp = simplify_gen_unary (NOT, mode, const1_rtx, mode);
986 : 895 : return simplify_gen_binary (ROTATE, mode, temp, XEXP (op, 1));
987 : : }
988 : :
989 : : /* (not (ashiftrt foo C)) where C is the number of bits in FOO
990 : : minus 1 is (ge foo (const_int 0)) if STORE_FLAG_VALUE is -1,
991 : : so we can perform the above simplification. */
992 : 1420790 : if (STORE_FLAG_VALUE == -1
993 : : && is_a <scalar_int_mode> (mode, &int_mode)
994 : : && GET_CODE (op) == ASHIFTRT
995 : : && CONST_INT_P (XEXP (op, 1))
996 : : && INTVAL (XEXP (op, 1)) == GET_MODE_PRECISION (int_mode) - 1)
997 : : return simplify_gen_relational (GE, int_mode, VOIDmode,
998 : : XEXP (op, 0), const0_rtx);
999 : :
1000 : :
1001 : 1420790 : if (partial_subreg_p (op)
1002 : 64745 : && subreg_lowpart_p (op)
1003 : 64549 : && GET_CODE (SUBREG_REG (op)) == ASHIFT
1004 : 1421136 : && XEXP (SUBREG_REG (op), 0) == const1_rtx)
1005 : : {
1006 : 33 : machine_mode inner_mode = GET_MODE (SUBREG_REG (op));
1007 : 33 : rtx x;
1008 : :
1009 : 33 : x = gen_rtx_ROTATE (inner_mode,
1010 : : simplify_gen_unary (NOT, inner_mode, const1_rtx,
1011 : : inner_mode),
1012 : : XEXP (SUBREG_REG (op), 1));
1013 : 33 : temp = rtl_hooks.gen_lowpart_no_emit (mode, x);
1014 : 33 : if (temp)
1015 : : return temp;
1016 : : }
1017 : :
1018 : : /* Apply De Morgan's laws to reduce number of patterns for machines
1019 : : with negating logical insns (and-not, nand, etc.). If result has
1020 : : only one NOT, put it first, since that is how the patterns are
1021 : : coded. */
1022 : 1420757 : if (GET_CODE (op) == IOR || GET_CODE (op) == AND)
1023 : : {
1024 : 7585 : rtx in1 = XEXP (op, 0), in2 = XEXP (op, 1);
1025 : 7585 : machine_mode op_mode;
1026 : :
1027 : 7585 : op_mode = GET_MODE (in1);
1028 : 7585 : in1 = simplify_gen_unary (NOT, op_mode, in1, op_mode);
1029 : :
1030 : 7585 : op_mode = GET_MODE (in2);
1031 : 7585 : if (op_mode == VOIDmode)
1032 : 3699 : op_mode = mode;
1033 : 7585 : in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode);
1034 : :
1035 : 7585 : if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT)
1036 : : std::swap (in1, in2);
1037 : :
1038 : 15170 : return gen_rtx_fmt_ee (GET_CODE (op) == IOR ? AND : IOR,
1039 : : mode, in1, in2);
1040 : : }
1041 : :
1042 : : /* (not (bswap x)) -> (bswap (not x)). */
1043 : 1413172 : if (GET_CODE (op) == BSWAP || GET_CODE (op) == BITREVERSE)
1044 : : {
1045 : 0 : rtx x = simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1046 : 0 : return simplify_gen_unary (GET_CODE (op), mode, x, mode);
1047 : : }
1048 : : break;
1049 : :
1050 : 1506905 : case NEG:
1051 : : /* (neg (neg X)) == X. */
1052 : 1506905 : if (GET_CODE (op) == NEG)
1053 : 5725 : return XEXP (op, 0);
1054 : :
1055 : : /* (neg (x ? (neg y) : y)) == !x ? (neg y) : y.
1056 : : If comparison is not reversible use
1057 : : x ? y : (neg y). */
1058 : 1501180 : if (GET_CODE (op) == IF_THEN_ELSE)
1059 : : {
1060 : 1489 : rtx cond = XEXP (op, 0);
1061 : 1489 : rtx true_rtx = XEXP (op, 1);
1062 : 1489 : rtx false_rtx = XEXP (op, 2);
1063 : :
1064 : 1489 : if ((GET_CODE (true_rtx) == NEG
1065 : 0 : && rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
1066 : 1489 : || (GET_CODE (false_rtx) == NEG
1067 : 0 : && rtx_equal_p (XEXP (false_rtx, 0), true_rtx)))
1068 : : {
1069 : 0 : if (reversed_comparison_code (cond, NULL) != UNKNOWN)
1070 : 0 : temp = reversed_comparison (cond, mode);
1071 : : else
1072 : : {
1073 : : temp = cond;
1074 : : std::swap (true_rtx, false_rtx);
1075 : : }
1076 : 0 : return simplify_gen_ternary (IF_THEN_ELSE, mode,
1077 : 0 : mode, temp, true_rtx, false_rtx);
1078 : : }
1079 : : }
1080 : :
1081 : : /* (neg (plus X 1)) can become (not X). */
1082 : 1501180 : if (GET_CODE (op) == PLUS
1083 : 117582 : && XEXP (op, 1) == const1_rtx)
1084 : 51112 : return simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1085 : :
1086 : : /* Similarly, (neg (not X)) is (plus X 1). */
1087 : 1450068 : if (GET_CODE (op) == NOT)
1088 : 431 : return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
1089 : 431 : CONST1_RTX (mode));
1090 : :
1091 : : /* (neg (minus X Y)) can become (minus Y X). This transformation
1092 : : isn't safe for modes with signed zeros, since if X and Y are
1093 : : both +0, (minus Y X) is the same as (minus X Y). If the
1094 : : rounding mode is towards +infinity (or -infinity) then the two
1095 : : expressions will be rounded differently. */
1096 : 1449637 : if (GET_CODE (op) == MINUS
1097 : 23697 : && !HONOR_SIGNED_ZEROS (mode)
1098 : 1471922 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1099 : 22285 : return simplify_gen_binary (MINUS, mode, XEXP (op, 1), XEXP (op, 0));
1100 : :
1101 : 1427352 : if (GET_CODE (op) == PLUS
1102 : 66470 : && !HONOR_SIGNED_ZEROS (mode)
1103 : 1493479 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1104 : : {
1105 : : /* (neg (plus A C)) is simplified to (minus -C A). */
1106 : 66127 : if (CONST_SCALAR_INT_P (XEXP (op, 1))
1107 : 4490 : || CONST_DOUBLE_AS_FLOAT_P (XEXP (op, 1)))
1108 : : {
1109 : 61638 : temp = simplify_unary_operation (NEG, mode, XEXP (op, 1), mode);
1110 : 61638 : if (temp)
1111 : 61638 : return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 0));
1112 : : }
1113 : :
1114 : : /* (neg (plus A B)) is canonicalized to (minus (neg A) B). */
1115 : 4489 : temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
1116 : 4489 : return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 1));
1117 : : }
1118 : :
1119 : : /* (neg (mult A B)) becomes (mult A (neg B)).
1120 : : This works even for floating-point values. */
1121 : 1361225 : if (GET_CODE (op) == MULT
1122 : 1361225 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1123 : : {
1124 : 13889 : temp = simplify_gen_unary (NEG, mode, XEXP (op, 1), mode);
1125 : 13889 : return simplify_gen_binary (MULT, mode, XEXP (op, 0), temp);
1126 : : }
1127 : :
1128 : : /* NEG commutes with ASHIFT since it is multiplication. Only do
1129 : : this if we can then eliminate the NEG (e.g., if the operand
1130 : : is a constant). */
1131 : 1347336 : if (GET_CODE (op) == ASHIFT)
1132 : : {
1133 : 54413 : temp = simplify_unary_operation (NEG, mode, XEXP (op, 0), mode);
1134 : 54413 : if (temp)
1135 : 8438 : return simplify_gen_binary (ASHIFT, mode, temp, XEXP (op, 1));
1136 : : }
1137 : :
1138 : : /* (neg (ashiftrt X C)) can be replaced by (lshiftrt X C) when
1139 : : C is equal to the width of MODE minus 1. */
1140 : 1338898 : if (GET_CODE (op) == ASHIFTRT
1141 : 25662 : && CONST_INT_P (XEXP (op, 1))
1142 : 1390158 : && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1143 : 411 : return simplify_gen_binary (LSHIFTRT, mode,
1144 : 411 : XEXP (op, 0), XEXP (op, 1));
1145 : :
1146 : : /* (neg (lshiftrt X C)) can be replaced by (ashiftrt X C) when
1147 : : C is equal to the width of MODE minus 1. */
1148 : 1338487 : if (GET_CODE (op) == LSHIFTRT
1149 : 5094 : && CONST_INT_P (XEXP (op, 1))
1150 : 1348469 : && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1151 : 2311 : return simplify_gen_binary (ASHIFTRT, mode,
1152 : 2311 : XEXP (op, 0), XEXP (op, 1));
1153 : :
1154 : : /* (neg (xor A 1)) is (plus A -1) if A is known to be either 0 or 1. */
1155 : 1336176 : if (GET_CODE (op) == XOR
1156 : 9009 : && XEXP (op, 1) == const1_rtx
1157 : 1336236 : && nonzero_bits (XEXP (op, 0), mode) == 1)
1158 : 38 : return plus_constant (mode, XEXP (op, 0), -1);
1159 : :
1160 : : /* (neg (lt x 0)) is (ashiftrt X C) if STORE_FLAG_VALUE is 1. */
1161 : : /* (neg (lt x 0)) is (lshiftrt X C) if STORE_FLAG_VALUE is -1. */
1162 : 1336138 : if (GET_CODE (op) == LT
1163 : 1220 : && XEXP (op, 1) == const0_rtx
1164 : 1336994 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op, 0)), &inner))
1165 : : {
1166 : 225 : int_mode = as_a <scalar_int_mode> (mode);
1167 : 225 : int isize = GET_MODE_PRECISION (inner);
1168 : 225 : if (STORE_FLAG_VALUE == 1)
1169 : : {
1170 : 225 : temp = simplify_gen_binary (ASHIFTRT, inner, XEXP (op, 0),
1171 : : gen_int_shift_amount (inner,
1172 : 225 : isize - 1));
1173 : 225 : if (int_mode == inner)
1174 : : return temp;
1175 : 124 : if (GET_MODE_PRECISION (int_mode) > isize)
1176 : 61 : return simplify_gen_unary (SIGN_EXTEND, int_mode, temp, inner);
1177 : 63 : return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1178 : : }
1179 : : else if (STORE_FLAG_VALUE == -1)
1180 : : {
1181 : : temp = simplify_gen_binary (LSHIFTRT, inner, XEXP (op, 0),
1182 : : gen_int_shift_amount (inner,
1183 : : isize - 1));
1184 : : if (int_mode == inner)
1185 : : return temp;
1186 : : if (GET_MODE_PRECISION (int_mode) > isize)
1187 : : return simplify_gen_unary (ZERO_EXTEND, int_mode, temp, inner);
1188 : : return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1189 : : }
1190 : : }
1191 : :
1192 : 1335913 : if (vec_series_p (op, &base, &step))
1193 : : {
1194 : : /* Only create a new series if we can simplify both parts. In other
1195 : : cases this isn't really a simplification, and it's not necessarily
1196 : : a win to replace a vector operation with a scalar operation. */
1197 : 288 : scalar_mode inner_mode = GET_MODE_INNER (mode);
1198 : 288 : base = simplify_unary_operation (NEG, inner_mode, base, inner_mode);
1199 : 288 : if (base)
1200 : : {
1201 : 288 : step = simplify_unary_operation (NEG, inner_mode,
1202 : : step, inner_mode);
1203 : 288 : if (step)
1204 : 288 : return gen_vec_series (mode, base, step);
1205 : : }
1206 : : }
1207 : : break;
1208 : :
1209 : 1376193 : case TRUNCATE:
1210 : : /* Don't optimize (lshiftrt (mult ...)) as it would interfere
1211 : : with the umulXi3_highpart patterns. */
1212 : 1376193 : if (GET_CODE (op) == LSHIFTRT
1213 : 16001 : && GET_CODE (XEXP (op, 0)) == MULT)
1214 : : break;
1215 : :
1216 : 1368475 : if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
1217 : : {
1218 : 12 : if (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
1219 : : {
1220 : 12 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1221 : 12 : if (temp)
1222 : : return temp;
1223 : : }
1224 : : /* We can't handle truncation to a partial integer mode here
1225 : : because we don't know the real bitsize of the partial
1226 : : integer mode. */
1227 : : break;
1228 : : }
1229 : :
1230 : 1368463 : if (GET_MODE (op) != VOIDmode)
1231 : : {
1232 : 1368463 : temp = simplify_truncation (mode, op, GET_MODE (op));
1233 : 1368463 : if (temp)
1234 : : return temp;
1235 : : }
1236 : :
1237 : : /* If we know that the value is already truncated, we can
1238 : : replace the TRUNCATE with a SUBREG. */
1239 : 1197484 : if (known_eq (GET_MODE_NUNITS (mode), 1)
1240 : 1197484 : && (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op))
1241 : 0 : || truncated_to_mode (mode, op)))
1242 : : {
1243 : 1187447 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1244 : 1187447 : if (temp)
1245 : : return temp;
1246 : : }
1247 : :
1248 : : /* A truncate of a comparison can be replaced with a subreg if
1249 : : STORE_FLAG_VALUE permits. This is like the previous test,
1250 : : but it works even if the comparison is done in a mode larger
1251 : : than HOST_BITS_PER_WIDE_INT. */
1252 : 10220 : if (HWI_COMPUTABLE_MODE_P (mode)
1253 : 183 : && COMPARISON_P (op)
1254 : 0 : && (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0
1255 : 10220 : && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
1256 : : {
1257 : 0 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1258 : 0 : if (temp)
1259 : : return temp;
1260 : : }
1261 : :
1262 : : /* A truncate of a memory is just loading the low part of the memory
1263 : : if we are not changing the meaning of the address. */
1264 : 10220 : if (GET_CODE (op) == MEM
1265 : 275 : && !VECTOR_MODE_P (mode)
1266 : 181 : && !MEM_VOLATILE_P (op)
1267 : 10401 : && !mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op)))
1268 : : {
1269 : 181 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1270 : 181 : if (temp)
1271 : : return temp;
1272 : : }
1273 : :
1274 : : /* Check for useless truncation. */
1275 : 10220 : if (GET_MODE (op) == mode)
1276 : : return op;
1277 : : break;
1278 : :
1279 : 194113 : case FLOAT_TRUNCATE:
1280 : : /* Check for useless truncation. */
1281 : 194113 : if (GET_MODE (op) == mode)
1282 : : return op;
1283 : :
1284 : 194113 : if (DECIMAL_FLOAT_MODE_P (mode))
1285 : : break;
1286 : :
1287 : : /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF. */
1288 : 193953 : if (GET_CODE (op) == FLOAT_EXTEND
1289 : 6 : && GET_MODE (XEXP (op, 0)) == mode)
1290 : : return XEXP (op, 0);
1291 : :
1292 : : /* (float_truncate:SF (float_truncate:DF foo:XF))
1293 : : = (float_truncate:SF foo:XF).
1294 : : This may eliminate double rounding, so it is unsafe.
1295 : :
1296 : : (float_truncate:SF (float_extend:XF foo:DF))
1297 : : = (float_truncate:SF foo:DF).
1298 : :
1299 : : (float_truncate:DF (float_extend:XF foo:SF))
1300 : : = (float_extend:DF foo:SF). */
1301 : 193949 : if ((GET_CODE (op) == FLOAT_TRUNCATE
1302 : 132 : && flag_unsafe_math_optimizations)
1303 : 193945 : || GET_CODE (op) == FLOAT_EXTEND)
1304 : 12 : return simplify_gen_unary (GET_MODE_UNIT_SIZE (GET_MODE (XEXP (op, 0)))
1305 : 6 : > GET_MODE_UNIT_SIZE (mode)
1306 : : ? FLOAT_TRUNCATE : FLOAT_EXTEND,
1307 : : mode,
1308 : 12 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1309 : :
1310 : : /* (float_truncate (float x)) is (float x) */
1311 : 193943 : if ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1312 : 193943 : && (flag_unsafe_math_optimizations
1313 : 1563 : || exact_int_to_float_conversion_p (op)))
1314 : 1562 : return simplify_gen_unary (GET_CODE (op), mode,
1315 : : XEXP (op, 0),
1316 : 1562 : GET_MODE (XEXP (op, 0)));
1317 : :
1318 : : /* (float_truncate:SF (OP:DF (float_extend:DF foo:sf))) is
1319 : : (OP:SF foo:SF) if OP is NEG or ABS. */
1320 : 192381 : if ((GET_CODE (op) == ABS
1321 : 192381 : || GET_CODE (op) == NEG)
1322 : 190 : && GET_CODE (XEXP (op, 0)) == FLOAT_EXTEND
1323 : 36 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
1324 : 36 : return simplify_gen_unary (GET_CODE (op), mode,
1325 : 36 : XEXP (XEXP (op, 0), 0), mode);
1326 : :
1327 : : /* (float_truncate:SF (subreg:DF (float_truncate:SF X) 0))
1328 : : is (float_truncate:SF x). */
1329 : 192345 : if (GET_CODE (op) == SUBREG
1330 : 296 : && subreg_lowpart_p (op)
1331 : 192637 : && GET_CODE (SUBREG_REG (op)) == FLOAT_TRUNCATE)
1332 : : return SUBREG_REG (op);
1333 : : break;
1334 : :
1335 : 631960 : case FLOAT_EXTEND:
1336 : : /* Check for useless extension. */
1337 : 631960 : if (GET_MODE (op) == mode)
1338 : : return op;
1339 : :
1340 : 631960 : if (DECIMAL_FLOAT_MODE_P (mode))
1341 : : break;
1342 : :
1343 : : /* (float_extend (float_extend x)) is (float_extend x)
1344 : :
1345 : : (float_extend (float x)) is (float x) assuming that double
1346 : : rounding can't happen.
1347 : : */
1348 : 631864 : if (GET_CODE (op) == FLOAT_EXTEND
1349 : 631864 : || ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1350 : 1353 : && exact_int_to_float_conversion_p (op)))
1351 : 550 : return simplify_gen_unary (GET_CODE (op), mode,
1352 : : XEXP (op, 0),
1353 : 550 : GET_MODE (XEXP (op, 0)));
1354 : :
1355 : : break;
1356 : :
1357 : 239845 : case ABS:
1358 : : /* (abs (neg <foo>)) -> (abs <foo>) */
1359 : 239845 : if (GET_CODE (op) == NEG)
1360 : 34 : return simplify_gen_unary (ABS, mode, XEXP (op, 0),
1361 : 34 : GET_MODE (XEXP (op, 0)));
1362 : :
1363 : : /* If the mode of the operand is VOIDmode (i.e. if it is ASM_OPERANDS),
1364 : : do nothing. */
1365 : 239811 : if (GET_MODE (op) == VOIDmode)
1366 : : break;
1367 : :
1368 : : /* If operand is something known to be positive, ignore the ABS. */
1369 : 239811 : if (val_signbit_known_clear_p (GET_MODE (op),
1370 : : nonzero_bits (op, GET_MODE (op))))
1371 : : return op;
1372 : :
1373 : : /* Using nonzero_bits doesn't (currently) work for modes wider than
1374 : : HOST_WIDE_INT, so the following transformations help simplify
1375 : : ABS for TImode and wider. */
1376 : 239649 : switch (GET_CODE (op))
1377 : : {
1378 : : case ABS:
1379 : : case CLRSB:
1380 : : case FFS:
1381 : : case PARITY:
1382 : : case POPCOUNT:
1383 : : case SS_ABS:
1384 : : return op;
1385 : :
1386 : 0 : case LSHIFTRT:
1387 : 0 : if (CONST_INT_P (XEXP (op, 1))
1388 : 0 : && INTVAL (XEXP (op, 1)) > 0
1389 : 239649 : && is_a <scalar_int_mode> (mode, &int_mode)
1390 : 0 : && INTVAL (XEXP (op, 1)) < GET_MODE_PRECISION (int_mode))
1391 : : return op;
1392 : : break;
1393 : :
1394 : : default:
1395 : : break;
1396 : : }
1397 : :
1398 : : /* If operand is known to be only -1 or 0, convert ABS to NEG. */
1399 : 239649 : if (is_a <scalar_int_mode> (mode, &int_mode)
1400 : 29447 : && (num_sign_bit_copies (op, int_mode)
1401 : 29447 : == GET_MODE_PRECISION (int_mode)))
1402 : 2 : return gen_rtx_NEG (int_mode, op);
1403 : :
1404 : : break;
1405 : :
1406 : 0 : case FFS:
1407 : : /* (ffs (*_extend <X>)) = (*_extend (ffs <X>)). */
1408 : 0 : if (GET_CODE (op) == SIGN_EXTEND
1409 : 0 : || GET_CODE (op) == ZERO_EXTEND)
1410 : : {
1411 : 0 : temp = simplify_gen_unary (FFS, GET_MODE (XEXP (op, 0)),
1412 : 0 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1413 : 0 : return simplify_gen_unary (GET_CODE (op), mode, temp,
1414 : 0 : GET_MODE (temp));
1415 : : }
1416 : : break;
1417 : :
1418 : 3134 : case POPCOUNT:
1419 : 3134 : switch (GET_CODE (op))
1420 : : {
1421 : 0 : case BSWAP:
1422 : 0 : case BITREVERSE:
1423 : : /* (popcount (bswap <X>)) = (popcount <X>). */
1424 : 0 : return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1425 : 0 : GET_MODE (XEXP (op, 0)));
1426 : :
1427 : 15 : case ZERO_EXTEND:
1428 : : /* (popcount (zero_extend <X>)) = (zero_extend (popcount <X>)). */
1429 : 30 : temp = simplify_gen_unary (POPCOUNT, GET_MODE (XEXP (op, 0)),
1430 : 15 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1431 : 15 : return simplify_gen_unary (ZERO_EXTEND, mode, temp,
1432 : 15 : GET_MODE (temp));
1433 : :
1434 : 0 : case ROTATE:
1435 : 0 : case ROTATERT:
1436 : : /* Rotations don't affect popcount. */
1437 : 0 : if (!side_effects_p (XEXP (op, 1)))
1438 : 0 : return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1439 : 0 : GET_MODE (XEXP (op, 0)));
1440 : : break;
1441 : :
1442 : : default:
1443 : : break;
1444 : : }
1445 : : break;
1446 : :
1447 : 0 : case PARITY:
1448 : 0 : switch (GET_CODE (op))
1449 : : {
1450 : 0 : case NOT:
1451 : 0 : case BSWAP:
1452 : 0 : case BITREVERSE:
1453 : 0 : return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1454 : 0 : GET_MODE (XEXP (op, 0)));
1455 : :
1456 : 0 : case ZERO_EXTEND:
1457 : 0 : case SIGN_EXTEND:
1458 : 0 : temp = simplify_gen_unary (PARITY, GET_MODE (XEXP (op, 0)),
1459 : 0 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1460 : 0 : return simplify_gen_unary (GET_CODE (op), mode, temp,
1461 : 0 : GET_MODE (temp));
1462 : :
1463 : 0 : case ROTATE:
1464 : 0 : case ROTATERT:
1465 : : /* Rotations don't affect parity. */
1466 : 0 : if (!side_effects_p (XEXP (op, 1)))
1467 : 0 : return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1468 : 0 : GET_MODE (XEXP (op, 0)));
1469 : : break;
1470 : :
1471 : : case PARITY:
1472 : : /* (parity (parity x)) -> parity (x). */
1473 : : return op;
1474 : :
1475 : : default:
1476 : : break;
1477 : : }
1478 : : break;
1479 : :
1480 : 13489 : case BSWAP:
1481 : : /* (bswap (bswap x)) -> x. */
1482 : 13489 : if (GET_CODE (op) == BSWAP)
1483 : 90 : return XEXP (op, 0);
1484 : : break;
1485 : :
1486 : 0 : case BITREVERSE:
1487 : : /* (bitreverse (bitreverse x)) -> x. */
1488 : 0 : if (GET_CODE (op) == BITREVERSE)
1489 : 0 : return XEXP (op, 0);
1490 : : break;
1491 : :
1492 : 828797 : case FLOAT:
1493 : : /* (float (sign_extend <X>)) = (float <X>). */
1494 : 828797 : if (GET_CODE (op) == SIGN_EXTEND)
1495 : 7108 : return simplify_gen_unary (FLOAT, mode, XEXP (op, 0),
1496 : 7108 : GET_MODE (XEXP (op, 0)));
1497 : : break;
1498 : :
1499 : 3005132 : case SIGN_EXTEND:
1500 : : /* Check for useless extension. */
1501 : 3005132 : if (GET_MODE (op) == mode)
1502 : : return op;
1503 : :
1504 : : /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
1505 : : becomes just the MINUS if its mode is MODE. This allows
1506 : : folding switch statements on machines using casesi (such as
1507 : : the VAX). */
1508 : 3005092 : if (GET_CODE (op) == TRUNCATE
1509 : 40 : && GET_MODE (XEXP (op, 0)) == mode
1510 : 40 : && GET_CODE (XEXP (op, 0)) == MINUS
1511 : 0 : && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
1512 : 0 : && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
1513 : : return XEXP (op, 0);
1514 : :
1515 : : /* Extending a widening multiplication should be canonicalized to
1516 : : a wider widening multiplication. */
1517 : 3005092 : if (GET_CODE (op) == MULT)
1518 : : {
1519 : 67194 : rtx lhs = XEXP (op, 0);
1520 : 67194 : rtx rhs = XEXP (op, 1);
1521 : 67194 : enum rtx_code lcode = GET_CODE (lhs);
1522 : 67194 : enum rtx_code rcode = GET_CODE (rhs);
1523 : :
1524 : : /* Widening multiplies usually extend both operands, but sometimes
1525 : : they use a shift to extract a portion of a register. */
1526 : 67194 : if ((lcode == SIGN_EXTEND
1527 : 67052 : || (lcode == ASHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1528 : 750 : && (rcode == SIGN_EXTEND
1529 : 706 : || (rcode == ASHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1530 : : {
1531 : 165 : machine_mode lmode = GET_MODE (lhs);
1532 : 165 : machine_mode rmode = GET_MODE (rhs);
1533 : 165 : int bits;
1534 : :
1535 : 165 : if (lcode == ASHIFTRT)
1536 : : /* Number of bits not shifted off the end. */
1537 : 125 : bits = (GET_MODE_UNIT_PRECISION (lmode)
1538 : 125 : - INTVAL (XEXP (lhs, 1)));
1539 : : else /* lcode == SIGN_EXTEND */
1540 : : /* Size of inner mode. */
1541 : 80 : bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1542 : :
1543 : 165 : if (rcode == ASHIFTRT)
1544 : 121 : bits += (GET_MODE_UNIT_PRECISION (rmode)
1545 : 121 : - INTVAL (XEXP (rhs, 1)));
1546 : : else /* rcode == SIGN_EXTEND */
1547 : 88 : bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1548 : :
1549 : : /* We can only widen multiplies if the result is mathematiclly
1550 : : equivalent. I.e. if overflow was impossible. */
1551 : 330 : if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1552 : 108 : return simplify_gen_binary
1553 : 108 : (MULT, mode,
1554 : : simplify_gen_unary (SIGN_EXTEND, mode, lhs, lmode),
1555 : 108 : simplify_gen_unary (SIGN_EXTEND, mode, rhs, rmode));
1556 : : }
1557 : : }
1558 : :
1559 : : /* Check for a sign extension of a subreg of a promoted
1560 : : variable, where the promotion is sign-extended, and the
1561 : : target mode is the same as the variable's promotion. */
1562 : 3004984 : if (GET_CODE (op) == SUBREG
1563 : 248358 : && SUBREG_PROMOTED_VAR_P (op)
1564 : 3010238 : && SUBREG_PROMOTED_SIGNED_P (op))
1565 : : {
1566 : 0 : rtx subreg = SUBREG_REG (op);
1567 : 0 : machine_mode subreg_mode = GET_MODE (subreg);
1568 : 0 : if (!paradoxical_subreg_p (mode, subreg_mode))
1569 : : {
1570 : 0 : temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
1571 : 0 : if (temp)
1572 : : {
1573 : : /* Preserve SUBREG_PROMOTED_VAR_P. */
1574 : 0 : if (partial_subreg_p (temp))
1575 : : {
1576 : 0 : SUBREG_PROMOTED_VAR_P (temp) = 1;
1577 : 0 : SUBREG_PROMOTED_SET (temp, SRP_SIGNED);
1578 : : }
1579 : 0 : return temp;
1580 : : }
1581 : : }
1582 : : else
1583 : : /* Sign-extending a sign-extended subreg. */
1584 : 0 : return simplify_gen_unary (SIGN_EXTEND, mode,
1585 : 0 : subreg, subreg_mode);
1586 : : }
1587 : :
1588 : : /* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
1589 : : (sign_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1590 : 3004984 : if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND)
1591 : : {
1592 : 29403 : gcc_assert (GET_MODE_UNIT_PRECISION (mode)
1593 : : > GET_MODE_UNIT_PRECISION (GET_MODE (op)));
1594 : 9801 : return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0),
1595 : 9801 : GET_MODE (XEXP (op, 0)));
1596 : : }
1597 : :
1598 : : /* (sign_extend:M (ashiftrt:N (ashift <X> (const_int I)) (const_int I)))
1599 : : is (sign_extend:M (subreg:O <X>)) if there is mode with
1600 : : GET_MODE_BITSIZE (N) - I bits.
1601 : : (sign_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1602 : : is similarly (zero_extend:M (subreg:O <X>)). */
1603 : 2995183 : if ((GET_CODE (op) == ASHIFTRT || GET_CODE (op) == LSHIFTRT)
1604 : 72553 : && GET_CODE (XEXP (op, 0)) == ASHIFT
1605 : 2998284 : && is_a <scalar_int_mode> (mode, &int_mode)
1606 : 5675 : && CONST_INT_P (XEXP (op, 1))
1607 : 5675 : && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1608 : 3000734 : && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1609 : 5551 : GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1610 : : {
1611 : 5551 : scalar_int_mode tmode;
1612 : 5551 : gcc_assert (GET_MODE_PRECISION (int_mode)
1613 : : > GET_MODE_PRECISION (op_mode));
1614 : 5551 : if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1615 : 8528 : - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1616 : : {
1617 : 2574 : rtx inner =
1618 : 2574 : rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1619 : 2574 : if (inner)
1620 : 2574 : return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
1621 : : ? SIGN_EXTEND : ZERO_EXTEND,
1622 : 2574 : int_mode, inner, tmode);
1623 : : }
1624 : : }
1625 : :
1626 : : /* (sign_extend:M (lshiftrt:N <X> (const_int I))) is better as
1627 : : (zero_extend:M (lshiftrt:N <X> (const_int I))) if I is not 0. */
1628 : 2992609 : if (GET_CODE (op) == LSHIFTRT
1629 : 346 : && CONST_INT_P (XEXP (op, 1))
1630 : 346 : && XEXP (op, 1) != const0_rtx)
1631 : 346 : return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1632 : :
1633 : : /* (sign_extend:M (truncate:N (lshiftrt:O <X> (const_int I)))) where
1634 : : I is GET_MODE_PRECISION(O) - GET_MODE_PRECISION(N), simplifies to
1635 : : (ashiftrt:M <X> (const_int I)) if modes M and O are the same, and
1636 : : (truncate:M (ashiftrt:O <X> (const_int I))) if M is narrower than
1637 : : O, and (sign_extend:M (ashiftrt:O <X> (const_int I))) if M is
1638 : : wider than O. */
1639 : 2992263 : if (GET_CODE (op) == TRUNCATE
1640 : 40 : && GET_CODE (XEXP (op, 0)) == LSHIFTRT
1641 : 0 : && CONST_INT_P (XEXP (XEXP (op, 0), 1)))
1642 : : {
1643 : 0 : scalar_int_mode m_mode, n_mode, o_mode;
1644 : 0 : rtx old_shift = XEXP (op, 0);
1645 : 0 : if (is_a <scalar_int_mode> (mode, &m_mode)
1646 : 0 : && is_a <scalar_int_mode> (GET_MODE (op), &n_mode)
1647 : 0 : && is_a <scalar_int_mode> (GET_MODE (old_shift), &o_mode)
1648 : 0 : && GET_MODE_PRECISION (o_mode) - GET_MODE_PRECISION (n_mode)
1649 : 0 : == INTVAL (XEXP (old_shift, 1)))
1650 : : {
1651 : 0 : rtx new_shift = simplify_gen_binary (ASHIFTRT,
1652 : : GET_MODE (old_shift),
1653 : : XEXP (old_shift, 0),
1654 : : XEXP (old_shift, 1));
1655 : 0 : if (GET_MODE_PRECISION (m_mode) > GET_MODE_PRECISION (o_mode))
1656 : 0 : return simplify_gen_unary (SIGN_EXTEND, mode, new_shift,
1657 : 0 : GET_MODE (new_shift));
1658 : 0 : if (mode != GET_MODE (new_shift))
1659 : 0 : return simplify_gen_unary (TRUNCATE, mode, new_shift,
1660 : 0 : GET_MODE (new_shift));
1661 : : return new_shift;
1662 : : }
1663 : : }
1664 : :
1665 : : /* We can canonicalize SIGN_EXTEND (op) as ZERO_EXTEND (op) when
1666 : : we know the sign bit of OP must be clear. */
1667 : 2992263 : if (val_signbit_known_clear_p (GET_MODE (op),
1668 : 2992263 : nonzero_bits (op, GET_MODE (op))))
1669 : 44339 : return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1670 : :
1671 : : /* (sign_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1672 : 2947924 : if (GET_CODE (op) == SUBREG
1673 : 248071 : && subreg_lowpart_p (op)
1674 : 248003 : && GET_MODE (SUBREG_REG (op)) == mode
1675 : 3139174 : && is_a <scalar_int_mode> (mode, &int_mode)
1676 : 197444 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1677 : 197444 : && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
1678 : 195673 : && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
1679 : 3143597 : && (nonzero_bits (SUBREG_REG (op), mode)
1680 : 195673 : & ~(GET_MODE_MASK (op_mode) >> 1)) == 0)
1681 : 6194 : return SUBREG_REG (op);
1682 : :
1683 : : #if defined(POINTERS_EXTEND_UNSIGNED)
1684 : : /* As we do not know which address space the pointer is referring to,
1685 : : we can do this only if the target does not support different pointer
1686 : : or address modes depending on the address space. */
1687 : 2941730 : if (target_default_pointer_address_modes_p ()
1688 : : && ! POINTERS_EXTEND_UNSIGNED
1689 : : && mode == Pmode && GET_MODE (op) == ptr_mode
1690 : : && (CONSTANT_P (op)
1691 : : || (GET_CODE (op) == SUBREG
1692 : : && REG_P (SUBREG_REG (op))
1693 : : && REG_POINTER (SUBREG_REG (op))
1694 : : && GET_MODE (SUBREG_REG (op)) == Pmode))
1695 : : && !targetm.have_ptr_extend ())
1696 : : {
1697 : : temp
1698 : : = convert_memory_address_addr_space_1 (Pmode, op,
1699 : : ADDR_SPACE_GENERIC, false,
1700 : : true);
1701 : : if (temp)
1702 : : return temp;
1703 : : }
1704 : : #endif
1705 : : break;
1706 : :
1707 : 9361018 : case ZERO_EXTEND:
1708 : : /* Check for useless extension. */
1709 : 9361018 : if (GET_MODE (op) == mode)
1710 : : return op;
1711 : :
1712 : : /* Check for a zero extension of a subreg of a promoted
1713 : : variable, where the promotion is zero-extended, and the
1714 : : target mode is the same as the variable's promotion. */
1715 : 9360978 : if (GET_CODE (op) == SUBREG
1716 : 1480739 : && SUBREG_PROMOTED_VAR_P (op)
1717 : 9361857 : && SUBREG_PROMOTED_UNSIGNED_P (op))
1718 : : {
1719 : 879 : rtx subreg = SUBREG_REG (op);
1720 : 879 : machine_mode subreg_mode = GET_MODE (subreg);
1721 : 879 : if (!paradoxical_subreg_p (mode, subreg_mode))
1722 : : {
1723 : 665 : temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
1724 : 665 : if (temp)
1725 : : {
1726 : : /* Preserve SUBREG_PROMOTED_VAR_P. */
1727 : 665 : if (partial_subreg_p (temp))
1728 : : {
1729 : 129 : SUBREG_PROMOTED_VAR_P (temp) = 1;
1730 : 129 : SUBREG_PROMOTED_SET (temp, SRP_UNSIGNED);
1731 : : }
1732 : 665 : return temp;
1733 : : }
1734 : : }
1735 : : else
1736 : : /* Zero-extending a zero-extended subreg. */
1737 : 214 : return simplify_gen_unary (ZERO_EXTEND, mode,
1738 : 214 : subreg, subreg_mode);
1739 : : }
1740 : :
1741 : : /* Extending a widening multiplication should be canonicalized to
1742 : : a wider widening multiplication. */
1743 : 9360099 : if (GET_CODE (op) == MULT)
1744 : : {
1745 : 161758 : rtx lhs = XEXP (op, 0);
1746 : 161758 : rtx rhs = XEXP (op, 1);
1747 : 161758 : enum rtx_code lcode = GET_CODE (lhs);
1748 : 161758 : enum rtx_code rcode = GET_CODE (rhs);
1749 : :
1750 : : /* Widening multiplies usually extend both operands, but sometimes
1751 : : they use a shift to extract a portion of a register. */
1752 : 161758 : if ((lcode == ZERO_EXTEND
1753 : 161148 : || (lcode == LSHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1754 : 674 : && (rcode == ZERO_EXTEND
1755 : 636 : || (rcode == LSHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1756 : : {
1757 : 38 : machine_mode lmode = GET_MODE (lhs);
1758 : 38 : machine_mode rmode = GET_MODE (rhs);
1759 : 38 : int bits;
1760 : :
1761 : 38 : if (lcode == LSHIFTRT)
1762 : : /* Number of bits not shifted off the end. */
1763 : 0 : bits = (GET_MODE_UNIT_PRECISION (lmode)
1764 : 0 : - INTVAL (XEXP (lhs, 1)));
1765 : : else /* lcode == ZERO_EXTEND */
1766 : : /* Size of inner mode. */
1767 : 76 : bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1768 : :
1769 : 38 : if (rcode == LSHIFTRT)
1770 : 0 : bits += (GET_MODE_UNIT_PRECISION (rmode)
1771 : 0 : - INTVAL (XEXP (rhs, 1)));
1772 : : else /* rcode == ZERO_EXTEND */
1773 : 76 : bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1774 : :
1775 : : /* We can only widen multiplies if the result is mathematiclly
1776 : : equivalent. I.e. if overflow was impossible. */
1777 : 76 : if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1778 : 38 : return simplify_gen_binary
1779 : 38 : (MULT, mode,
1780 : : simplify_gen_unary (ZERO_EXTEND, mode, lhs, lmode),
1781 : 38 : simplify_gen_unary (ZERO_EXTEND, mode, rhs, rmode));
1782 : : }
1783 : : }
1784 : :
1785 : : /* (zero_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1786 : 9360061 : if (GET_CODE (op) == ZERO_EXTEND)
1787 : 12508 : return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0),
1788 : 12508 : GET_MODE (XEXP (op, 0)));
1789 : :
1790 : : /* (zero_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1791 : : is (zero_extend:M (subreg:O <X>)) if there is mode with
1792 : : GET_MODE_PRECISION (N) - I bits. */
1793 : 9347553 : if (GET_CODE (op) == LSHIFTRT
1794 : 45434 : && GET_CODE (XEXP (op, 0)) == ASHIFT
1795 : 9347558 : && is_a <scalar_int_mode> (mode, &int_mode)
1796 : 5 : && CONST_INT_P (XEXP (op, 1))
1797 : 0 : && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1798 : 9347553 : && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1799 : 0 : GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1800 : : {
1801 : 0 : scalar_int_mode tmode;
1802 : 0 : if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1803 : 0 : - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1804 : : {
1805 : 0 : rtx inner =
1806 : 0 : rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1807 : 0 : if (inner)
1808 : 0 : return simplify_gen_unary (ZERO_EXTEND, int_mode,
1809 : 0 : inner, tmode);
1810 : : }
1811 : : }
1812 : :
1813 : : /* (zero_extend:M (subreg:N <X:O>)) is <X:O> (for M == O) or
1814 : : (zero_extend:M <X:O>), if X doesn't have any non-zero bits outside
1815 : : of mode N. E.g.
1816 : : (zero_extend:SI (subreg:QI (and:SI (reg:SI) (const_int 63)) 0)) is
1817 : : (and:SI (reg:SI) (const_int 63)). */
1818 : 9347553 : if (partial_subreg_p (op)
1819 : 10781968 : && is_a <scalar_int_mode> (mode, &int_mode)
1820 : 1461747 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &op0_mode)
1821 : 1460888 : && GET_MODE_PRECISION (op0_mode) <= HOST_BITS_PER_WIDE_INT
1822 : 1111486 : && GET_MODE_PRECISION (int_mode) >= GET_MODE_PRECISION (op0_mode)
1823 : 1053634 : && subreg_lowpart_p (op)
1824 : 10099518 : && (nonzero_bits (SUBREG_REG (op), op0_mode)
1825 : 751965 : & ~GET_MODE_MASK (GET_MODE (op))) == 0)
1826 : : {
1827 : 27332 : if (GET_MODE_PRECISION (int_mode) == GET_MODE_PRECISION (op0_mode))
1828 : 17959 : return SUBREG_REG (op);
1829 : 9373 : return simplify_gen_unary (ZERO_EXTEND, int_mode, SUBREG_REG (op),
1830 : 9373 : op0_mode);
1831 : : }
1832 : :
1833 : : /* (zero_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1834 : 9320221 : if (GET_CODE (op) == SUBREG
1835 : 1452528 : && subreg_lowpart_p (op)
1836 : 870173 : && GET_MODE (SUBREG_REG (op)) == mode
1837 : 10062386 : && is_a <scalar_int_mode> (mode, &int_mode)
1838 : 742165 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1839 : 742165 : && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
1840 : 674213 : && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
1841 : 9994434 : && (nonzero_bits (SUBREG_REG (op), mode)
1842 : 674213 : & ~GET_MODE_MASK (op_mode)) == 0)
1843 : 0 : return SUBREG_REG (op);
1844 : :
1845 : : #if defined(POINTERS_EXTEND_UNSIGNED)
1846 : : /* As we do not know which address space the pointer is referring to,
1847 : : we can do this only if the target does not support different pointer
1848 : : or address modes depending on the address space. */
1849 : 9320221 : if (target_default_pointer_address_modes_p ()
1850 : : && POINTERS_EXTEND_UNSIGNED > 0
1851 : 9320221 : && mode == Pmode && GET_MODE (op) == ptr_mode
1852 : 562 : && (CONSTANT_P (op)
1853 : 547 : || (GET_CODE (op) == SUBREG
1854 : 0 : && REG_P (SUBREG_REG (op))
1855 : 0 : && REG_POINTER (SUBREG_REG (op))
1856 : 0 : && GET_MODE (SUBREG_REG (op)) == Pmode))
1857 : 9320236 : && !targetm.have_ptr_extend ())
1858 : : {
1859 : 15 : temp
1860 : 15 : = convert_memory_address_addr_space_1 (Pmode, op,
1861 : : ADDR_SPACE_GENERIC, false,
1862 : : true);
1863 : 15 : if (temp)
1864 : : return temp;
1865 : : }
1866 : : #endif
1867 : : break;
1868 : :
1869 : : default:
1870 : : break;
1871 : : }
1872 : :
1873 : 16530003 : if (VECTOR_MODE_P (mode)
1874 : 1213536 : && vec_duplicate_p (op, &elt)
1875 : 17747524 : && code != VEC_DUPLICATE)
1876 : : {
1877 : 3982 : if (code == SIGN_EXTEND || code == ZERO_EXTEND)
1878 : : /* Enforce a canonical order of VEC_DUPLICATE wrt other unary
1879 : : operations by promoting VEC_DUPLICATE to the root of the expression
1880 : : (as far as possible). */
1881 : 2938 : temp = simplify_gen_unary (code, GET_MODE_INNER (mode),
1882 : 5876 : elt, GET_MODE_INNER (GET_MODE (op)));
1883 : : else
1884 : : /* Try applying the operator to ELT and see if that simplifies.
1885 : : We can duplicate the result if so.
1886 : :
1887 : : The reason we traditionally haven't used simplify_gen_unary
1888 : : for these codes is that it didn't necessarily seem to be a
1889 : : win to convert things like:
1890 : :
1891 : : (neg:V (vec_duplicate:V (reg:S R)))
1892 : :
1893 : : to:
1894 : :
1895 : : (vec_duplicate:V (neg:S (reg:S R)))
1896 : :
1897 : : The first might be done entirely in vector registers while the
1898 : : second might need a move between register files.
1899 : :
1900 : : However, there also cases where promoting the vec_duplicate is
1901 : : more efficient, and there is definite value in having a canonical
1902 : : form when matching instruction patterns. We should consider
1903 : : extending the simplify_gen_unary code above to more cases. */
1904 : 1044 : temp = simplify_unary_operation (code, GET_MODE_INNER (mode),
1905 : 2088 : elt, GET_MODE_INNER (GET_MODE (op)));
1906 : 3982 : if (temp)
1907 : 3438 : return gen_vec_duplicate (mode, temp);
1908 : : }
1909 : :
1910 : : return 0;
1911 : : }
1912 : :
1913 : : /* Try to compute the value of a unary operation CODE whose output mode is to
1914 : : be MODE with input operand OP whose mode was originally OP_MODE.
1915 : : Return zero if the value cannot be computed. */
1916 : : rtx
1917 : 24180985 : simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
1918 : : rtx op, machine_mode op_mode)
1919 : : {
1920 : 24180985 : scalar_int_mode result_mode;
1921 : :
1922 : 24180985 : if (code == VEC_DUPLICATE)
1923 : : {
1924 : 1578008 : gcc_assert (VECTOR_MODE_P (mode));
1925 : 1578008 : if (GET_MODE (op) != VOIDmode)
1926 : : {
1927 : 479339 : if (!VECTOR_MODE_P (GET_MODE (op)))
1928 : 945602 : gcc_assert (GET_MODE_INNER (mode) == GET_MODE (op));
1929 : : else
1930 : 19614 : gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER
1931 : : (GET_MODE (op)));
1932 : : }
1933 : 1578008 : if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op))
1934 : 1127625 : return gen_const_vec_duplicate (mode, op);
1935 : 450383 : if (GET_CODE (op) == CONST_VECTOR
1936 : 450383 : && (CONST_VECTOR_DUPLICATE_P (op)
1937 : 451105 : || CONST_VECTOR_NUNITS (op).is_constant ()))
1938 : : {
1939 : 724 : unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op)
1940 : 724 : ? CONST_VECTOR_NPATTERNS (op)
1941 : 1446 : : CONST_VECTOR_NUNITS (op).to_constant ());
1942 : 1448 : gcc_assert (multiple_p (GET_MODE_NUNITS (mode), npatterns));
1943 : 724 : rtx_vector_builder builder (mode, npatterns, 1);
1944 : 2987 : for (unsigned i = 0; i < npatterns; i++)
1945 : 2263 : builder.quick_push (CONST_VECTOR_ELT (op, i));
1946 : 724 : return builder.build ();
1947 : 724 : }
1948 : : }
1949 : :
1950 : 22038147 : if (VECTOR_MODE_P (mode)
1951 : 1264586 : && GET_CODE (op) == CONST_VECTOR
1952 : 23176167 : && known_eq (GET_MODE_NUNITS (mode), CONST_VECTOR_NUNITS (op)))
1953 : : {
1954 : 41177 : gcc_assert (GET_MODE (op) == op_mode);
1955 : :
1956 : 41177 : rtx_vector_builder builder;
1957 : 41177 : if (!builder.new_unary_operation (mode, op, false))
1958 : : return 0;
1959 : :
1960 : 41177 : unsigned int count = builder.encoded_nelts ();
1961 : 172254 : for (unsigned int i = 0; i < count; i++)
1962 : : {
1963 : 263292 : rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
1964 : : CONST_VECTOR_ELT (op, i),
1965 : 263292 : GET_MODE_INNER (op_mode));
1966 : 131646 : if (!x || !valid_for_const_vector_p (mode, x))
1967 : 569 : return 0;
1968 : 131077 : builder.quick_push (x);
1969 : : }
1970 : 40608 : return builder.build ();
1971 : 41177 : }
1972 : :
1973 : : /* The order of these tests is critical so that, for example, we don't
1974 : : check the wrong mode (input vs. output) for a conversion operation,
1975 : : such as FIX. At some point, this should be simplified. */
1976 : :
1977 : 23011459 : if (code == FLOAT && CONST_SCALAR_INT_P (op))
1978 : : {
1979 : 5983 : REAL_VALUE_TYPE d;
1980 : :
1981 : 5983 : if (op_mode == VOIDmode)
1982 : : {
1983 : : /* CONST_INT have VOIDmode as the mode. We assume that all
1984 : : the bits of the constant are significant, though, this is
1985 : : a dangerous assumption as many times CONST_INTs are
1986 : : created and used with garbage in the bits outside of the
1987 : : precision of the implied mode of the const_int. */
1988 : 103 : op_mode = MAX_MODE_INT;
1989 : : }
1990 : :
1991 : 5983 : real_from_integer (&d, mode, rtx_mode_t (op, op_mode), SIGNED);
1992 : :
1993 : : /* Avoid the folding if flag_signaling_nans is on and
1994 : : operand is a signaling NaN. */
1995 : 5983 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
1996 : : return 0;
1997 : :
1998 : 5983 : d = real_value_truncate (mode, d);
1999 : :
2000 : : /* Avoid the folding if flag_rounding_math is on and the
2001 : : conversion is not exact. */
2002 : 5983 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2003 : : {
2004 : 817 : bool fail = false;
2005 : 817 : wide_int w = real_to_integer (&d, &fail,
2006 : : GET_MODE_PRECISION
2007 : 817 : (as_a <scalar_int_mode> (op_mode)));
2008 : 817 : if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
2009 : 807 : return 0;
2010 : 817 : }
2011 : :
2012 : 5176 : return const_double_from_real_value (d, mode);
2013 : : }
2014 : 23005476 : else if (code == UNSIGNED_FLOAT && CONST_SCALAR_INT_P (op))
2015 : : {
2016 : 1949 : REAL_VALUE_TYPE d;
2017 : :
2018 : 1949 : if (op_mode == VOIDmode)
2019 : : {
2020 : : /* CONST_INT have VOIDmode as the mode. We assume that all
2021 : : the bits of the constant are significant, though, this is
2022 : : a dangerous assumption as many times CONST_INTs are
2023 : : created and used with garbage in the bits outside of the
2024 : : precision of the implied mode of the const_int. */
2025 : 8 : op_mode = MAX_MODE_INT;
2026 : : }
2027 : :
2028 : 1949 : real_from_integer (&d, mode, rtx_mode_t (op, op_mode), UNSIGNED);
2029 : :
2030 : : /* Avoid the folding if flag_signaling_nans is on and
2031 : : operand is a signaling NaN. */
2032 : 1949 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2033 : : return 0;
2034 : :
2035 : 1949 : d = real_value_truncate (mode, d);
2036 : :
2037 : : /* Avoid the folding if flag_rounding_math is on and the
2038 : : conversion is not exact. */
2039 : 1949 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2040 : : {
2041 : 16 : bool fail = false;
2042 : 16 : wide_int w = real_to_integer (&d, &fail,
2043 : : GET_MODE_PRECISION
2044 : 16 : (as_a <scalar_int_mode> (op_mode)));
2045 : 16 : if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
2046 : 16 : return 0;
2047 : 16 : }
2048 : :
2049 : 1933 : return const_double_from_real_value (d, mode);
2050 : : }
2051 : :
2052 : 23003527 : if (CONST_SCALAR_INT_P (op) && is_a <scalar_int_mode> (mode, &result_mode))
2053 : : {
2054 : 3076209 : unsigned int width = GET_MODE_PRECISION (result_mode);
2055 : 3076209 : if (width > MAX_BITSIZE_MODE_ANY_INT)
2056 : : return 0;
2057 : :
2058 : 3076209 : wide_int result;
2059 : 3076209 : scalar_int_mode imode = (op_mode == VOIDmode
2060 : 3076209 : ? result_mode
2061 : 3076209 : : as_a <scalar_int_mode> (op_mode));
2062 : 3076209 : rtx_mode_t op0 = rtx_mode_t (op, imode);
2063 : 3076209 : int int_value;
2064 : :
2065 : : #if TARGET_SUPPORTS_WIDE_INT == 0
2066 : : /* This assert keeps the simplification from producing a result
2067 : : that cannot be represented in a CONST_DOUBLE but a lot of
2068 : : upstream callers expect that this function never fails to
2069 : : simplify something and so you if you added this to the test
2070 : : above the code would die later anyway. If this assert
2071 : : happens, you just need to make the port support wide int. */
2072 : : gcc_assert (width <= HOST_BITS_PER_DOUBLE_INT);
2073 : : #endif
2074 : :
2075 : 3076209 : switch (code)
2076 : : {
2077 : 150647 : case NOT:
2078 : 150647 : result = wi::bit_not (op0);
2079 : 150647 : break;
2080 : :
2081 : 1817562 : case NEG:
2082 : 1817562 : result = wi::neg (op0);
2083 : 1817562 : break;
2084 : :
2085 : 4837 : case ABS:
2086 : 4837 : result = wi::abs (op0);
2087 : 4837 : break;
2088 : :
2089 : 0 : case FFS:
2090 : 0 : result = wi::shwi (wi::ffs (op0), result_mode);
2091 : 0 : break;
2092 : :
2093 : 182 : case CLZ:
2094 : 182 : if (wi::ne_p (op0, 0))
2095 : 0 : int_value = wi::clz (op0);
2096 : 364 : else if (! CLZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2097 : : return NULL_RTX;
2098 : 0 : result = wi::shwi (int_value, result_mode);
2099 : 0 : break;
2100 : :
2101 : 0 : case CLRSB:
2102 : 0 : result = wi::shwi (wi::clrsb (op0), result_mode);
2103 : 0 : break;
2104 : :
2105 : 0 : case CTZ:
2106 : 0 : if (wi::ne_p (op0, 0))
2107 : 0 : int_value = wi::ctz (op0);
2108 : 0 : else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2109 : : return NULL_RTX;
2110 : 0 : result = wi::shwi (int_value, result_mode);
2111 : 0 : break;
2112 : :
2113 : 142 : case POPCOUNT:
2114 : 142 : result = wi::shwi (wi::popcount (op0), result_mode);
2115 : 142 : break;
2116 : :
2117 : 0 : case PARITY:
2118 : 0 : result = wi::shwi (wi::parity (op0), result_mode);
2119 : 0 : break;
2120 : :
2121 : 1548 : case BSWAP:
2122 : 1548 : result = wi::bswap (op0);
2123 : 1548 : break;
2124 : :
2125 : 0 : case BITREVERSE:
2126 : 0 : result = wi::bitreverse (op0);
2127 : 0 : break;
2128 : :
2129 : 935884 : case TRUNCATE:
2130 : 935884 : case ZERO_EXTEND:
2131 : 935884 : result = wide_int::from (op0, width, UNSIGNED);
2132 : 935884 : break;
2133 : :
2134 : 12920 : case US_TRUNCATE:
2135 : 12920 : case SS_TRUNCATE:
2136 : 12920 : {
2137 : 12920 : signop sgn = code == US_TRUNCATE ? UNSIGNED : SIGNED;
2138 : 12920 : wide_int nmax
2139 : 12920 : = wide_int::from (wi::max_value (width, sgn),
2140 : 12920 : GET_MODE_PRECISION (imode), sgn);
2141 : 12920 : wide_int nmin
2142 : 12920 : = wide_int::from (wi::min_value (width, sgn),
2143 : 12920 : GET_MODE_PRECISION (imode), sgn);
2144 : 12920 : result = wi::min (wi::max (op0, nmin, sgn), nmax, sgn);
2145 : 12920 : result = wide_int::from (result, width, sgn);
2146 : 12920 : break;
2147 : 12920 : }
2148 : 152487 : case SIGN_EXTEND:
2149 : 152487 : result = wide_int::from (op0, width, SIGNED);
2150 : 152487 : break;
2151 : :
2152 : 0 : case SS_NEG:
2153 : 0 : if (wi::only_sign_bit_p (op0))
2154 : 0 : result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
2155 : : else
2156 : 0 : result = wi::neg (op0);
2157 : : break;
2158 : :
2159 : 0 : case SS_ABS:
2160 : 0 : if (wi::only_sign_bit_p (op0))
2161 : 0 : result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
2162 : : else
2163 : 0 : result = wi::abs (op0);
2164 : : break;
2165 : :
2166 : : case SQRT:
2167 : : default:
2168 : : return 0;
2169 : : }
2170 : :
2171 : 3076027 : return immed_wide_int_const (result, result_mode);
2172 : 3076209 : }
2173 : :
2174 : 19927318 : else if (CONST_DOUBLE_AS_FLOAT_P (op)
2175 : 458250 : && SCALAR_FLOAT_MODE_P (mode)
2176 : 454424 : && SCALAR_FLOAT_MODE_P (GET_MODE (op)))
2177 : : {
2178 : 454424 : REAL_VALUE_TYPE d = *CONST_DOUBLE_REAL_VALUE (op);
2179 : 454424 : switch (code)
2180 : : {
2181 : : case SQRT:
2182 : : return 0;
2183 : 22934 : case ABS:
2184 : 22934 : d = real_value_abs (&d);
2185 : 22934 : break;
2186 : 15211 : case NEG:
2187 : 15211 : d = real_value_negate (&d);
2188 : 15211 : break;
2189 : 990 : case FLOAT_TRUNCATE:
2190 : : /* Don't perform the operation if flag_signaling_nans is on
2191 : : and the operand is a signaling NaN. */
2192 : 990 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2193 : : return NULL_RTX;
2194 : : /* Or if flag_rounding_math is on and the truncation is not
2195 : : exact. */
2196 : 990 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2197 : 990 : && !exact_real_truncate (mode, &d))
2198 : 231 : return NULL_RTX;
2199 : 759 : d = real_value_truncate (mode, d);
2200 : 759 : break;
2201 : 368347 : case FLOAT_EXTEND:
2202 : : /* Don't perform the operation if flag_signaling_nans is on
2203 : : and the operand is a signaling NaN. */
2204 : 368347 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2205 : : return NULL_RTX;
2206 : : /* All this does is change the mode, unless changing
2207 : : mode class. */
2208 : 368345 : if (GET_MODE_CLASS (mode) != GET_MODE_CLASS (GET_MODE (op)))
2209 : 0 : real_convert (&d, mode, &d);
2210 : : break;
2211 : 0 : case FIX:
2212 : : /* Don't perform the operation if flag_signaling_nans is on
2213 : : and the operand is a signaling NaN. */
2214 : 0 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2215 : : return NULL_RTX;
2216 : 0 : real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
2217 : 0 : break;
2218 : 46307 : case NOT:
2219 : 46307 : {
2220 : 46307 : long tmp[4];
2221 : 46307 : int i;
2222 : :
2223 : 46307 : real_to_target (tmp, &d, GET_MODE (op));
2224 : 231535 : for (i = 0; i < 4; i++)
2225 : 185228 : tmp[i] = ~tmp[i];
2226 : 46307 : real_from_target (&d, tmp, mode);
2227 : 46307 : break;
2228 : : }
2229 : 0 : default:
2230 : 0 : gcc_unreachable ();
2231 : : }
2232 : 453556 : return const_double_from_real_value (d, mode);
2233 : : }
2234 : 3826 : else if (CONST_DOUBLE_AS_FLOAT_P (op)
2235 : 3826 : && SCALAR_FLOAT_MODE_P (GET_MODE (op))
2236 : 19476720 : && is_int_mode (mode, &result_mode))
2237 : : {
2238 : 3826 : unsigned int width = GET_MODE_PRECISION (result_mode);
2239 : 3826 : if (width > MAX_BITSIZE_MODE_ANY_INT)
2240 : : return 0;
2241 : :
2242 : : /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
2243 : : operators are intentionally left unspecified (to ease implementation
2244 : : by target backends), for consistency, this routine implements the
2245 : : same semantics for constant folding as used by the middle-end. */
2246 : :
2247 : : /* This was formerly used only for non-IEEE float.
2248 : : eggert@twinsun.com says it is safe for IEEE also. */
2249 : 3826 : REAL_VALUE_TYPE t;
2250 : 3826 : const REAL_VALUE_TYPE *x = CONST_DOUBLE_REAL_VALUE (op);
2251 : 3826 : wide_int wmax, wmin;
2252 : : /* This is part of the abi to real_to_integer, but we check
2253 : : things before making this call. */
2254 : 3826 : bool fail;
2255 : :
2256 : 3826 : switch (code)
2257 : : {
2258 : 2052 : case FIX:
2259 : 2052 : if (REAL_VALUE_ISNAN (*x))
2260 : 0 : return const0_rtx;
2261 : :
2262 : : /* Test against the signed upper bound. */
2263 : 2052 : wmax = wi::max_value (width, SIGNED);
2264 : 2052 : real_from_integer (&t, VOIDmode, wmax, SIGNED);
2265 : 2052 : if (real_less (&t, x))
2266 : 0 : return immed_wide_int_const (wmax, mode);
2267 : :
2268 : : /* Test against the signed lower bound. */
2269 : 2052 : wmin = wi::min_value (width, SIGNED);
2270 : 2052 : real_from_integer (&t, VOIDmode, wmin, SIGNED);
2271 : 2052 : if (real_less (x, &t))
2272 : 0 : return immed_wide_int_const (wmin, mode);
2273 : :
2274 : 2052 : return immed_wide_int_const (real_to_integer (x, &fail, width),
2275 : : mode);
2276 : :
2277 : 1774 : case UNSIGNED_FIX:
2278 : 1774 : if (REAL_VALUE_ISNAN (*x) || REAL_VALUE_NEGATIVE (*x))
2279 : 0 : return const0_rtx;
2280 : :
2281 : : /* Test against the unsigned upper bound. */
2282 : 1774 : wmax = wi::max_value (width, UNSIGNED);
2283 : 1774 : real_from_integer (&t, VOIDmode, wmax, UNSIGNED);
2284 : 1774 : if (real_less (&t, x))
2285 : 0 : return immed_wide_int_const (wmax, mode);
2286 : :
2287 : 1774 : return immed_wide_int_const (real_to_integer (x, &fail, width),
2288 : : mode);
2289 : :
2290 : 0 : default:
2291 : 0 : gcc_unreachable ();
2292 : : }
2293 : 3826 : }
2294 : :
2295 : : /* Handle polynomial integers. */
2296 : : else if (CONST_POLY_INT_P (op))
2297 : : {
2298 : : poly_wide_int result;
2299 : : switch (code)
2300 : : {
2301 : : case NEG:
2302 : : result = -const_poly_int_value (op);
2303 : : break;
2304 : :
2305 : : case NOT:
2306 : : result = ~const_poly_int_value (op);
2307 : : break;
2308 : :
2309 : : default:
2310 : : return NULL_RTX;
2311 : : }
2312 : : return immed_wide_int_const (result, mode);
2313 : : }
2314 : :
2315 : : return NULL_RTX;
2316 : : }
2317 : :
2318 : : /* Subroutine of simplify_binary_operation to simplify a binary operation
2319 : : CODE that can commute with byte swapping, with result mode MODE and
2320 : : operating on OP0 and OP1. CODE is currently one of AND, IOR or XOR.
2321 : : Return zero if no simplification or canonicalization is possible. */
2322 : :
2323 : : rtx
2324 : 29298369 : simplify_context::simplify_byte_swapping_operation (rtx_code code,
2325 : : machine_mode mode,
2326 : : rtx op0, rtx op1)
2327 : : {
2328 : 29298369 : rtx tem;
2329 : :
2330 : : /* (op (bswap x) C1)) -> (bswap (op x C2)) with C2 swapped. */
2331 : 29298369 : if (GET_CODE (op0) == BSWAP && CONST_SCALAR_INT_P (op1))
2332 : : {
2333 : 151 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0),
2334 : : simplify_gen_unary (BSWAP, mode, op1, mode));
2335 : 151 : return simplify_gen_unary (BSWAP, mode, tem, mode);
2336 : : }
2337 : :
2338 : : /* (op (bswap x) (bswap y)) -> (bswap (op x y)). */
2339 : 29298218 : if (GET_CODE (op0) == BSWAP && GET_CODE (op1) == BSWAP)
2340 : : {
2341 : 0 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0), XEXP (op1, 0));
2342 : 0 : return simplify_gen_unary (BSWAP, mode, tem, mode);
2343 : : }
2344 : :
2345 : : return NULL_RTX;
2346 : : }
2347 : :
2348 : : /* Subroutine of simplify_binary_operation to simplify a commutative,
2349 : : associative binary operation CODE with result mode MODE, operating
2350 : : on OP0 and OP1. CODE is currently one of PLUS, MULT, AND, IOR, XOR,
2351 : : SMIN, SMAX, UMIN or UMAX. Return zero if no simplification or
2352 : : canonicalization is possible. */
2353 : :
2354 : : rtx
2355 : 37255525 : simplify_context::simplify_associative_operation (rtx_code code,
2356 : : machine_mode mode,
2357 : : rtx op0, rtx op1)
2358 : : {
2359 : 37255525 : rtx tem;
2360 : :
2361 : : /* Normally expressions simplified by simplify-rtx.cc are combined
2362 : : at most from a few machine instructions and therefore the
2363 : : expressions should be fairly small. During var-tracking
2364 : : we can see arbitrarily large expressions though and reassociating
2365 : : those can be quadratic, so punt after encountering max_assoc_count
2366 : : simplify_associative_operation calls during outermost simplify_*
2367 : : call. */
2368 : 37255525 : if (++assoc_count >= max_assoc_count)
2369 : : return NULL_RTX;
2370 : :
2371 : : /* Linearize the operator to the left. */
2372 : 37254057 : if (GET_CODE (op1) == code)
2373 : : {
2374 : : /* "(a op b) op (c op d)" becomes "((a op b) op c) op d)". */
2375 : 14106 : if (GET_CODE (op0) == code)
2376 : : {
2377 : 4772 : tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
2378 : 4772 : return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
2379 : : }
2380 : :
2381 : : /* "a op (b op c)" becomes "(b op c) op a". */
2382 : 9334 : if (! swap_commutative_operands_p (op1, op0))
2383 : 9334 : return simplify_gen_binary (code, mode, op1, op0);
2384 : :
2385 : : std::swap (op0, op1);
2386 : : }
2387 : :
2388 : 37239951 : if (GET_CODE (op0) == code)
2389 : : {
2390 : : /* Canonicalize "(x op c) op y" as "(x op y) op c". */
2391 : 849825 : if (swap_commutative_operands_p (XEXP (op0, 1), op1))
2392 : : {
2393 : 136234 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
2394 : 136234 : return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2395 : : }
2396 : :
2397 : : /* Attempt to simplify "(a op b) op c" as "a op (b op c)". */
2398 : 713591 : tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
2399 : 713591 : if (tem != 0)
2400 : 43725 : return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
2401 : :
2402 : : /* Attempt to simplify "(a op b) op c" as "(a op c) op b". */
2403 : 669866 : tem = simplify_binary_operation (code, mode, XEXP (op0, 0), op1);
2404 : 669866 : if (tem != 0)
2405 : 2158 : return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2406 : : }
2407 : :
2408 : : return 0;
2409 : : }
2410 : :
2411 : : /* Return a mask describing the COMPARISON. */
2412 : : static int
2413 : 36 : comparison_to_mask (enum rtx_code comparison)
2414 : : {
2415 : 36 : switch (comparison)
2416 : : {
2417 : : case LT:
2418 : : return 8;
2419 : 0 : case GT:
2420 : 0 : return 4;
2421 : 18 : case EQ:
2422 : 18 : return 2;
2423 : 18 : case UNORDERED:
2424 : 18 : return 1;
2425 : :
2426 : 0 : case LTGT:
2427 : 0 : return 12;
2428 : 0 : case LE:
2429 : 0 : return 10;
2430 : 0 : case GE:
2431 : 0 : return 6;
2432 : 0 : case UNLT:
2433 : 0 : return 9;
2434 : 0 : case UNGT:
2435 : 0 : return 5;
2436 : 0 : case UNEQ:
2437 : 0 : return 3;
2438 : :
2439 : 0 : case ORDERED:
2440 : 0 : return 14;
2441 : 0 : case NE:
2442 : 0 : return 13;
2443 : 0 : case UNLE:
2444 : 0 : return 11;
2445 : 0 : case UNGE:
2446 : 0 : return 7;
2447 : :
2448 : 0 : default:
2449 : 0 : gcc_unreachable ();
2450 : : }
2451 : : }
2452 : :
2453 : : /* Return a comparison corresponding to the MASK. */
2454 : : static enum rtx_code
2455 : 18 : mask_to_comparison (int mask)
2456 : : {
2457 : 18 : switch (mask)
2458 : : {
2459 : : case 8:
2460 : : return LT;
2461 : : case 4:
2462 : : return GT;
2463 : : case 2:
2464 : : return EQ;
2465 : : case 1:
2466 : : return UNORDERED;
2467 : :
2468 : : case 12:
2469 : : return LTGT;
2470 : : case 10:
2471 : : return LE;
2472 : : case 6:
2473 : : return GE;
2474 : : case 9:
2475 : : return UNLT;
2476 : : case 5:
2477 : : return UNGT;
2478 : : case 3:
2479 : : return UNEQ;
2480 : :
2481 : : case 14:
2482 : : return ORDERED;
2483 : : case 13:
2484 : : return NE;
2485 : : case 11:
2486 : : return UNLE;
2487 : : case 7:
2488 : : return UNGE;
2489 : :
2490 : 0 : default:
2491 : 0 : gcc_unreachable ();
2492 : : }
2493 : : }
2494 : :
2495 : : /* Return true if CODE is valid for comparisons of mode MODE, false
2496 : : otherwise.
2497 : :
2498 : : It is always safe to return false, even if the code was valid for the
2499 : : given mode as that will merely suppress optimizations. */
2500 : :
2501 : : static bool
2502 : 18 : comparison_code_valid_for_mode (enum rtx_code code, enum machine_mode mode)
2503 : : {
2504 : 18 : switch (code)
2505 : : {
2506 : : /* These are valid for integral, floating and vector modes. */
2507 : 0 : case NE:
2508 : 0 : case EQ:
2509 : 0 : case GE:
2510 : 0 : case GT:
2511 : 0 : case LE:
2512 : 0 : case LT:
2513 : 0 : return (INTEGRAL_MODE_P (mode)
2514 : 0 : || FLOAT_MODE_P (mode)
2515 : 0 : || VECTOR_MODE_P (mode));
2516 : :
2517 : : /* These are valid for floating point modes. */
2518 : 18 : case LTGT:
2519 : 18 : case UNORDERED:
2520 : 18 : case ORDERED:
2521 : 18 : case UNEQ:
2522 : 18 : case UNGE:
2523 : 18 : case UNGT:
2524 : 18 : case UNLE:
2525 : 18 : case UNLT:
2526 : 18 : return FLOAT_MODE_P (mode);
2527 : :
2528 : : /* These are filtered out in simplify_logical_operation, but
2529 : : we check for them too as a matter of safety. They are valid
2530 : : for integral and vector modes. */
2531 : 0 : case GEU:
2532 : 0 : case GTU:
2533 : 0 : case LEU:
2534 : 0 : case LTU:
2535 : 0 : return INTEGRAL_MODE_P (mode) || VECTOR_MODE_P (mode);
2536 : :
2537 : 0 : default:
2538 : 0 : gcc_unreachable ();
2539 : : }
2540 : : }
2541 : :
2542 : : /* Canonicalize RES, a scalar const0_rtx/const_true_rtx to the right
2543 : : false/true value of comparison with MODE where comparison operands
2544 : : have CMP_MODE. */
2545 : :
2546 : : static rtx
2547 : 743227 : relational_result (machine_mode mode, machine_mode cmp_mode, rtx res)
2548 : : {
2549 : 743227 : if (SCALAR_FLOAT_MODE_P (mode))
2550 : : {
2551 : 59 : if (res == const0_rtx)
2552 : 59 : return CONST0_RTX (mode);
2553 : : #ifdef FLOAT_STORE_FLAG_VALUE
2554 : : REAL_VALUE_TYPE val = FLOAT_STORE_FLAG_VALUE (mode);
2555 : : return const_double_from_real_value (val, mode);
2556 : : #else
2557 : : return NULL_RTX;
2558 : : #endif
2559 : : }
2560 : 743168 : if (VECTOR_MODE_P (mode))
2561 : : {
2562 : 42 : if (res == const0_rtx)
2563 : 12 : return CONST0_RTX (mode);
2564 : : #ifdef VECTOR_STORE_FLAG_VALUE
2565 : : rtx val = VECTOR_STORE_FLAG_VALUE (mode);
2566 : : if (val == NULL_RTX)
2567 : : return NULL_RTX;
2568 : : if (val == const1_rtx)
2569 : : return CONST1_RTX (mode);
2570 : :
2571 : : return gen_const_vec_duplicate (mode, val);
2572 : : #else
2573 : : return NULL_RTX;
2574 : : #endif
2575 : : }
2576 : : /* For vector comparison with scalar int result, it is unknown
2577 : : if the target means here a comparison into an integral bitmask,
2578 : : or comparison where all comparisons true mean const_true_rtx
2579 : : whole result, or where any comparisons true mean const_true_rtx
2580 : : whole result. For const0_rtx all the cases are the same. */
2581 : 743126 : if (VECTOR_MODE_P (cmp_mode)
2582 : 0 : && SCALAR_INT_MODE_P (mode)
2583 : 0 : && res == const_true_rtx)
2584 : 0 : return NULL_RTX;
2585 : :
2586 : : return res;
2587 : : }
2588 : :
2589 : : /* Simplify a logical operation CODE with result mode MODE, operating on OP0
2590 : : and OP1, which should be both relational operations. Return 0 if no such
2591 : : simplification is possible. */
2592 : : rtx
2593 : 10362169 : simplify_context::simplify_logical_relational_operation (rtx_code code,
2594 : : machine_mode mode,
2595 : : rtx op0, rtx op1)
2596 : : {
2597 : : /* We only handle IOR of two relational operations. */
2598 : 10362169 : if (code != IOR)
2599 : : return 0;
2600 : :
2601 : 10362169 : if (!(COMPARISON_P (op0) && COMPARISON_P (op1)))
2602 : : return 0;
2603 : :
2604 : 2140 : if (!(rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2605 : 373 : && rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))))
2606 : 1749 : return 0;
2607 : :
2608 : 18 : enum rtx_code code0 = GET_CODE (op0);
2609 : 18 : enum rtx_code code1 = GET_CODE (op1);
2610 : :
2611 : : /* We don't handle unsigned comparisons currently. */
2612 : 18 : if (code0 == LTU || code0 == GTU || code0 == LEU || code0 == GEU)
2613 : : return 0;
2614 : 18 : if (code1 == LTU || code1 == GTU || code1 == LEU || code1 == GEU)
2615 : : return 0;
2616 : :
2617 : 18 : int mask0 = comparison_to_mask (code0);
2618 : 18 : int mask1 = comparison_to_mask (code1);
2619 : :
2620 : 18 : int mask = mask0 | mask1;
2621 : :
2622 : 18 : if (mask == 15)
2623 : 0 : return relational_result (mode, GET_MODE (op0), const_true_rtx);
2624 : :
2625 : 18 : code = mask_to_comparison (mask);
2626 : :
2627 : : /* Many comparison codes are only valid for certain mode classes. */
2628 : 18 : if (!comparison_code_valid_for_mode (code, mode))
2629 : : return 0;
2630 : :
2631 : 5 : op0 = XEXP (op1, 0);
2632 : 5 : op1 = XEXP (op1, 1);
2633 : :
2634 : 5 : return simplify_gen_relational (code, mode, VOIDmode, op0, op1);
2635 : : }
2636 : :
2637 : : /* Simplify a binary operation CODE with result mode MODE, operating on OP0
2638 : : and OP1. Return 0 if no simplification is possible.
2639 : :
2640 : : Don't use this for relational operations such as EQ or LT.
2641 : : Use simplify_relational_operation instead. */
2642 : : rtx
2643 : 381800088 : simplify_context::simplify_binary_operation (rtx_code code, machine_mode mode,
2644 : : rtx op0, rtx op1)
2645 : : {
2646 : 381800088 : rtx trueop0, trueop1;
2647 : 381800088 : rtx tem;
2648 : :
2649 : : /* Relational operations don't work here. We must know the mode
2650 : : of the operands in order to do the comparison correctly.
2651 : : Assuming a full word can give incorrect results.
2652 : : Consider comparing 128 with -128 in QImode. */
2653 : 381800088 : gcc_assert (GET_RTX_CLASS (code) != RTX_COMPARE);
2654 : 381800088 : gcc_assert (GET_RTX_CLASS (code) != RTX_COMM_COMPARE);
2655 : :
2656 : : /* Make sure the constant is second. */
2657 : 381800088 : if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
2658 : 381800088 : && swap_commutative_operands_p (op0, op1))
2659 : : std::swap (op0, op1);
2660 : :
2661 : 381800088 : trueop0 = avoid_constant_pool_reference (op0);
2662 : 381800088 : trueop1 = avoid_constant_pool_reference (op1);
2663 : :
2664 : 381800088 : tem = simplify_const_binary_operation (code, mode, trueop0, trueop1);
2665 : 381800088 : if (tem)
2666 : : return tem;
2667 : 356661524 : tem = simplify_binary_operation_1 (code, mode, op0, op1, trueop0, trueop1);
2668 : :
2669 : 356661524 : if (tem)
2670 : : return tem;
2671 : :
2672 : : /* If the above steps did not result in a simplification and op0 or op1
2673 : : were constant pool references, use the referenced constants directly. */
2674 : 305833833 : if (trueop0 != op0 || trueop1 != op1)
2675 : 365028 : return simplify_gen_binary (code, mode, trueop0, trueop1);
2676 : :
2677 : : return NULL_RTX;
2678 : : }
2679 : :
2680 : : /* Subroutine of simplify_binary_operation_1 that looks for cases in
2681 : : which OP0 and OP1 are both vector series or vector duplicates
2682 : : (which are really just series with a step of 0). If so, try to
2683 : : form a new series by applying CODE to the bases and to the steps.
2684 : : Return null if no simplification is possible.
2685 : :
2686 : : MODE is the mode of the operation and is known to be a vector
2687 : : integer mode. */
2688 : :
2689 : : rtx
2690 : 1750015 : simplify_context::simplify_binary_operation_series (rtx_code code,
2691 : : machine_mode mode,
2692 : : rtx op0, rtx op1)
2693 : : {
2694 : 1750015 : rtx base0, step0;
2695 : 1750015 : if (vec_duplicate_p (op0, &base0))
2696 : 35038 : step0 = const0_rtx;
2697 : 1714977 : else if (!vec_series_p (op0, &base0, &step0))
2698 : : return NULL_RTX;
2699 : :
2700 : 35294 : rtx base1, step1;
2701 : 35294 : if (vec_duplicate_p (op1, &base1))
2702 : 869 : step1 = const0_rtx;
2703 : 34425 : else if (!vec_series_p (op1, &base1, &step1))
2704 : : return NULL_RTX;
2705 : :
2706 : : /* Only create a new series if we can simplify both parts. In other
2707 : : cases this isn't really a simplification, and it's not necessarily
2708 : : a win to replace a vector operation with a scalar operation. */
2709 : 2283 : scalar_mode inner_mode = GET_MODE_INNER (mode);
2710 : 2283 : rtx new_base = simplify_binary_operation (code, inner_mode, base0, base1);
2711 : 2283 : if (!new_base)
2712 : : return NULL_RTX;
2713 : :
2714 : 1709 : rtx new_step = simplify_binary_operation (code, inner_mode, step0, step1);
2715 : 1709 : if (!new_step)
2716 : : return NULL_RTX;
2717 : :
2718 : 1709 : return gen_vec_series (mode, new_base, new_step);
2719 : : }
2720 : :
2721 : : /* Subroutine of simplify_binary_operation_1. Un-distribute a binary
2722 : : operation CODE with result mode MODE, operating on OP0 and OP1.
2723 : : e.g. simplify (xor (and A C) (and (B C)) to (and (xor (A B) C).
2724 : : Returns NULL_RTX if no simplification is possible. */
2725 : :
2726 : : rtx
2727 : 1114724 : simplify_context::simplify_distributive_operation (rtx_code code,
2728 : : machine_mode mode,
2729 : : rtx op0, rtx op1)
2730 : : {
2731 : 1114724 : enum rtx_code op = GET_CODE (op0);
2732 : 1114724 : gcc_assert (GET_CODE (op1) == op);
2733 : :
2734 : 1114724 : if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))
2735 : 1114724 : && ! side_effects_p (XEXP (op0, 1)))
2736 : 269284 : return simplify_gen_binary (op, mode,
2737 : : simplify_gen_binary (code, mode,
2738 : : XEXP (op0, 0),
2739 : : XEXP (op1, 0)),
2740 : 269284 : XEXP (op0, 1));
2741 : :
2742 : 845440 : if (GET_RTX_CLASS (op) == RTX_COMM_ARITH)
2743 : : {
2744 : 828617 : if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2745 : 828617 : && ! side_effects_p (XEXP (op0, 0)))
2746 : 411294 : return simplify_gen_binary (op, mode,
2747 : : simplify_gen_binary (code, mode,
2748 : : XEXP (op0, 1),
2749 : : XEXP (op1, 1)),
2750 : 411294 : XEXP (op0, 0));
2751 : 417323 : if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 1))
2752 : 417323 : && ! side_effects_p (XEXP (op0, 0)))
2753 : 53 : return simplify_gen_binary (op, mode,
2754 : : simplify_gen_binary (code, mode,
2755 : : XEXP (op0, 1),
2756 : : XEXP (op1, 0)),
2757 : 53 : XEXP (op0, 0));
2758 : 417270 : if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 0))
2759 : 417270 : && ! side_effects_p (XEXP (op0, 1)))
2760 : 222945 : return simplify_gen_binary (op, mode,
2761 : : simplify_gen_binary (code, mode,
2762 : : XEXP (op0, 0),
2763 : : XEXP (op1, 1)),
2764 : 222945 : XEXP (op0, 1));
2765 : : }
2766 : :
2767 : : return NULL_RTX;
2768 : : }
2769 : :
2770 : : /* Return TRUE if a rotate in mode MODE with a constant count in OP1
2771 : : should be reversed.
2772 : :
2773 : : If the rotate should not be reversed, return FALSE.
2774 : :
2775 : : LEFT indicates if this is a rotate left or a rotate right. */
2776 : :
2777 : : bool
2778 : 136320 : reverse_rotate_by_imm_p (machine_mode mode, unsigned int left, rtx op1)
2779 : : {
2780 : 136320 : if (!CONST_INT_P (op1))
2781 : : return false;
2782 : :
2783 : : /* Some targets may only be able to rotate by a constant
2784 : : in one direction. So we need to query the optab interface
2785 : : to see what is possible. */
2786 : 108246 : optab binoptab = left ? rotl_optab : rotr_optab;
2787 : 43214 : optab re_binoptab = left ? rotr_optab : rotl_optab;
2788 : 108246 : enum insn_code icode = optab_handler (binoptab, mode);
2789 : 108246 : enum insn_code re_icode = optab_handler (re_binoptab, mode);
2790 : :
2791 : : /* If the target can not support the reversed optab, then there
2792 : : is nothing to do. */
2793 : 108246 : if (re_icode == CODE_FOR_nothing)
2794 : : return false;
2795 : :
2796 : : /* If the target does not support the requested rotate-by-immediate,
2797 : : then we want to try reversing the rotate. We also want to try
2798 : : reversing to minimize the count. */
2799 : 105414 : if ((icode == CODE_FOR_nothing)
2800 : 105414 : || (!insn_operand_matches (icode, 2, op1))
2801 : 527070 : || (IN_RANGE (INTVAL (op1),
2802 : : GET_MODE_UNIT_PRECISION (mode) / 2 + left,
2803 : : GET_MODE_UNIT_PRECISION (mode) - 1)))
2804 : 13967 : return (insn_operand_matches (re_icode, 2, op1));
2805 : : return false;
2806 : : }
2807 : :
2808 : : /* Subroutine of simplify_binary_operation. Simplify a binary operation
2809 : : CODE with result mode MODE, operating on OP0 and OP1. If OP0 and/or
2810 : : OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the
2811 : : actual constants. */
2812 : :
2813 : : rtx
2814 : 356661524 : simplify_context::simplify_binary_operation_1 (rtx_code code,
2815 : : machine_mode mode,
2816 : : rtx op0, rtx op1,
2817 : : rtx trueop0, rtx trueop1)
2818 : : {
2819 : 356661524 : rtx tem, reversed, opleft, opright, elt0, elt1;
2820 : 356661524 : HOST_WIDE_INT val;
2821 : 356661524 : scalar_int_mode int_mode, inner_mode;
2822 : 356661524 : poly_int64 offset;
2823 : :
2824 : : /* Even if we can't compute a constant result,
2825 : : there are some cases worth simplifying. */
2826 : :
2827 : 356661524 : switch (code)
2828 : : {
2829 : 206168436 : case PLUS:
2830 : : /* Maybe simplify x + 0 to x. The two expressions are equivalent
2831 : : when x is NaN, infinite, or finite and nonzero. They aren't
2832 : : when x is -0 and the rounding mode is not towards -infinity,
2833 : : since (-0) + 0 is then 0. */
2834 : 408692000 : if (!HONOR_SIGNED_ZEROS (mode) && !HONOR_SNANS (mode)
2835 : 408691990 : && trueop1 == CONST0_RTX (mode))
2836 : : return op0;
2837 : :
2838 : : /* ((-a) + b) -> (b - a) and similarly for (a + (-b)). These
2839 : : transformations are safe even for IEEE. */
2840 : 204983181 : if (GET_CODE (op0) == NEG)
2841 : 37559 : return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
2842 : 204945622 : else if (GET_CODE (op1) == NEG)
2843 : 8891 : return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
2844 : :
2845 : : /* (~a) + 1 -> -a */
2846 : 204936731 : if (INTEGRAL_MODE_P (mode)
2847 : 200522396 : && GET_CODE (op0) == NOT
2848 : 467335 : && trueop1 == const1_rtx)
2849 : 1507 : return simplify_gen_unary (NEG, mode, XEXP (op0, 0), mode);
2850 : :
2851 : : /* Handle both-operands-constant cases. We can only add
2852 : : CONST_INTs to constants since the sum of relocatable symbols
2853 : : can't be handled by most assemblers. Don't add CONST_INT
2854 : : to CONST_INT since overflow won't be computed properly if wider
2855 : : than HOST_BITS_PER_WIDE_INT. */
2856 : :
2857 : 204935224 : if ((GET_CODE (op0) == CONST
2858 : 204935224 : || GET_CODE (op0) == SYMBOL_REF
2859 : 202875179 : || GET_CODE (op0) == LABEL_REF)
2860 : 204935297 : && poly_int_rtx_p (op1, &offset))
2861 : 2059048 : return plus_constant (mode, op0, offset);
2862 : 202876176 : else if ((GET_CODE (op1) == CONST
2863 : 202876176 : || GET_CODE (op1) == SYMBOL_REF
2864 : 199782757 : || GET_CODE (op1) == LABEL_REF)
2865 : 202928100 : && poly_int_rtx_p (op0, &offset))
2866 : 0 : return plus_constant (mode, op1, offset);
2867 : :
2868 : : /* See if this is something like X * C - X or vice versa or
2869 : : if the multiplication is written as a shift. If so, we can
2870 : : distribute and make a new multiply, shift, or maybe just
2871 : : have X (if C is 2 in the example above). But don't make
2872 : : something more expensive than we had before. */
2873 : :
2874 : 202876176 : if (is_a <scalar_int_mode> (mode, &int_mode))
2875 : : {
2876 : 196836460 : rtx lhs = op0, rhs = op1;
2877 : :
2878 : 196836460 : wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
2879 : 196836460 : wide_int coeff1 = wi::one (GET_MODE_PRECISION (int_mode));
2880 : :
2881 : 196836460 : if (GET_CODE (lhs) == NEG)
2882 : : {
2883 : 0 : coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
2884 : 0 : lhs = XEXP (lhs, 0);
2885 : : }
2886 : 196836460 : else if (GET_CODE (lhs) == MULT
2887 : 5040370 : && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
2888 : : {
2889 : 4162063 : coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
2890 : 4162063 : lhs = XEXP (lhs, 0);
2891 : : }
2892 : 192674397 : else if (GET_CODE (lhs) == ASHIFT
2893 : 9151477 : && CONST_INT_P (XEXP (lhs, 1))
2894 : 9082856 : && INTVAL (XEXP (lhs, 1)) >= 0
2895 : 201757253 : && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
2896 : : {
2897 : 18165712 : coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
2898 : 9082856 : GET_MODE_PRECISION (int_mode));
2899 : 9082856 : lhs = XEXP (lhs, 0);
2900 : : }
2901 : :
2902 : 196836460 : if (GET_CODE (rhs) == NEG)
2903 : : {
2904 : 0 : coeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
2905 : 0 : rhs = XEXP (rhs, 0);
2906 : : }
2907 : 196836460 : else if (GET_CODE (rhs) == MULT
2908 : 222622 : && CONST_INT_P (XEXP (rhs, 1)))
2909 : : {
2910 : 149132 : coeff1 = rtx_mode_t (XEXP (rhs, 1), int_mode);
2911 : 149132 : rhs = XEXP (rhs, 0);
2912 : : }
2913 : 196687328 : else if (GET_CODE (rhs) == ASHIFT
2914 : 461414 : && CONST_INT_P (XEXP (rhs, 1))
2915 : 451585 : && INTVAL (XEXP (rhs, 1)) >= 0
2916 : 197138913 : && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
2917 : : {
2918 : 903170 : coeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
2919 : 451585 : GET_MODE_PRECISION (int_mode));
2920 : 451585 : rhs = XEXP (rhs, 0);
2921 : : }
2922 : :
2923 : 196836460 : if (rtx_equal_p (lhs, rhs))
2924 : : {
2925 : 719593 : rtx orig = gen_rtx_PLUS (int_mode, op0, op1);
2926 : 719593 : rtx coeff;
2927 : 719593 : bool speed = optimize_function_for_speed_p (cfun);
2928 : :
2929 : 719593 : coeff = immed_wide_int_const (coeff0 + coeff1, int_mode);
2930 : :
2931 : 719593 : tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
2932 : 719593 : return (set_src_cost (tem, int_mode, speed)
2933 : 719593 : <= set_src_cost (orig, int_mode, speed) ? tem : 0);
2934 : : }
2935 : :
2936 : : /* Optimize (X - 1) * Y + Y to X * Y. */
2937 : 196116867 : lhs = op0;
2938 : 196116867 : rhs = op1;
2939 : 196116867 : if (GET_CODE (op0) == MULT)
2940 : : {
2941 : 5037361 : if (((GET_CODE (XEXP (op0, 0)) == PLUS
2942 : 144213 : && XEXP (XEXP (op0, 0), 1) == constm1_rtx)
2943 : 5023948 : || (GET_CODE (XEXP (op0, 0)) == MINUS
2944 : 20685 : && XEXP (XEXP (op0, 0), 1) == const1_rtx))
2945 : 5050774 : && rtx_equal_p (XEXP (op0, 1), op1))
2946 : 29 : lhs = XEXP (XEXP (op0, 0), 0);
2947 : 5037332 : else if (((GET_CODE (XEXP (op0, 1)) == PLUS
2948 : 752 : && XEXP (XEXP (op0, 1), 1) == constm1_rtx)
2949 : 5037265 : || (GET_CODE (XEXP (op0, 1)) == MINUS
2950 : 225 : && XEXP (XEXP (op0, 1), 1) == const1_rtx))
2951 : 5037399 : && rtx_equal_p (XEXP (op0, 0), op1))
2952 : 0 : lhs = XEXP (XEXP (op0, 1), 0);
2953 : : }
2954 : 191079506 : else if (GET_CODE (op1) == MULT)
2955 : : {
2956 : 107910 : if (((GET_CODE (XEXP (op1, 0)) == PLUS
2957 : 17 : && XEXP (XEXP (op1, 0), 1) == constm1_rtx)
2958 : 107908 : || (GET_CODE (XEXP (op1, 0)) == MINUS
2959 : 4 : && XEXP (XEXP (op1, 0), 1) == const1_rtx))
2960 : 107912 : && rtx_equal_p (XEXP (op1, 1), op0))
2961 : 0 : rhs = XEXP (XEXP (op1, 0), 0);
2962 : 107910 : else if (((GET_CODE (XEXP (op1, 1)) == PLUS
2963 : 2 : && XEXP (XEXP (op1, 1), 1) == constm1_rtx)
2964 : 107908 : || (GET_CODE (XEXP (op1, 1)) == MINUS
2965 : 0 : && XEXP (XEXP (op1, 1), 1) == const1_rtx))
2966 : 107912 : && rtx_equal_p (XEXP (op1, 0), op0))
2967 : 0 : rhs = XEXP (XEXP (op1, 1), 0);
2968 : : }
2969 : 196116867 : if (lhs != op0 || rhs != op1)
2970 : 29 : return simplify_gen_binary (MULT, int_mode, lhs, rhs);
2971 : 196836460 : }
2972 : :
2973 : : /* (plus (xor X C1) C2) is (xor X (C1^C2)) if C2 is signbit. */
2974 : 202156554 : if (CONST_SCALAR_INT_P (op1)
2975 : 157740379 : && GET_CODE (op0) == XOR
2976 : 17113 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
2977 : 202165908 : && mode_signbit_p (mode, op1))
2978 : 121 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
2979 : : simplify_gen_binary (XOR, mode, op1,
2980 : 121 : XEXP (op0, 1)));
2981 : :
2982 : : /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)). */
2983 : 202156433 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2984 : 202154397 : && GET_CODE (op0) == MULT
2985 : 207516150 : && GET_CODE (XEXP (op0, 0)) == NEG)
2986 : : {
2987 : 315 : rtx in1, in2;
2988 : :
2989 : 315 : in1 = XEXP (XEXP (op0, 0), 0);
2990 : 315 : in2 = XEXP (op0, 1);
2991 : 315 : return simplify_gen_binary (MINUS, mode, op1,
2992 : : simplify_gen_binary (MULT, mode,
2993 : 315 : in1, in2));
2994 : : }
2995 : :
2996 : : /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
2997 : : C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
2998 : : is 1. */
2999 : 202156118 : if (COMPARISON_P (op0)
3000 : 1485128 : && ((STORE_FLAG_VALUE == -1 && trueop1 == const1_rtx)
3001 : 1485128 : || (STORE_FLAG_VALUE == 1 && trueop1 == constm1_rtx))
3002 : 202189797 : && (reversed = reversed_comparison (op0, mode)))
3003 : 33363 : return
3004 : 33363 : simplify_gen_unary (NEG, mode, reversed, mode);
3005 : :
3006 : : /* If one of the operands is a PLUS or a MINUS, see if we can
3007 : : simplify this by the associative law.
3008 : : Don't use the associative law for floating point.
3009 : : The inaccuracy makes it nonassociative,
3010 : : and subtle programs can break if operations are associated. */
3011 : :
3012 : 202122755 : if (INTEGRAL_MODE_P (mode)
3013 : 197708457 : && (plus_minus_operand_p (op0)
3014 : 170430333 : || plus_minus_operand_p (op1))
3015 : 28124443 : && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
3016 : : return tem;
3017 : :
3018 : : /* Reassociate floating point addition only when the user
3019 : : specifies associative math operations. */
3020 : 174624759 : if (FLOAT_MODE_P (mode)
3021 : 4414298 : && flag_associative_math)
3022 : : {
3023 : 769400 : tem = simplify_associative_operation (code, mode, op0, op1);
3024 : 769400 : if (tem)
3025 : : return tem;
3026 : : }
3027 : :
3028 : : /* Handle vector series. */
3029 : 174612273 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3030 : : {
3031 : 1497203 : tem = simplify_binary_operation_series (code, mode, op0, op1);
3032 : 1497203 : if (tem)
3033 : : return tem;
3034 : : }
3035 : : break;
3036 : :
3037 : 35504423 : case COMPARE:
3038 : : /* Convert (compare (gt (flags) 0) (lt (flags) 0)) to (flags). */
3039 : 35504423 : if (((GET_CODE (op0) == GT && GET_CODE (op1) == LT)
3040 : 35504410 : || (GET_CODE (op0) == GTU && GET_CODE (op1) == LTU))
3041 : 13 : && XEXP (op0, 1) == const0_rtx && XEXP (op1, 1) == const0_rtx)
3042 : : {
3043 : 9 : rtx xop00 = XEXP (op0, 0);
3044 : 9 : rtx xop10 = XEXP (op1, 0);
3045 : :
3046 : 9 : if (REG_P (xop00) && REG_P (xop10)
3047 : 9 : && REGNO (xop00) == REGNO (xop10)
3048 : 9 : && GET_MODE (xop00) == mode
3049 : 0 : && GET_MODE (xop10) == mode
3050 : 9 : && GET_MODE_CLASS (mode) == MODE_CC)
3051 : : return xop00;
3052 : : }
3053 : : break;
3054 : :
3055 : 33499731 : case MINUS:
3056 : : /* We can't assume x-x is 0 even with non-IEEE floating point,
3057 : : but since it is zero except in very strange circumstances, we
3058 : : will treat it as zero with -ffinite-math-only. */
3059 : 33499731 : if (rtx_equal_p (trueop0, trueop1)
3060 : 170240 : && ! side_effects_p (op0)
3061 : 33668906 : && (!FLOAT_MODE_P (mode) || !HONOR_NANS (mode)))
3062 : 167525 : return CONST0_RTX (mode);
3063 : :
3064 : : /* Change subtraction from zero into negation. (0 - x) is the
3065 : : same as -x when x is NaN, infinite, or finite and nonzero.
3066 : : But if the mode has signed zeros, and does not round towards
3067 : : -infinity, then 0 - 0 is 0, not -0. */
3068 : 33332206 : if (!HONOR_SIGNED_ZEROS (mode) && trueop0 == CONST0_RTX (mode))
3069 : 292424 : return simplify_gen_unary (NEG, mode, op1, mode);
3070 : :
3071 : : /* (-1 - a) is ~a, unless the expression contains symbolic
3072 : : constants, in which case not retaining additions and
3073 : : subtractions could cause invalid assembly to be produced. */
3074 : 33039782 : if (trueop0 == CONSTM1_RTX (mode)
3075 : 33039782 : && !contains_symbolic_reference_p (op1))
3076 : 268594 : return simplify_gen_unary (NOT, mode, op1, mode);
3077 : :
3078 : : /* Subtracting 0 has no effect unless the mode has signalling NaNs,
3079 : : or has signed zeros and supports rounding towards -infinity.
3080 : : In such a case, 0 - 0 is -0. */
3081 : 33405395 : if (!(HONOR_SIGNED_ZEROS (mode)
3082 : 634207 : && HONOR_SIGN_DEPENDENT_ROUNDING (mode))
3083 : 32770074 : && !HONOR_SNANS (mode)
3084 : 65541234 : && trueop1 == CONST0_RTX (mode))
3085 : : return op0;
3086 : :
3087 : : /* See if this is something like X * C - X or vice versa or
3088 : : if the multiplication is written as a shift. If so, we can
3089 : : distribute and make a new multiply, shift, or maybe just
3090 : : have X (if C is 2 in the example above). But don't make
3091 : : something more expensive than we had before. */
3092 : :
3093 : 31873347 : if (is_a <scalar_int_mode> (mode, &int_mode))
3094 : : {
3095 : 30882139 : rtx lhs = op0, rhs = op1;
3096 : :
3097 : 30882139 : wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
3098 : 30882139 : wide_int negcoeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3099 : :
3100 : 30882139 : if (GET_CODE (lhs) == NEG)
3101 : : {
3102 : 96033 : coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3103 : 96033 : lhs = XEXP (lhs, 0);
3104 : : }
3105 : 30786106 : else if (GET_CODE (lhs) == MULT
3106 : 176300 : && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
3107 : : {
3108 : 68444 : coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
3109 : 68444 : lhs = XEXP (lhs, 0);
3110 : : }
3111 : 30717662 : else if (GET_CODE (lhs) == ASHIFT
3112 : 294958 : && CONST_INT_P (XEXP (lhs, 1))
3113 : 292409 : && INTVAL (XEXP (lhs, 1)) >= 0
3114 : 31010071 : && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
3115 : : {
3116 : 584818 : coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
3117 : 292409 : GET_MODE_PRECISION (int_mode));
3118 : 292409 : lhs = XEXP (lhs, 0);
3119 : : }
3120 : :
3121 : 30882139 : if (GET_CODE (rhs) == NEG)
3122 : : {
3123 : 6459 : negcoeff1 = wi::one (GET_MODE_PRECISION (int_mode));
3124 : 6459 : rhs = XEXP (rhs, 0);
3125 : : }
3126 : 30875680 : else if (GET_CODE (rhs) == MULT
3127 : 134282 : && CONST_INT_P (XEXP (rhs, 1)))
3128 : : {
3129 : 115324 : negcoeff1 = wi::neg (rtx_mode_t (XEXP (rhs, 1), int_mode));
3130 : 115324 : rhs = XEXP (rhs, 0);
3131 : : }
3132 : 30760356 : else if (GET_CODE (rhs) == ASHIFT
3133 : 308719 : && CONST_INT_P (XEXP (rhs, 1))
3134 : 308513 : && INTVAL (XEXP (rhs, 1)) >= 0
3135 : 31068869 : && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
3136 : : {
3137 : 617026 : negcoeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
3138 : 308513 : GET_MODE_PRECISION (int_mode));
3139 : 308513 : negcoeff1 = -negcoeff1;
3140 : 308513 : rhs = XEXP (rhs, 0);
3141 : : }
3142 : :
3143 : 30882139 : if (rtx_equal_p (lhs, rhs))
3144 : : {
3145 : 136514 : rtx orig = gen_rtx_MINUS (int_mode, op0, op1);
3146 : 136514 : rtx coeff;
3147 : 136514 : bool speed = optimize_function_for_speed_p (cfun);
3148 : :
3149 : 136514 : coeff = immed_wide_int_const (coeff0 + negcoeff1, int_mode);
3150 : :
3151 : 136514 : tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
3152 : 136514 : return (set_src_cost (tem, int_mode, speed)
3153 : 136514 : <= set_src_cost (orig, int_mode, speed) ? tem : 0);
3154 : : }
3155 : :
3156 : : /* Optimize (X + 1) * Y - Y to X * Y. */
3157 : 30745625 : lhs = op0;
3158 : 30745625 : if (GET_CODE (op0) == MULT)
3159 : : {
3160 : 176244 : if (((GET_CODE (XEXP (op0, 0)) == PLUS
3161 : 5463 : && XEXP (XEXP (op0, 0), 1) == const1_rtx)
3162 : 174942 : || (GET_CODE (XEXP (op0, 0)) == MINUS
3163 : 2857 : && XEXP (XEXP (op0, 0), 1) == constm1_rtx))
3164 : 177546 : && rtx_equal_p (XEXP (op0, 1), op1))
3165 : 12 : lhs = XEXP (XEXP (op0, 0), 0);
3166 : 176232 : else if (((GET_CODE (XEXP (op0, 1)) == PLUS
3167 : 11 : && XEXP (XEXP (op0, 1), 1) == const1_rtx)
3168 : 176229 : || (GET_CODE (XEXP (op0, 1)) == MINUS
3169 : 45 : && XEXP (XEXP (op0, 1), 1) == constm1_rtx))
3170 : 176235 : && rtx_equal_p (XEXP (op0, 0), op1))
3171 : 0 : lhs = XEXP (XEXP (op0, 1), 0);
3172 : : }
3173 : 30745625 : if (lhs != op0)
3174 : 12 : return simplify_gen_binary (MULT, int_mode, lhs, op1);
3175 : 30882139 : }
3176 : :
3177 : : /* (a - (-b)) -> (a + b). True even for IEEE. */
3178 : 31736821 : if (GET_CODE (op1) == NEG)
3179 : 6431 : return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
3180 : :
3181 : : /* (-x - c) may be simplified as (-c - x). */
3182 : 31730390 : if (GET_CODE (op0) == NEG
3183 : 99045 : && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1)))
3184 : : {
3185 : 515 : tem = simplify_unary_operation (NEG, mode, op1, mode);
3186 : 515 : if (tem)
3187 : 515 : return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
3188 : : }
3189 : :
3190 : 31729875 : if ((GET_CODE (op0) == CONST
3191 : 31729875 : || GET_CODE (op0) == SYMBOL_REF
3192 : 27369819 : || GET_CODE (op0) == LABEL_REF)
3193 : 31730575 : && poly_int_rtx_p (op1, &offset))
3194 : 35206 : return plus_constant (mode, op0, trunc_int_for_mode (-offset, mode));
3195 : :
3196 : : /* Don't let a relocatable value get a negative coeff. */
3197 : 31694669 : if (poly_int_rtx_p (op1) && GET_MODE (op0) != VOIDmode)
3198 : 5867144 : return simplify_gen_binary (PLUS, mode,
3199 : : op0,
3200 : 5867144 : neg_poly_int_rtx (mode, op1));
3201 : :
3202 : : /* (x - (x & y)) -> (x & ~y) */
3203 : 25827525 : if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND)
3204 : : {
3205 : 326706 : if (rtx_equal_p (op0, XEXP (op1, 0)))
3206 : : {
3207 : 5272 : tem = simplify_gen_unary (NOT, mode, XEXP (op1, 1),
3208 : 2636 : GET_MODE (XEXP (op1, 1)));
3209 : 2636 : return simplify_gen_binary (AND, mode, op0, tem);
3210 : : }
3211 : 324070 : if (rtx_equal_p (op0, XEXP (op1, 1)))
3212 : : {
3213 : 2098 : tem = simplify_gen_unary (NOT, mode, XEXP (op1, 0),
3214 : 1049 : GET_MODE (XEXP (op1, 0)));
3215 : 1049 : return simplify_gen_binary (AND, mode, op0, tem);
3216 : : }
3217 : : }
3218 : :
3219 : : /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
3220 : : by reversing the comparison code if valid. */
3221 : 25823840 : if (STORE_FLAG_VALUE == 1
3222 : 25823840 : && trueop0 == const1_rtx
3223 : 924311 : && COMPARISON_P (op1)
3224 : 25935822 : && (reversed = reversed_comparison (op1, mode)))
3225 : : return reversed;
3226 : :
3227 : : /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A). */
3228 : 25711881 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3229 : 25710637 : && GET_CODE (op1) == MULT
3230 : 25936794 : && GET_CODE (XEXP (op1, 0)) == NEG)
3231 : : {
3232 : 169 : rtx in1, in2;
3233 : :
3234 : 169 : in1 = XEXP (XEXP (op1, 0), 0);
3235 : 169 : in2 = XEXP (op1, 1);
3236 : 169 : return simplify_gen_binary (PLUS, mode,
3237 : : simplify_gen_binary (MULT, mode,
3238 : : in1, in2),
3239 : 169 : op0);
3240 : : }
3241 : :
3242 : : /* Canonicalize (minus (neg A) (mult B C)) to
3243 : : (minus (mult (neg B) C) A). */
3244 : 25711712 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3245 : 25710468 : && GET_CODE (op1) == MULT
3246 : 25936456 : && GET_CODE (op0) == NEG)
3247 : : {
3248 : 739 : rtx in1, in2;
3249 : :
3250 : 739 : in1 = simplify_gen_unary (NEG, mode, XEXP (op1, 0), mode);
3251 : 739 : in2 = XEXP (op1, 1);
3252 : 739 : return simplify_gen_binary (MINUS, mode,
3253 : : simplify_gen_binary (MULT, mode,
3254 : : in1, in2),
3255 : 739 : XEXP (op0, 0));
3256 : : }
3257 : :
3258 : : /* If one of the operands is a PLUS or a MINUS, see if we can
3259 : : simplify this by the associative law. This will, for example,
3260 : : canonicalize (minus A (plus B C)) to (minus (minus A B) C).
3261 : : Don't use the associative law for floating point.
3262 : : The inaccuracy makes it nonassociative,
3263 : : and subtle programs can break if operations are associated. */
3264 : :
3265 : 25710973 : if (INTEGRAL_MODE_P (mode)
3266 : 24984429 : && (plus_minus_operand_p (op0)
3267 : 23062570 : || plus_minus_operand_p (op1))
3268 : 2896020 : && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
3269 : : return tem;
3270 : :
3271 : : /* Handle vector series. */
3272 : 22915962 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3273 : : {
3274 : 252812 : tem = simplify_binary_operation_series (code, mode, op0, op1);
3275 : 252812 : if (tem)
3276 : : return tem;
3277 : : }
3278 : : break;
3279 : :
3280 : 10202884 : case MULT:
3281 : 10202884 : if (trueop1 == constm1_rtx)
3282 : 30177 : return simplify_gen_unary (NEG, mode, op0, mode);
3283 : :
3284 : 10172707 : if (GET_CODE (op0) == NEG)
3285 : : {
3286 : 33629 : rtx temp = simplify_unary_operation (NEG, mode, op1, mode);
3287 : : /* If op1 is a MULT as well and simplify_unary_operation
3288 : : just moved the NEG to the second operand, simplify_gen_binary
3289 : : below could through simplify_associative_operation move
3290 : : the NEG around again and recurse endlessly. */
3291 : 33629 : if (temp
3292 : 1491 : && GET_CODE (op1) == MULT
3293 : 0 : && GET_CODE (temp) == MULT
3294 : 0 : && XEXP (op1, 0) == XEXP (temp, 0)
3295 : 0 : && GET_CODE (XEXP (temp, 1)) == NEG
3296 : 0 : && XEXP (op1, 1) == XEXP (XEXP (temp, 1), 0))
3297 : : temp = NULL_RTX;
3298 : : if (temp)
3299 : 1491 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp);
3300 : : }
3301 : 10171216 : if (GET_CODE (op1) == NEG)
3302 : : {
3303 : 1766 : rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
3304 : : /* If op0 is a MULT as well and simplify_unary_operation
3305 : : just moved the NEG to the second operand, simplify_gen_binary
3306 : : below could through simplify_associative_operation move
3307 : : the NEG around again and recurse endlessly. */
3308 : 1766 : if (temp
3309 : 374 : && GET_CODE (op0) == MULT
3310 : 270 : && GET_CODE (temp) == MULT
3311 : 270 : && XEXP (op0, 0) == XEXP (temp, 0)
3312 : 6 : && GET_CODE (XEXP (temp, 1)) == NEG
3313 : 5 : && XEXP (op0, 1) == XEXP (XEXP (temp, 1), 0))
3314 : : temp = NULL_RTX;
3315 : : if (temp)
3316 : 369 : return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
3317 : : }
3318 : :
3319 : : /* Maybe simplify x * 0 to 0. The reduction is not valid if
3320 : : x is NaN, since x * 0 is then also NaN. Nor is it valid
3321 : : when the mode has signed zeros, since multiplying a negative
3322 : : number by 0 will give -0, not 0. */
3323 : 10170847 : if (!HONOR_NANS (mode)
3324 : 9303458 : && !HONOR_SIGNED_ZEROS (mode)
3325 : 9303097 : && trueop1 == CONST0_RTX (mode)
3326 : 10213766 : && ! side_effects_p (op0))
3327 : : return op1;
3328 : :
3329 : : /* In IEEE floating point, x*1 is not equivalent to x for
3330 : : signalling NaNs. */
3331 : 10128994 : if (!HONOR_SNANS (mode)
3332 : 10128994 : && trueop1 == CONST1_RTX (mode))
3333 : : return op0;
3334 : :
3335 : : /* Convert multiply by constant power of two into shift. */
3336 : 9698901 : if (mem_depth == 0 && CONST_SCALAR_INT_P (trueop1))
3337 : : {
3338 : 5595784 : val = wi::exact_log2 (rtx_mode_t (trueop1, mode));
3339 : 5595784 : if (val >= 0)
3340 : 2478794 : return simplify_gen_binary (ASHIFT, mode, op0,
3341 : : gen_int_shift_amount (mode, val));
3342 : : }
3343 : :
3344 : : /* x*2 is x+x and x*(-1) is -x */
3345 : 7220107 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
3346 : 135225 : && SCALAR_FLOAT_MODE_P (GET_MODE (trueop1))
3347 : 135225 : && !DECIMAL_FLOAT_MODE_P (GET_MODE (trueop1))
3348 : 134853 : && GET_MODE (op0) == mode)
3349 : : {
3350 : 134853 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
3351 : :
3352 : 134853 : if (real_equal (d1, &dconst2))
3353 : 519 : return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
3354 : :
3355 : 134334 : if (!HONOR_SNANS (mode)
3356 : 134334 : && real_equal (d1, &dconstm1))
3357 : 22 : return simplify_gen_unary (NEG, mode, op0, mode);
3358 : : }
3359 : :
3360 : : /* Optimize -x * -x as x * x. */
3361 : 7219566 : if (FLOAT_MODE_P (mode)
3362 : 1274745 : && GET_CODE (op0) == NEG
3363 : 19828 : && GET_CODE (op1) == NEG
3364 : 0 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3365 : 0 : && !side_effects_p (XEXP (op0, 0)))
3366 : 0 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3367 : :
3368 : : /* Likewise, optimize abs(x) * abs(x) as x * x. */
3369 : 7219566 : if (SCALAR_FLOAT_MODE_P (mode)
3370 : 1015955 : && GET_CODE (op0) == ABS
3371 : 1059 : && GET_CODE (op1) == ABS
3372 : 0 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3373 : 7219566 : && !side_effects_p (XEXP (op0, 0)))
3374 : 0 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3375 : :
3376 : : /* Reassociate multiplication, but for floating point MULTs
3377 : : only when the user specifies unsafe math optimizations. */
3378 : 7219566 : if (! FLOAT_MODE_P (mode)
3379 : 1274745 : || flag_unsafe_math_optimizations)
3380 : : {
3381 : 6353188 : tem = simplify_associative_operation (code, mode, op0, op1);
3382 : 6353188 : if (tem)
3383 : : return tem;
3384 : : }
3385 : : break;
3386 : :
3387 : 11552813 : case IOR:
3388 : 11552813 : if (trueop1 == CONST0_RTX (mode))
3389 : : return op0;
3390 : 10942147 : if (INTEGRAL_MODE_P (mode)
3391 : 10742337 : && trueop1 == CONSTM1_RTX (mode)
3392 : 5469 : && !side_effects_p (op0))
3393 : : return op1;
3394 : 10936678 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
3395 : : return op0;
3396 : : /* A | (~A) -> -1 */
3397 : 57014 : if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
3398 : 10936433 : || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
3399 : 47 : && ! side_effects_p (op0)
3400 : 10936527 : && GET_MODE_CLASS (mode) != MODE_CC)
3401 : 47 : return CONSTM1_RTX (mode);
3402 : :
3403 : : /* (ior A C) is C if all bits of A that might be nonzero are on in C. */
3404 : 10936433 : if (CONST_INT_P (op1)
3405 : 2678016 : && HWI_COMPUTABLE_MODE_P (mode)
3406 : 2658046 : && (nonzero_bits (op0, mode) & ~UINTVAL (op1)) == 0
3407 : 11275044 : && !side_effects_p (op0))
3408 : : return op1;
3409 : :
3410 : : /* Canonicalize (X & C1) | C2. */
3411 : 10597822 : if (GET_CODE (op0) == AND
3412 : 3179707 : && CONST_INT_P (trueop1)
3413 : 490449 : && CONST_INT_P (XEXP (op0, 1)))
3414 : : {
3415 : 367896 : HOST_WIDE_INT mask = GET_MODE_MASK (mode);
3416 : 367896 : HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
3417 : 367896 : HOST_WIDE_INT c2 = INTVAL (trueop1);
3418 : :
3419 : : /* If (C1&C2) == C1, then (X&C1)|C2 becomes C2. */
3420 : 367896 : if ((c1 & c2) == c1
3421 : 367896 : && !side_effects_p (XEXP (op0, 0)))
3422 : : return trueop1;
3423 : :
3424 : : /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2. */
3425 : 367896 : if (((c1|c2) & mask) == mask)
3426 : 55010 : return simplify_gen_binary (IOR, mode, XEXP (op0, 0), op1);
3427 : : }
3428 : :
3429 : : /* Convert (A & B) | A to A. */
3430 : 10542812 : if (GET_CODE (op0) == AND
3431 : 3124697 : && (rtx_equal_p (XEXP (op0, 0), op1)
3432 : 3124626 : || rtx_equal_p (XEXP (op0, 1), op1))
3433 : 77 : && ! side_effects_p (XEXP (op0, 0))
3434 : 10542889 : && ! side_effects_p (XEXP (op0, 1)))
3435 : : return op1;
3436 : :
3437 : : /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3438 : : mode size to (rotate A CX). */
3439 : :
3440 : 10542735 : if (GET_CODE (op1) == ASHIFT
3441 : 10542735 : || GET_CODE (op1) == SUBREG)
3442 : : {
3443 : : opleft = op1;
3444 : : opright = op0;
3445 : : }
3446 : : else
3447 : : {
3448 : 9124107 : opright = op1;
3449 : 9124107 : opleft = op0;
3450 : : }
3451 : :
3452 : 2306360 : if (GET_CODE (opleft) == ASHIFT && GET_CODE (opright) == LSHIFTRT
3453 : 19507 : && rtx_equal_p (XEXP (opleft, 0), XEXP (opright, 0))
3454 : 2040 : && CONST_INT_P (XEXP (opleft, 1))
3455 : 987 : && CONST_INT_P (XEXP (opright, 1))
3456 : 10542735 : && (INTVAL (XEXP (opleft, 1)) + INTVAL (XEXP (opright, 1))
3457 : 1974 : == GET_MODE_UNIT_PRECISION (mode)))
3458 : 638 : return gen_rtx_ROTATE (mode, XEXP (opright, 0), XEXP (opleft, 1));
3459 : :
3460 : : /* Same, but for ashift that has been "simplified" to a wider mode
3461 : : by simplify_shift_const. */
3462 : :
3463 : 10542097 : if (GET_CODE (opleft) == SUBREG
3464 : 679650 : && is_a <scalar_int_mode> (mode, &int_mode)
3465 : 561888 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (opleft)),
3466 : : &inner_mode)
3467 : 553998 : && GET_CODE (SUBREG_REG (opleft)) == ASHIFT
3468 : 54330 : && GET_CODE (opright) == LSHIFTRT
3469 : 380 : && GET_CODE (XEXP (opright, 0)) == SUBREG
3470 : 76 : && known_eq (SUBREG_BYTE (opleft), SUBREG_BYTE (XEXP (opright, 0)))
3471 : 148 : && GET_MODE_SIZE (int_mode) < GET_MODE_SIZE (inner_mode)
3472 : 74 : && rtx_equal_p (XEXP (SUBREG_REG (opleft), 0),
3473 : 74 : SUBREG_REG (XEXP (opright, 0)))
3474 : 6 : && CONST_INT_P (XEXP (SUBREG_REG (opleft), 1))
3475 : 6 : && CONST_INT_P (XEXP (opright, 1))
3476 : 10542097 : && (INTVAL (XEXP (SUBREG_REG (opleft), 1))
3477 : 6 : + INTVAL (XEXP (opright, 1))
3478 : 6 : == GET_MODE_PRECISION (int_mode)))
3479 : 1 : return gen_rtx_ROTATE (int_mode, XEXP (opright, 0),
3480 : : XEXP (SUBREG_REG (opleft), 1));
3481 : :
3482 : : /* If OP0 is (ashiftrt (plus ...) C), it might actually be
3483 : : a (sign_extend (plus ...)). Then check if OP1 is a CONST_INT and
3484 : : the PLUS does not affect any of the bits in OP1: then we can do
3485 : : the IOR as a PLUS and we can associate. This is valid if OP1
3486 : : can be safely shifted left C bits. */
3487 : 10542096 : if (CONST_INT_P (trueop1) && GET_CODE (op0) == ASHIFTRT
3488 : 6630 : && GET_CODE (XEXP (op0, 0)) == PLUS
3489 : 138 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
3490 : 84 : && CONST_INT_P (XEXP (op0, 1))
3491 : 84 : && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
3492 : : {
3493 : 84 : int count = INTVAL (XEXP (op0, 1));
3494 : 84 : HOST_WIDE_INT mask = UINTVAL (trueop1) << count;
3495 : :
3496 : 84 : if (mask >> count == INTVAL (trueop1)
3497 : 77 : && trunc_int_for_mode (mask, mode) == mask
3498 : 151 : && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
3499 : 0 : return simplify_gen_binary (ASHIFTRT, mode,
3500 : : plus_constant (mode, XEXP (op0, 0),
3501 : : mask),
3502 : : XEXP (op0, 1));
3503 : : }
3504 : :
3505 : : /* The following happens with bitfield merging.
3506 : : (X & C) | ((X | Y) & ~C) -> X | (Y & ~C) */
3507 : 10542096 : if (GET_CODE (op0) == AND
3508 : 3124620 : && GET_CODE (op1) == AND
3509 : 236672 : && CONST_INT_P (XEXP (op0, 1))
3510 : 88093 : && CONST_INT_P (XEXP (op1, 1))
3511 : 82772 : && (INTVAL (XEXP (op0, 1))
3512 : 82772 : == ~INTVAL (XEXP (op1, 1))))
3513 : : {
3514 : : /* The IOR may be on both sides. */
3515 : 28763 : rtx top0 = NULL_RTX, top1 = NULL_RTX;
3516 : 28763 : if (GET_CODE (XEXP (op1, 0)) == IOR)
3517 : : top0 = op0, top1 = op1;
3518 : 28718 : else if (GET_CODE (XEXP (op0, 0)) == IOR)
3519 : 0 : top0 = op1, top1 = op0;
3520 : 28763 : if (top0 && top1)
3521 : : {
3522 : : /* X may be on either side of the inner IOR. */
3523 : 45 : rtx tem = NULL_RTX;
3524 : 45 : if (rtx_equal_p (XEXP (top0, 0),
3525 : 45 : XEXP (XEXP (top1, 0), 0)))
3526 : 43 : tem = XEXP (XEXP (top1, 0), 1);
3527 : 2 : else if (rtx_equal_p (XEXP (top0, 0),
3528 : 2 : XEXP (XEXP (top1, 0), 1)))
3529 : 2 : tem = XEXP (XEXP (top1, 0), 0);
3530 : 45 : if (tem)
3531 : 45 : return simplify_gen_binary (IOR, mode, XEXP (top0, 0),
3532 : : simplify_gen_binary
3533 : 45 : (AND, mode, tem, XEXP (top1, 1)));
3534 : : }
3535 : : }
3536 : :
3537 : : /* Convert (ior (and A C) (and B C)) into (and (ior A B) C). */
3538 : 10542051 : if (GET_CODE (op0) == GET_CODE (op1)
3539 : 2801053 : && (GET_CODE (op0) == AND
3540 : : || GET_CODE (op0) == IOR
3541 : 2801053 : || GET_CODE (op0) == LSHIFTRT
3542 : 2563772 : || GET_CODE (op0) == ASHIFTRT
3543 : 2563680 : || GET_CODE (op0) == ASHIFT
3544 : 2548051 : || GET_CODE (op0) == ROTATE
3545 : 2548051 : || GET_CODE (op0) == ROTATERT))
3546 : : {
3547 : 253002 : tem = simplify_distributive_operation (code, mode, op0, op1);
3548 : 253002 : if (tem)
3549 : : return tem;
3550 : : }
3551 : :
3552 : 10466177 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3553 : 10466177 : if (tem)
3554 : : return tem;
3555 : :
3556 : 10466149 : tem = simplify_associative_operation (code, mode, op0, op1);
3557 : 10466149 : if (tem)
3558 : : return tem;
3559 : :
3560 : 10362169 : tem = simplify_logical_relational_operation (code, mode, op0, op1);
3561 : 10362169 : if (tem)
3562 : : return tem;
3563 : : break;
3564 : :
3565 : 1115639 : case XOR:
3566 : 1115639 : if (trueop1 == CONST0_RTX (mode))
3567 : : return op0;
3568 : 1079196 : if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
3569 : 19942 : return simplify_gen_unary (NOT, mode, op0, mode);
3570 : 1059254 : if (rtx_equal_p (trueop0, trueop1)
3571 : 1073 : && ! side_effects_p (op0)
3572 : 1060327 : && GET_MODE_CLASS (mode) != MODE_CC)
3573 : 1073 : return CONST0_RTX (mode);
3574 : :
3575 : : /* Canonicalize XOR of the most significant bit to PLUS. */
3576 : 1058181 : if (CONST_SCALAR_INT_P (op1)
3577 : 1058181 : && mode_signbit_p (mode, op1))
3578 : 34368 : return simplify_gen_binary (PLUS, mode, op0, op1);
3579 : : /* (xor (plus X C1) C2) is (xor X (C1^C2)) if C1 is signbit. */
3580 : 1023813 : if (CONST_SCALAR_INT_P (op1)
3581 : 376866 : && GET_CODE (op0) == PLUS
3582 : 2317 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
3583 : 1025276 : && mode_signbit_p (mode, XEXP (op0, 1)))
3584 : 126 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3585 : : simplify_gen_binary (XOR, mode, op1,
3586 : 126 : XEXP (op0, 1)));
3587 : :
3588 : : /* If we are XORing two things that have no bits in common,
3589 : : convert them into an IOR. This helps to detect rotation encoded
3590 : : using those methods and possibly other simplifications. */
3591 : :
3592 : 1023687 : if (HWI_COMPUTABLE_MODE_P (mode)
3593 : 1023687 : && (nonzero_bits (op0, mode)
3594 : 906335 : & nonzero_bits (op1, mode)) == 0)
3595 : 7133 : return (simplify_gen_binary (IOR, mode, op0, op1));
3596 : :
3597 : : /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
3598 : : Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
3599 : : (NOT y). */
3600 : 1016554 : {
3601 : 1016554 : int num_negated = 0;
3602 : :
3603 : 1016554 : if (GET_CODE (op0) == NOT)
3604 : 457 : num_negated++, op0 = XEXP (op0, 0);
3605 : 1016554 : if (GET_CODE (op1) == NOT)
3606 : 0 : num_negated++, op1 = XEXP (op1, 0);
3607 : :
3608 : 0 : if (num_negated == 2)
3609 : 0 : return simplify_gen_binary (XOR, mode, op0, op1);
3610 : 1016554 : else if (num_negated == 1)
3611 : 457 : return simplify_gen_unary (NOT, mode,
3612 : : simplify_gen_binary (XOR, mode, op0, op1),
3613 : 457 : mode);
3614 : : }
3615 : :
3616 : : /* Convert (xor (and A B) B) to (and (not A) B). The latter may
3617 : : correspond to a machine insn or result in further simplifications
3618 : : if B is a constant. */
3619 : :
3620 : 1016097 : if (GET_CODE (op0) == AND
3621 : 91587 : && rtx_equal_p (XEXP (op0, 1), op1)
3622 : 1028137 : && ! side_effects_p (op1))
3623 : 12040 : return simplify_gen_binary (AND, mode,
3624 : : simplify_gen_unary (NOT, mode,
3625 : : XEXP (op0, 0), mode),
3626 : 12040 : op1);
3627 : :
3628 : 1004057 : else if (GET_CODE (op0) == AND
3629 : 79547 : && rtx_equal_p (XEXP (op0, 0), op1)
3630 : 1005688 : && ! side_effects_p (op1))
3631 : 1631 : return simplify_gen_binary (AND, mode,
3632 : : simplify_gen_unary (NOT, mode,
3633 : : XEXP (op0, 1), mode),
3634 : 1631 : op1);
3635 : :
3636 : : /* Given (xor (ior (xor A B) C) D), where B, C and D are
3637 : : constants, simplify to (xor (ior A C) (B&~C)^D), canceling
3638 : : out bits inverted twice and not set by C. Similarly, given
3639 : : (xor (and (xor A B) C) D), simplify without inverting C in
3640 : : the xor operand: (xor (and A C) (B&C)^D).
3641 : : */
3642 : 1002426 : else if ((GET_CODE (op0) == IOR || GET_CODE (op0) == AND)
3643 : 90067 : && GET_CODE (XEXP (op0, 0)) == XOR
3644 : 2627 : && CONST_INT_P (op1)
3645 : 101 : && CONST_INT_P (XEXP (op0, 1))
3646 : 90 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
3647 : : {
3648 : 90 : enum rtx_code op = GET_CODE (op0);
3649 : 90 : rtx a = XEXP (XEXP (op0, 0), 0);
3650 : 90 : rtx b = XEXP (XEXP (op0, 0), 1);
3651 : 90 : rtx c = XEXP (op0, 1);
3652 : 90 : rtx d = op1;
3653 : 90 : HOST_WIDE_INT bval = INTVAL (b);
3654 : 90 : HOST_WIDE_INT cval = INTVAL (c);
3655 : 90 : HOST_WIDE_INT dval = INTVAL (d);
3656 : 90 : HOST_WIDE_INT xcval;
3657 : :
3658 : 90 : if (op == IOR)
3659 : 8 : xcval = ~cval;
3660 : : else
3661 : : xcval = cval;
3662 : :
3663 : 90 : return simplify_gen_binary (XOR, mode,
3664 : : simplify_gen_binary (op, mode, a, c),
3665 : 180 : gen_int_mode ((bval & xcval) ^ dval,
3666 : : mode));
3667 : : }
3668 : :
3669 : : /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P),
3670 : : we can transform like this:
3671 : : (A&B)^C == ~(A&B)&C | ~C&(A&B)
3672 : : == (~A|~B)&C | ~C&(A&B) * DeMorgan's Law
3673 : : == ~A&C | ~B&C | A&(~C&B) * Distribute and re-order
3674 : : Attempt a few simplifications when B and C are both constants. */
3675 : 1002336 : if (GET_CODE (op0) == AND
3676 : 77834 : && CONST_INT_P (op1)
3677 : 10473 : && CONST_INT_P (XEXP (op0, 1)))
3678 : : {
3679 : 8815 : rtx a = XEXP (op0, 0);
3680 : 8815 : rtx b = XEXP (op0, 1);
3681 : 8815 : rtx c = op1;
3682 : 8815 : HOST_WIDE_INT bval = INTVAL (b);
3683 : 8815 : HOST_WIDE_INT cval = INTVAL (c);
3684 : :
3685 : : /* Instead of computing ~A&C, we compute its negated value,
3686 : : ~(A|~C). If it yields -1, ~A&C is zero, so we can
3687 : : optimize for sure. If it does not simplify, we still try
3688 : : to compute ~A&C below, but since that always allocates
3689 : : RTL, we don't try that before committing to returning a
3690 : : simplified expression. */
3691 : 8815 : rtx n_na_c = simplify_binary_operation (IOR, mode, a,
3692 : : GEN_INT (~cval));
3693 : :
3694 : 8815 : if ((~cval & bval) == 0)
3695 : : {
3696 : 361 : rtx na_c = NULL_RTX;
3697 : 361 : if (n_na_c)
3698 : 0 : na_c = simplify_gen_unary (NOT, mode, n_na_c, mode);
3699 : : else
3700 : : {
3701 : : /* If ~A does not simplify, don't bother: we don't
3702 : : want to simplify 2 operations into 3, and if na_c
3703 : : were to simplify with na, n_na_c would have
3704 : : simplified as well. */
3705 : 361 : rtx na = simplify_unary_operation (NOT, mode, a, mode);
3706 : 361 : if (na)
3707 : 0 : na_c = simplify_gen_binary (AND, mode, na, c);
3708 : : }
3709 : :
3710 : : /* Try to simplify ~A&C | ~B&C. */
3711 : 0 : if (na_c != NULL_RTX)
3712 : 0 : return simplify_gen_binary (IOR, mode, na_c,
3713 : 0 : gen_int_mode (~bval & cval, mode));
3714 : : }
3715 : : else
3716 : : {
3717 : : /* If ~A&C is zero, simplify A&(~C&B) | ~B&C. */
3718 : 8454 : if (n_na_c == CONSTM1_RTX (mode))
3719 : : {
3720 : 0 : rtx a_nc_b = simplify_gen_binary (AND, mode, a,
3721 : 0 : gen_int_mode (~cval & bval,
3722 : : mode));
3723 : 0 : return simplify_gen_binary (IOR, mode, a_nc_b,
3724 : 0 : gen_int_mode (~bval & cval,
3725 : : mode));
3726 : : }
3727 : : }
3728 : : }
3729 : :
3730 : : /* If we have (xor (and (xor A B) C) A) with C a constant we can instead
3731 : : do (ior (and A ~C) (and B C)) which is a machine instruction on some
3732 : : machines, and also has shorter instruction path length. */
3733 : 1002336 : if (GET_CODE (op0) == AND
3734 : 77834 : && GET_CODE (XEXP (op0, 0)) == XOR
3735 : 2498 : && CONST_INT_P (XEXP (op0, 1))
3736 : 1003019 : && rtx_equal_p (XEXP (XEXP (op0, 0), 0), trueop1))
3737 : : {
3738 : 7 : rtx a = trueop1;
3739 : 7 : rtx b = XEXP (XEXP (op0, 0), 1);
3740 : 7 : rtx c = XEXP (op0, 1);
3741 : 7 : rtx nc = simplify_gen_unary (NOT, mode, c, mode);
3742 : 7 : rtx a_nc = simplify_gen_binary (AND, mode, a, nc);
3743 : 7 : rtx bc = simplify_gen_binary (AND, mode, b, c);
3744 : 7 : return simplify_gen_binary (IOR, mode, a_nc, bc);
3745 : : }
3746 : : /* Similarly, (xor (and (xor A B) C) B) as (ior (and A C) (and B ~C)) */
3747 : 1002329 : else if (GET_CODE (op0) == AND
3748 : 77827 : && GET_CODE (XEXP (op0, 0)) == XOR
3749 : 2491 : && CONST_INT_P (XEXP (op0, 1))
3750 : 1003005 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), trueop1))
3751 : : {
3752 : 8 : rtx a = XEXP (XEXP (op0, 0), 0);
3753 : 8 : rtx b = trueop1;
3754 : 8 : rtx c = XEXP (op0, 1);
3755 : 8 : rtx nc = simplify_gen_unary (NOT, mode, c, mode);
3756 : 8 : rtx b_nc = simplify_gen_binary (AND, mode, b, nc);
3757 : 8 : rtx ac = simplify_gen_binary (AND, mode, a, c);
3758 : 8 : return simplify_gen_binary (IOR, mode, ac, b_nc);
3759 : : }
3760 : :
3761 : : /* (xor (comparison foo bar) (const_int 1)) can become the reversed
3762 : : comparison if STORE_FLAG_VALUE is 1. */
3763 : 1002321 : if (STORE_FLAG_VALUE == 1
3764 : 1002321 : && trueop1 == const1_rtx
3765 : 153485 : && COMPARISON_P (op0)
3766 : 1006242 : && (reversed = reversed_comparison (op0, mode)))
3767 : : return reversed;
3768 : :
3769 : : /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
3770 : : is (lt foo (const_int 0)), so we can perform the above
3771 : : simplification if STORE_FLAG_VALUE is 1. */
3772 : :
3773 : 998488 : if (is_a <scalar_int_mode> (mode, &int_mode)
3774 : : && STORE_FLAG_VALUE == 1
3775 : 885264 : && trueop1 == const1_rtx
3776 : 149652 : && GET_CODE (op0) == LSHIFTRT
3777 : 32211 : && CONST_INT_P (XEXP (op0, 1))
3778 : 1030699 : && INTVAL (XEXP (op0, 1)) == GET_MODE_PRECISION (int_mode) - 1)
3779 : 31723 : return gen_rtx_GE (int_mode, XEXP (op0, 0), const0_rtx);
3780 : :
3781 : : /* (xor (comparison foo bar) (const_int sign-bit))
3782 : : when STORE_FLAG_VALUE is the sign bit. */
3783 : 966765 : if (is_a <scalar_int_mode> (mode, &int_mode)
3784 : 853541 : && val_signbit_p (int_mode, STORE_FLAG_VALUE)
3785 : 0 : && trueop1 == const_true_rtx
3786 : 0 : && COMPARISON_P (op0)
3787 : 966765 : && (reversed = reversed_comparison (op0, int_mode)))
3788 : : return reversed;
3789 : :
3790 : : /* Convert (xor (and A C) (and B C)) into (and (xor A B) C). */
3791 : 966765 : if (GET_CODE (op0) == GET_CODE (op1)
3792 : 290410 : && (GET_CODE (op0) == AND
3793 : 290410 : || GET_CODE (op0) == LSHIFTRT
3794 : 251458 : || GET_CODE (op0) == ASHIFTRT
3795 : 251408 : || GET_CODE (op0) == ASHIFT
3796 : 251259 : || GET_CODE (op0) == ROTATE
3797 : 251167 : || GET_CODE (op0) == ROTATERT))
3798 : : {
3799 : 39718 : tem = simplify_distributive_operation (code, mode, op0, op1);
3800 : 39718 : if (tem)
3801 : : return tem;
3802 : : }
3803 : :
3804 : 928664 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3805 : 928664 : if (tem)
3806 : : return tem;
3807 : :
3808 : 928664 : tem = simplify_associative_operation (code, mode, op0, op1);
3809 : 928664 : if (tem)
3810 : : return tem;
3811 : : break;
3812 : :
3813 : 19906748 : case AND:
3814 : 19906748 : if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
3815 : : return trueop1;
3816 : 19707214 : if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
3817 : : return op0;
3818 : 19355402 : if (HWI_COMPUTABLE_MODE_P (mode))
3819 : : {
3820 : : /* When WORD_REGISTER_OPERATIONS is true, we need to know the
3821 : : nonzero bits in WORD_MODE rather than MODE. */
3822 : 17155085 : scalar_int_mode tmode = as_a <scalar_int_mode> (mode);
3823 : 17155085 : if (WORD_REGISTER_OPERATIONS
3824 : : && GET_MODE_BITSIZE (tmode) < BITS_PER_WORD)
3825 : : tmode = word_mode;
3826 : 17155085 : HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, tmode);
3827 : 17155085 : HOST_WIDE_INT nzop1;
3828 : 17155085 : if (CONST_INT_P (trueop1))
3829 : : {
3830 : 14625098 : HOST_WIDE_INT val1 = INTVAL (trueop1);
3831 : : /* If we are turning off bits already known off in OP0, we need
3832 : : not do an AND. */
3833 : 14625098 : if ((nzop0 & ~val1) == 0)
3834 : 346916 : return op0;
3835 : : }
3836 : 16831595 : nzop1 = nonzero_bits (trueop1, mode);
3837 : : /* If we are clearing all the nonzero bits, the result is zero. */
3838 : 16831595 : if ((nzop1 & nzop0) == 0
3839 : 16831595 : && !side_effects_p (op0) && !side_effects_p (op1))
3840 : 23426 : return CONST0_RTX (mode);
3841 : : }
3842 : 19009616 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
3843 : 19009616 : && GET_MODE_CLASS (mode) != MODE_CC)
3844 : : return op0;
3845 : : /* A & (~A) -> 0 */
3846 : 519508 : if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
3847 : 19004789 : || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
3848 : 2613 : && ! side_effects_p (op0)
3849 : 19009969 : && GET_MODE_CLASS (mode) != MODE_CC)
3850 : 2613 : return CONST0_RTX (mode);
3851 : :
3852 : : /* Transform (and (extend X) C) into (zero_extend (and X C)) if
3853 : : there are no nonzero bits of C outside of X's mode. */
3854 : 38009486 : if ((GET_CODE (op0) == SIGN_EXTEND
3855 : 19004743 : || GET_CODE (op0) == ZERO_EXTEND)
3856 : 76881 : && CONST_SCALAR_INT_P (trueop1)
3857 : 69284 : && is_a <scalar_int_mode> (mode, &int_mode)
3858 : 69284 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
3859 : 19074027 : && (wi::mask (GET_MODE_PRECISION (inner_mode), true,
3860 : 69284 : GET_MODE_PRECISION (int_mode))
3861 : 19074027 : & rtx_mode_t (trueop1, mode)) == 0)
3862 : : {
3863 : 67524 : machine_mode imode = GET_MODE (XEXP (op0, 0));
3864 : 67524 : tem = immed_wide_int_const (rtx_mode_t (trueop1, mode), imode);
3865 : 67524 : tem = simplify_gen_binary (AND, imode, XEXP (op0, 0), tem);
3866 : 67524 : return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
3867 : : }
3868 : :
3869 : : /* Transform (and (truncate X) C) into (truncate (and X C)). This way
3870 : : we might be able to further simplify the AND with X and potentially
3871 : : remove the truncation altogether. */
3872 : 18937219 : if (GET_CODE (op0) == TRUNCATE && CONST_INT_P (trueop1))
3873 : : {
3874 : 6 : rtx x = XEXP (op0, 0);
3875 : 6 : machine_mode xmode = GET_MODE (x);
3876 : 6 : tem = simplify_gen_binary (AND, xmode, x,
3877 : 6 : gen_int_mode (INTVAL (trueop1), xmode));
3878 : 6 : return simplify_gen_unary (TRUNCATE, mode, tem, xmode);
3879 : : }
3880 : :
3881 : : /* Canonicalize (A | C1) & C2 as (A & C2) | (C1 & C2). */
3882 : 18937213 : if (GET_CODE (op0) == IOR
3883 : 1187339 : && CONST_INT_P (trueop1)
3884 : 173046 : && CONST_INT_P (XEXP (op0, 1)))
3885 : : {
3886 : 119572 : HOST_WIDE_INT tmp = INTVAL (trueop1) & INTVAL (XEXP (op0, 1));
3887 : 119572 : return simplify_gen_binary (IOR, mode,
3888 : : simplify_gen_binary (AND, mode,
3889 : : XEXP (op0, 0), op1),
3890 : : gen_int_mode (tmp, mode));
3891 : : }
3892 : :
3893 : : /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
3894 : : insn (and may simplify more). */
3895 : 18817641 : if (GET_CODE (op0) == XOR
3896 : 82017 : && rtx_equal_p (XEXP (op0, 0), op1)
3897 : 18817652 : && ! side_effects_p (op1))
3898 : 11 : return simplify_gen_binary (AND, mode,
3899 : : simplify_gen_unary (NOT, mode,
3900 : : XEXP (op0, 1), mode),
3901 : 11 : op1);
3902 : :
3903 : 18817630 : if (GET_CODE (op0) == XOR
3904 : 82006 : && rtx_equal_p (XEXP (op0, 1), op1)
3905 : 18819489 : && ! side_effects_p (op1))
3906 : 1859 : return simplify_gen_binary (AND, mode,
3907 : : simplify_gen_unary (NOT, mode,
3908 : : XEXP (op0, 0), mode),
3909 : 1859 : op1);
3910 : :
3911 : : /* Similarly for (~(A ^ B)) & A. */
3912 : 18815771 : if (GET_CODE (op0) == NOT
3913 : 516941 : && GET_CODE (XEXP (op0, 0)) == XOR
3914 : 1574 : && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
3915 : 18815771 : && ! side_effects_p (op1))
3916 : 0 : return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
3917 : :
3918 : 18815771 : if (GET_CODE (op0) == NOT
3919 : 516941 : && GET_CODE (XEXP (op0, 0)) == XOR
3920 : 1574 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
3921 : 18815771 : && ! side_effects_p (op1))
3922 : 0 : return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
3923 : :
3924 : : /* Convert (A | B) & A to A. */
3925 : 18815771 : if (GET_CODE (op0) == IOR
3926 : 1067767 : && (rtx_equal_p (XEXP (op0, 0), op1)
3927 : 1067729 : || rtx_equal_p (XEXP (op0, 1), op1))
3928 : 47 : && ! side_effects_p (XEXP (op0, 0))
3929 : 18815818 : && ! side_effects_p (XEXP (op0, 1)))
3930 : : return op1;
3931 : :
3932 : : /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
3933 : : ((A & N) + B) & M -> (A + B) & M
3934 : : Similarly if (N & M) == 0,
3935 : : ((A | N) + B) & M -> (A + B) & M
3936 : : and for - instead of + and/or ^ instead of |.
3937 : : Also, if (N & M) == 0, then
3938 : : (A +- N) & M -> A & M. */
3939 : 18815724 : if (CONST_INT_P (trueop1)
3940 : 14180108 : && HWI_COMPUTABLE_MODE_P (mode)
3941 : 14153716 : && ~UINTVAL (trueop1)
3942 : 14153716 : && (UINTVAL (trueop1) & (UINTVAL (trueop1) + 1)) == 0
3943 : 28028469 : && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS))
3944 : : {
3945 : 798668 : rtx pmop[2];
3946 : 798668 : int which;
3947 : :
3948 : 798668 : pmop[0] = XEXP (op0, 0);
3949 : 798668 : pmop[1] = XEXP (op0, 1);
3950 : :
3951 : 798668 : if (CONST_INT_P (pmop[1])
3952 : 400764 : && (UINTVAL (pmop[1]) & UINTVAL (trueop1)) == 0)
3953 : 122588 : return simplify_gen_binary (AND, mode, pmop[0], op1);
3954 : :
3955 : 2049204 : for (which = 0; which < 2; which++)
3956 : : {
3957 : 1366136 : tem = pmop[which];
3958 : 1366136 : switch (GET_CODE (tem))
3959 : : {
3960 : 10720 : case AND:
3961 : 10720 : if (CONST_INT_P (XEXP (tem, 1))
3962 : 9322 : && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1))
3963 : : == UINTVAL (trueop1))
3964 : 6937 : pmop[which] = XEXP (tem, 0);
3965 : : break;
3966 : 1794 : case IOR:
3967 : 1794 : case XOR:
3968 : 1794 : if (CONST_INT_P (XEXP (tem, 1))
3969 : 344 : && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1)) == 0)
3970 : 51 : pmop[which] = XEXP (tem, 0);
3971 : : break;
3972 : : default:
3973 : : break;
3974 : : }
3975 : : }
3976 : :
3977 : 683068 : if (pmop[0] != XEXP (op0, 0) || pmop[1] != XEXP (op0, 1))
3978 : : {
3979 : 6988 : tem = simplify_gen_binary (GET_CODE (op0), mode,
3980 : : pmop[0], pmop[1]);
3981 : 6988 : return simplify_gen_binary (code, mode, tem, op1);
3982 : : }
3983 : : }
3984 : :
3985 : : /* (and X (ior (not X) Y) -> (and X Y) */
3986 : 18693136 : if (GET_CODE (op1) == IOR
3987 : 821983 : && GET_CODE (XEXP (op1, 0)) == NOT
3988 : 18697026 : && rtx_equal_p (op0, XEXP (XEXP (op1, 0), 0)))
3989 : 0 : return simplify_gen_binary (AND, mode, op0, XEXP (op1, 1));
3990 : :
3991 : : /* (and (ior (not X) Y) X) -> (and X Y) */
3992 : 18693136 : if (GET_CODE (op0) == IOR
3993 : 1067720 : && GET_CODE (XEXP (op0, 0)) == NOT
3994 : 18733054 : && rtx_equal_p (op1, XEXP (XEXP (op0, 0), 0)))
3995 : 6 : return simplify_gen_binary (AND, mode, op1, XEXP (op0, 1));
3996 : :
3997 : : /* (and X (ior Y (not X)) -> (and X Y) */
3998 : 18693130 : if (GET_CODE (op1) == IOR
3999 : 821983 : && GET_CODE (XEXP (op1, 1)) == NOT
4000 : 18693137 : && rtx_equal_p (op0, XEXP (XEXP (op1, 1), 0)))
4001 : 0 : return simplify_gen_binary (AND, mode, op0, XEXP (op1, 0));
4002 : :
4003 : : /* (and (ior Y (not X)) X) -> (and X Y) */
4004 : 18693130 : if (GET_CODE (op0) == IOR
4005 : 1067714 : && GET_CODE (XEXP (op0, 1)) == NOT
4006 : 18699286 : && rtx_equal_p (op1, XEXP (XEXP (op0, 1), 0)))
4007 : 1 : return simplify_gen_binary (AND, mode, op1, XEXP (op0, 0));
4008 : :
4009 : : /* Convert (and (ior A C) (ior B C)) into (ior (and A B) C). */
4010 : 18693129 : if (GET_CODE (op0) == GET_CODE (op1)
4011 : 1797974 : && (GET_CODE (op0) == AND
4012 : : || GET_CODE (op0) == IOR
4013 : 1797974 : || GET_CODE (op0) == LSHIFTRT
4014 : 976151 : || GET_CODE (op0) == ASHIFTRT
4015 : 976054 : || GET_CODE (op0) == ASHIFT
4016 : 975970 : || GET_CODE (op0) == ROTATE
4017 : 975970 : || GET_CODE (op0) == ROTATERT))
4018 : : {
4019 : 822004 : tem = simplify_distributive_operation (code, mode, op0, op1);
4020 : 822004 : if (tem)
4021 : : return tem;
4022 : : }
4023 : :
4024 : 17903528 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
4025 : 17903528 : if (tem)
4026 : : return tem;
4027 : :
4028 : 17903405 : tem = simplify_associative_operation (code, mode, op0, op1);
4029 : 17903405 : if (tem)
4030 : : return tem;
4031 : : break;
4032 : :
4033 : 785100 : case UDIV:
4034 : : /* 0/x is 0 (or x&0 if x has side-effects). */
4035 : 785100 : if (trueop0 == CONST0_RTX (mode)
4036 : 274 : && !cfun->can_throw_non_call_exceptions)
4037 : : {
4038 : 274 : if (side_effects_p (op1))
4039 : 0 : return simplify_gen_binary (AND, mode, op1, trueop0);
4040 : : return trueop0;
4041 : : }
4042 : : /* x/1 is x. */
4043 : 784826 : if (trueop1 == CONST1_RTX (mode))
4044 : : {
4045 : 217571 : tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4046 : 217571 : if (tem)
4047 : : return tem;
4048 : : }
4049 : : /* Convert divide by power of two into shift. */
4050 : 567255 : if (CONST_INT_P (trueop1)
4051 : 567255 : && (val = exact_log2 (UINTVAL (trueop1))) > 0)
4052 : 265935 : return simplify_gen_binary (LSHIFTRT, mode, op0,
4053 : : gen_int_shift_amount (mode, val));
4054 : : break;
4055 : :
4056 : 875230 : case DIV:
4057 : : /* Handle floating point and integers separately. */
4058 : 875230 : if (SCALAR_FLOAT_MODE_P (mode))
4059 : : {
4060 : : /* Maybe change 0.0 / x to 0.0. This transformation isn't
4061 : : safe for modes with NaNs, since 0.0 / 0.0 will then be
4062 : : NaN rather than 0.0. Nor is it safe for modes with signed
4063 : : zeros, since dividing 0 by a negative number gives -0.0 */
4064 : 272014 : if (trueop0 == CONST0_RTX (mode)
4065 : 2918 : && !HONOR_NANS (mode)
4066 : 13 : && !HONOR_SIGNED_ZEROS (mode)
4067 : 272027 : && ! side_effects_p (op1))
4068 : : return op0;
4069 : : /* x/1.0 is x. */
4070 : 272001 : if (trueop1 == CONST1_RTX (mode)
4071 : 272001 : && !HONOR_SNANS (mode))
4072 : : return op0;
4073 : :
4074 : 271998 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
4075 : 22475 : && trueop1 != CONST0_RTX (mode))
4076 : : {
4077 : 16810 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
4078 : :
4079 : : /* x/-1.0 is -x. */
4080 : 16810 : if (real_equal (d1, &dconstm1)
4081 : 16810 : && !HONOR_SNANS (mode))
4082 : 0 : return simplify_gen_unary (NEG, mode, op0, mode);
4083 : :
4084 : : /* Change FP division by a constant into multiplication.
4085 : : Only do this with -freciprocal-math. */
4086 : 16810 : if (flag_reciprocal_math
4087 : 16810 : && !real_equal (d1, &dconst0))
4088 : : {
4089 : 3 : REAL_VALUE_TYPE d;
4090 : 3 : real_arithmetic (&d, RDIV_EXPR, &dconst1, d1);
4091 : 3 : tem = const_double_from_real_value (d, mode);
4092 : 3 : return simplify_gen_binary (MULT, mode, op0, tem);
4093 : : }
4094 : : }
4095 : : }
4096 : 603216 : else if (SCALAR_INT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
4097 : : {
4098 : : /* 0/x is 0 (or x&0 if x has side-effects). */
4099 : 586537 : if (trueop0 == CONST0_RTX (mode)
4100 : 543 : && !cfun->can_throw_non_call_exceptions)
4101 : : {
4102 : 501 : if (side_effects_p (op1))
4103 : 8 : return simplify_gen_binary (AND, mode, op1, trueop0);
4104 : : return trueop0;
4105 : : }
4106 : : /* x/1 is x. */
4107 : 586036 : if (trueop1 == CONST1_RTX (mode))
4108 : : {
4109 : 247 : tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4110 : 247 : if (tem)
4111 : : return tem;
4112 : : }
4113 : : /* x/-1 is -x. */
4114 : 585789 : if (trueop1 == CONSTM1_RTX (mode))
4115 : : {
4116 : 226 : rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4117 : 226 : if (x)
4118 : 226 : return simplify_gen_unary (NEG, mode, x, mode);
4119 : : }
4120 : : }
4121 : : break;
4122 : :
4123 : 759004 : case UMOD:
4124 : : /* 0%x is 0 (or x&0 if x has side-effects). */
4125 : 759004 : if (trueop0 == CONST0_RTX (mode))
4126 : : {
4127 : 645 : if (side_effects_p (op1))
4128 : 0 : return simplify_gen_binary (AND, mode, op1, trueop0);
4129 : : return trueop0;
4130 : : }
4131 : : /* x%1 is 0 (of x&0 if x has side-effects). */
4132 : 758359 : if (trueop1 == CONST1_RTX (mode))
4133 : : {
4134 : 245247 : if (side_effects_p (op0))
4135 : 0 : return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
4136 : 245247 : return CONST0_RTX (mode);
4137 : : }
4138 : : /* Implement modulus by power of two as AND. */
4139 : 513112 : if (CONST_INT_P (trueop1)
4140 : 513112 : && exact_log2 (UINTVAL (trueop1)) > 0)
4141 : 232275 : return simplify_gen_binary (AND, mode, op0,
4142 : 464550 : gen_int_mode (UINTVAL (trueop1) - 1,
4143 : : mode));
4144 : : break;
4145 : :
4146 : 317219 : case MOD:
4147 : : /* 0%x is 0 (or x&0 if x has side-effects). */
4148 : 317219 : if (trueop0 == CONST0_RTX (mode))
4149 : : {
4150 : 537 : if (side_effects_p (op1))
4151 : 8 : return simplify_gen_binary (AND, mode, op1, trueop0);
4152 : : return trueop0;
4153 : : }
4154 : : /* x%1 and x%-1 is 0 (or x&0 if x has side-effects). */
4155 : 316682 : if (trueop1 == CONST1_RTX (mode) || trueop1 == constm1_rtx)
4156 : : {
4157 : 368 : if (side_effects_p (op0))
4158 : 0 : return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
4159 : 368 : return CONST0_RTX (mode);
4160 : : }
4161 : : break;
4162 : :
4163 : 128640 : case ROTATERT:
4164 : 128640 : case ROTATE:
4165 : 128640 : if (trueop1 == CONST0_RTX (mode))
4166 : : return op0;
4167 : : /* Canonicalize rotates by constant amount. If the condition of
4168 : : reversing direction is met, then reverse the direction. */
4169 : : #if defined(HAVE_rotate) && defined(HAVE_rotatert)
4170 : 128540 : if (reverse_rotate_by_imm_p (mode, (code == ROTATE), trueop1))
4171 : : {
4172 : 11249 : int new_amount = GET_MODE_UNIT_PRECISION (mode) - INTVAL (trueop1);
4173 : 11249 : rtx new_amount_rtx = gen_int_shift_amount (mode, new_amount);
4174 : 11515 : return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
4175 : : mode, op0, new_amount_rtx);
4176 : : }
4177 : : #endif
4178 : : /* FALLTHRU */
4179 : 4830202 : case ASHIFTRT:
4180 : 4830202 : if (trueop1 == CONST0_RTX (mode))
4181 : : return op0;
4182 : 4829052 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4183 : : return op0;
4184 : : /* Rotating ~0 always results in ~0. */
4185 : 4828834 : if (CONST_INT_P (trueop0)
4186 : 13801 : && HWI_COMPUTABLE_MODE_P (mode)
4187 : 13753 : && UINTVAL (trueop0) == GET_MODE_MASK (mode)
4188 : 4828834 : && ! side_effects_p (op1))
4189 : : return op0;
4190 : :
4191 : 26611975 : canonicalize_shift:
4192 : : /* Given:
4193 : : scalar modes M1, M2
4194 : : scalar constants c1, c2
4195 : : size (M2) > size (M1)
4196 : : c1 == size (M2) - size (M1)
4197 : : optimize:
4198 : : ([a|l]shiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int <c1>))
4199 : : <low_part>)
4200 : : (const_int <c2>))
4201 : : to:
4202 : : (subreg:M1 ([a|l]shiftrt:M2 (reg:M2) (const_int <c1 + c2>))
4203 : : <low_part>). */
4204 : 26611975 : if ((code == ASHIFTRT || code == LSHIFTRT)
4205 : 10041506 : && is_a <scalar_int_mode> (mode, &int_mode)
4206 : 9598489 : && SUBREG_P (op0)
4207 : 935623 : && CONST_INT_P (op1)
4208 : 934378 : && GET_CODE (SUBREG_REG (op0)) == LSHIFTRT
4209 : 21717 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op0)),
4210 : : &inner_mode)
4211 : 21717 : && CONST_INT_P (XEXP (SUBREG_REG (op0), 1))
4212 : 43128 : && GET_MODE_BITSIZE (inner_mode) > GET_MODE_BITSIZE (int_mode)
4213 : 21564 : && (INTVAL (XEXP (SUBREG_REG (op0), 1))
4214 : 43128 : == GET_MODE_BITSIZE (inner_mode) - GET_MODE_BITSIZE (int_mode))
4215 : 26633360 : && subreg_lowpart_p (op0))
4216 : : {
4217 : 21385 : rtx tmp = gen_int_shift_amount
4218 : 21385 : (inner_mode, INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (op1));
4219 : :
4220 : : /* Combine would usually zero out the value when combining two
4221 : : local shifts and the range becomes larger or equal to the mode.
4222 : : However since we fold away one of the shifts here combine won't
4223 : : see it so we should immediately zero the result if it's out of
4224 : : range. */
4225 : 21385 : if (code == LSHIFTRT
4226 : 39518 : && INTVAL (tmp) >= GET_MODE_BITSIZE (inner_mode))
4227 : 0 : tmp = const0_rtx;
4228 : : else
4229 : 21385 : tmp = simplify_gen_binary (code,
4230 : : inner_mode,
4231 : 21385 : XEXP (SUBREG_REG (op0), 0),
4232 : : tmp);
4233 : :
4234 : 21385 : return lowpart_subreg (int_mode, tmp, inner_mode);
4235 : : }
4236 : :
4237 : : if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
4238 : : {
4239 : : val = INTVAL (op1) & (GET_MODE_UNIT_PRECISION (mode) - 1);
4240 : : if (val != INTVAL (op1))
4241 : : return simplify_gen_binary (code, mode, op0,
4242 : : gen_int_shift_amount (mode, val));
4243 : : }
4244 : : break;
4245 : :
4246 : 0 : case SS_ASHIFT:
4247 : 0 : if (CONST_INT_P (trueop0)
4248 : 0 : && HWI_COMPUTABLE_MODE_P (mode)
4249 : 0 : && (UINTVAL (trueop0) == (GET_MODE_MASK (mode) >> 1)
4250 : 0 : || mode_signbit_p (mode, trueop0))
4251 : 0 : && ! side_effects_p (op1))
4252 : : return op0;
4253 : 0 : goto simplify_ashift;
4254 : :
4255 : 0 : case US_ASHIFT:
4256 : 0 : if (CONST_INT_P (trueop0)
4257 : 0 : && HWI_COMPUTABLE_MODE_P (mode)
4258 : 0 : && UINTVAL (trueop0) == GET_MODE_MASK (mode)
4259 : 0 : && ! side_effects_p (op1))
4260 : : return op0;
4261 : : /* FALLTHRU */
4262 : :
4263 : 16734554 : case ASHIFT:
4264 : 16734554 : simplify_ashift:
4265 : 16734554 : if (trueop1 == CONST0_RTX (mode))
4266 : : return op0;
4267 : 16574374 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4268 : : return op0;
4269 : 16553680 : if (mem_depth
4270 : 100475 : && code == ASHIFT
4271 : 100475 : && CONST_INT_P (trueop1)
4272 : 100471 : && is_a <scalar_int_mode> (mode, &int_mode)
4273 : 16654147 : && IN_RANGE (UINTVAL (trueop1),
4274 : : 1, GET_MODE_PRECISION (int_mode) - 1))
4275 : : {
4276 : 100467 : auto c = (wi::one (GET_MODE_PRECISION (int_mode))
4277 : 100467 : << UINTVAL (trueop1));
4278 : 100467 : rtx new_op1 = immed_wide_int_const (c, int_mode);
4279 : 100467 : return simplify_gen_binary (MULT, int_mode, op0, new_op1);
4280 : 100467 : }
4281 : 16453213 : goto canonicalize_shift;
4282 : :
4283 : 6925376 : case LSHIFTRT:
4284 : 6925376 : if (trueop1 == CONST0_RTX (mode))
4285 : : return op0;
4286 : 5331363 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4287 : : return op0;
4288 : : /* Optimize (lshiftrt (clz X) C) as (eq X 0). */
4289 : 5329928 : if (GET_CODE (op0) == CLZ
4290 : 0 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
4291 : 0 : && CONST_INT_P (trueop1)
4292 : : && STORE_FLAG_VALUE == 1
4293 : 5329928 : && INTVAL (trueop1) < GET_MODE_UNIT_PRECISION (mode))
4294 : : {
4295 : 0 : unsigned HOST_WIDE_INT zero_val = 0;
4296 : :
4297 : 0 : if (CLZ_DEFINED_VALUE_AT_ZERO (inner_mode, zero_val)
4298 : 0 : && zero_val == GET_MODE_PRECISION (inner_mode)
4299 : 0 : && INTVAL (trueop1) == exact_log2 (zero_val))
4300 : 0 : return simplify_gen_relational (EQ, mode, inner_mode,
4301 : 0 : XEXP (op0, 0), const0_rtx);
4302 : : }
4303 : 5329928 : goto canonicalize_shift;
4304 : :
4305 : 182204 : case SMIN:
4306 : 182204 : if (HWI_COMPUTABLE_MODE_P (mode)
4307 : 166020 : && mode_signbit_p (mode, trueop1)
4308 : 182204 : && ! side_effects_p (op0))
4309 : : return op1;
4310 : 182204 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4311 : : return op0;
4312 : 182082 : tem = simplify_associative_operation (code, mode, op0, op1);
4313 : 182082 : if (tem)
4314 : : return tem;
4315 : : break;
4316 : :
4317 : 333503 : case SMAX:
4318 : 333503 : if (HWI_COMPUTABLE_MODE_P (mode)
4319 : 309357 : && CONST_INT_P (trueop1)
4320 : 293487 : && (UINTVAL (trueop1) == GET_MODE_MASK (mode) >> 1)
4321 : 333503 : && ! side_effects_p (op0))
4322 : : return op1;
4323 : 333503 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4324 : : return op0;
4325 : 333405 : tem = simplify_associative_operation (code, mode, op0, op1);
4326 : 333405 : if (tem)
4327 : : return tem;
4328 : : break;
4329 : :
4330 : 167682 : case UMIN:
4331 : 167682 : if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
4332 : : return op1;
4333 : 167656 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4334 : : return op0;
4335 : 167559 : tem = simplify_associative_operation (code, mode, op0, op1);
4336 : 167559 : if (tem)
4337 : : return tem;
4338 : : break;
4339 : :
4340 : 151761 : case UMAX:
4341 : 151761 : if (trueop1 == constm1_rtx && ! side_effects_p (op0))
4342 : : return op1;
4343 : 151761 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4344 : : return op0;
4345 : 151673 : tem = simplify_associative_operation (code, mode, op0, op1);
4346 : 151673 : if (tem)
4347 : : return tem;
4348 : : break;
4349 : :
4350 : 10396 : case SS_PLUS:
4351 : 10396 : case US_PLUS:
4352 : 10396 : case SS_MINUS:
4353 : 10396 : case US_MINUS:
4354 : : /* Simplify x +/- 0 to x, if possible. */
4355 : 10396 : if (trueop1 == CONST0_RTX (mode))
4356 : : return op0;
4357 : : return 0;
4358 : :
4359 : 0 : case SS_MULT:
4360 : 0 : case US_MULT:
4361 : : /* Simplify x * 0 to 0, if possible. */
4362 : 0 : if (trueop1 == CONST0_RTX (mode)
4363 : 0 : && !side_effects_p (op0))
4364 : : return op1;
4365 : :
4366 : : /* Simplify x * 1 to x, if possible. */
4367 : 0 : if (trueop1 == CONST1_RTX (mode))
4368 : : return op0;
4369 : : return 0;
4370 : :
4371 : 504830 : case SMUL_HIGHPART:
4372 : 504830 : case UMUL_HIGHPART:
4373 : : /* Simplify x * 0 to 0, if possible. */
4374 : 504830 : if (trueop1 == CONST0_RTX (mode)
4375 : 504830 : && !side_effects_p (op0))
4376 : : return op1;
4377 : : return 0;
4378 : :
4379 : 0 : case SS_DIV:
4380 : 0 : case US_DIV:
4381 : : /* Simplify x / 1 to x, if possible. */
4382 : 0 : if (trueop1 == CONST1_RTX (mode))
4383 : : return op0;
4384 : : return 0;
4385 : :
4386 : 0 : case COPYSIGN:
4387 : 0 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4388 : : return op0;
4389 : 0 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1))
4390 : : {
4391 : 0 : REAL_VALUE_TYPE f1;
4392 : 0 : real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (trueop1));
4393 : 0 : rtx tmp = simplify_gen_unary (ABS, mode, op0, mode);
4394 : 0 : if (REAL_VALUE_NEGATIVE (f1))
4395 : 0 : tmp = simplify_unary_operation (NEG, mode, tmp, mode);
4396 : 0 : return tmp;
4397 : : }
4398 : 0 : if (GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
4399 : 0 : return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
4400 : 0 : if (GET_CODE (op1) == ABS
4401 : 0 : && ! side_effects_p (op1))
4402 : 0 : return simplify_gen_unary (ABS, mode, op0, mode);
4403 : 0 : if (GET_CODE (op0) == COPYSIGN
4404 : 0 : && ! side_effects_p (XEXP (op0, 1)))
4405 : 0 : return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
4406 : 0 : if (GET_CODE (op1) == COPYSIGN
4407 : 0 : && ! side_effects_p (XEXP (op1, 0)))
4408 : 0 : return simplify_gen_binary (COPYSIGN, mode, op0, XEXP (op1, 1));
4409 : : return 0;
4410 : :
4411 : 771 : case VEC_SERIES:
4412 : 1542 : if (op1 == CONST0_RTX (GET_MODE_INNER (mode)))
4413 : 96 : return gen_vec_duplicate (mode, op0);
4414 : 675 : if (valid_for_const_vector_p (mode, op0)
4415 : 675 : && valid_for_const_vector_p (mode, op1))
4416 : 96 : return gen_const_vec_series (mode, op0, op1);
4417 : : return 0;
4418 : :
4419 : 2617510 : case VEC_SELECT:
4420 : 2617510 : if (!VECTOR_MODE_P (mode))
4421 : : {
4422 : 730194 : gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
4423 : 1460388 : gcc_assert (mode == GET_MODE_INNER (GET_MODE (trueop0)));
4424 : 730194 : gcc_assert (GET_CODE (trueop1) == PARALLEL);
4425 : 730194 : gcc_assert (XVECLEN (trueop1, 0) == 1);
4426 : :
4427 : : /* We can't reason about selections made at runtime. */
4428 : 730194 : if (!CONST_INT_P (XVECEXP (trueop1, 0, 0)))
4429 : 62345 : return 0;
4430 : :
4431 : 730194 : if (vec_duplicate_p (trueop0, &elt0))
4432 : 1316 : return elt0;
4433 : :
4434 : 728878 : if (GET_CODE (trueop0) == CONST_VECTOR)
4435 : 6767 : return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP
4436 : : (trueop1, 0, 0)));
4437 : :
4438 : : /* Extract a scalar element from a nested VEC_SELECT expression
4439 : : (with optional nested VEC_CONCAT expression). Some targets
4440 : : (i386) extract scalar element from a vector using chain of
4441 : : nested VEC_SELECT expressions. When input operand is a memory
4442 : : operand, this operation can be simplified to a simple scalar
4443 : : load from an offseted memory address. */
4444 : 722111 : int n_elts;
4445 : 722111 : if (GET_CODE (trueop0) == VEC_SELECT
4446 : 776373 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
4447 : 54262 : .is_constant (&n_elts)))
4448 : : {
4449 : 54262 : rtx op0 = XEXP (trueop0, 0);
4450 : 54262 : rtx op1 = XEXP (trueop0, 1);
4451 : :
4452 : 54262 : int i = INTVAL (XVECEXP (trueop1, 0, 0));
4453 : 54262 : int elem;
4454 : :
4455 : 54262 : rtvec vec;
4456 : 54262 : rtx tmp_op, tmp;
4457 : :
4458 : 54262 : gcc_assert (GET_CODE (op1) == PARALLEL);
4459 : 54262 : gcc_assert (i < n_elts);
4460 : :
4461 : : /* Select element, pointed by nested selector. */
4462 : 54262 : elem = INTVAL (XVECEXP (op1, 0, i));
4463 : :
4464 : : /* Handle the case when nested VEC_SELECT wraps VEC_CONCAT. */
4465 : 54262 : if (GET_CODE (op0) == VEC_CONCAT)
4466 : : {
4467 : 18321 : rtx op00 = XEXP (op0, 0);
4468 : 18321 : rtx op01 = XEXP (op0, 1);
4469 : :
4470 : 18321 : machine_mode mode00, mode01;
4471 : 18321 : int n_elts00, n_elts01;
4472 : :
4473 : 18321 : mode00 = GET_MODE (op00);
4474 : 18321 : mode01 = GET_MODE (op01);
4475 : :
4476 : : /* Find out the number of elements of each operand.
4477 : : Since the concatenated result has a constant number
4478 : : of elements, the operands must too. */
4479 : 18321 : n_elts00 = GET_MODE_NUNITS (mode00).to_constant ();
4480 : 18321 : n_elts01 = GET_MODE_NUNITS (mode01).to_constant ();
4481 : :
4482 : 18321 : gcc_assert (n_elts == n_elts00 + n_elts01);
4483 : :
4484 : : /* Select correct operand of VEC_CONCAT
4485 : : and adjust selector. */
4486 : 18321 : if (elem < n_elts01)
4487 : : tmp_op = op00;
4488 : : else
4489 : : {
4490 : 42 : tmp_op = op01;
4491 : 42 : elem -= n_elts00;
4492 : : }
4493 : : }
4494 : : else
4495 : : tmp_op = op0;
4496 : :
4497 : 54262 : vec = rtvec_alloc (1);
4498 : 54262 : RTVEC_ELT (vec, 0) = GEN_INT (elem);
4499 : :
4500 : 54262 : tmp = gen_rtx_fmt_ee (code, mode,
4501 : : tmp_op, gen_rtx_PARALLEL (VOIDmode, vec));
4502 : 54262 : return tmp;
4503 : : }
4504 : 667849 : }
4505 : : else
4506 : : {
4507 : 1887316 : gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
4508 : 5661948 : gcc_assert (GET_MODE_INNER (mode)
4509 : : == GET_MODE_INNER (GET_MODE (trueop0)));
4510 : 1887316 : gcc_assert (GET_CODE (trueop1) == PARALLEL);
4511 : :
4512 : 1887316 : if (vec_duplicate_p (trueop0, &elt0))
4513 : : /* It doesn't matter which elements are selected by trueop1,
4514 : : because they are all the same. */
4515 : 25835 : return gen_vec_duplicate (mode, elt0);
4516 : :
4517 : 1875526 : if (GET_CODE (trueop0) == CONST_VECTOR)
4518 : : {
4519 : 10116 : unsigned n_elts = XVECLEN (trueop1, 0);
4520 : 10116 : rtvec v = rtvec_alloc (n_elts);
4521 : 10116 : unsigned int i;
4522 : :
4523 : 20232 : gcc_assert (known_eq (n_elts, GET_MODE_NUNITS (mode)));
4524 : 65992 : for (i = 0; i < n_elts; i++)
4525 : : {
4526 : 55876 : rtx x = XVECEXP (trueop1, 0, i);
4527 : :
4528 : 55876 : if (!CONST_INT_P (x))
4529 : : return 0;
4530 : :
4531 : 55876 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0,
4532 : : INTVAL (x));
4533 : : }
4534 : :
4535 : 10116 : return gen_rtx_CONST_VECTOR (mode, v);
4536 : : }
4537 : :
4538 : : /* Recognize the identity. */
4539 : 1865410 : if (GET_MODE (trueop0) == mode)
4540 : : {
4541 : 515298 : bool maybe_ident = true;
4542 : 515298 : for (int i = 0; i < XVECLEN (trueop1, 0); i++)
4543 : : {
4544 : 514511 : rtx j = XVECEXP (trueop1, 0, i);
4545 : 514511 : if (!CONST_INT_P (j) || INTVAL (j) != i)
4546 : : {
4547 : : maybe_ident = false;
4548 : : break;
4549 : : }
4550 : : }
4551 : 318042 : if (maybe_ident)
4552 : : return trueop0;
4553 : : }
4554 : :
4555 : : /* If we select a low-part subreg, return that. */
4556 : 1864623 : if (vec_series_lowpart_p (mode, GET_MODE (trueop0), trueop1))
4557 : : {
4558 : 0 : rtx new_rtx = lowpart_subreg (mode, trueop0,
4559 : 0 : GET_MODE (trueop0));
4560 : 0 : if (new_rtx != NULL_RTX)
4561 : : return new_rtx;
4562 : : }
4563 : :
4564 : : /* If we build {a,b} then permute it, build the result directly. */
4565 : 1864623 : if (XVECLEN (trueop1, 0) == 2
4566 : 456538 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
4567 : 456538 : && CONST_INT_P (XVECEXP (trueop1, 0, 1))
4568 : 456538 : && GET_CODE (trueop0) == VEC_CONCAT
4569 : 125813 : && GET_CODE (XEXP (trueop0, 0)) == VEC_CONCAT
4570 : 66 : && GET_MODE (XEXP (trueop0, 0)) == mode
4571 : 66 : && GET_CODE (XEXP (trueop0, 1)) == VEC_CONCAT
4572 : 49 : && GET_MODE (XEXP (trueop0, 1)) == mode)
4573 : : {
4574 : 49 : unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
4575 : 49 : unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
4576 : 49 : rtx subop0, subop1;
4577 : :
4578 : 49 : gcc_assert (i0 < 4 && i1 < 4);
4579 : 49 : subop0 = XEXP (XEXP (trueop0, i0 / 2), i0 % 2);
4580 : 49 : subop1 = XEXP (XEXP (trueop0, i1 / 2), i1 % 2);
4581 : :
4582 : 49 : return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
4583 : : }
4584 : :
4585 : 1864574 : if (XVECLEN (trueop1, 0) == 2
4586 : 456489 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
4587 : 456489 : && CONST_INT_P (XVECEXP (trueop1, 0, 1))
4588 : 456489 : && GET_CODE (trueop0) == VEC_CONCAT
4589 : 125764 : && GET_MODE (trueop0) == mode)
4590 : : {
4591 : 2 : unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
4592 : 2 : unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
4593 : 2 : rtx subop0, subop1;
4594 : :
4595 : 2 : gcc_assert (i0 < 2 && i1 < 2);
4596 : 2 : subop0 = XEXP (trueop0, i0);
4597 : 2 : subop1 = XEXP (trueop0, i1);
4598 : :
4599 : 2 : return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
4600 : : }
4601 : :
4602 : : /* If we select one half of a vec_concat, return that. */
4603 : 1864572 : int l0, l1;
4604 : 1864572 : if (GET_CODE (trueop0) == VEC_CONCAT
4605 : 2114824 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
4606 : 1057412 : .is_constant (&l0))
4607 : 2921984 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 1)))
4608 : 1057412 : .is_constant (&l1))
4609 : 2921984 : && CONST_INT_P (XVECEXP (trueop1, 0, 0)))
4610 : : {
4611 : 1057412 : rtx subop0 = XEXP (trueop0, 0);
4612 : 1057412 : rtx subop1 = XEXP (trueop0, 1);
4613 : 1057412 : machine_mode mode0 = GET_MODE (subop0);
4614 : 1057412 : machine_mode mode1 = GET_MODE (subop1);
4615 : 1057412 : int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
4616 : 1057412 : if (i0 == 0 && !side_effects_p (op1) && mode == mode0)
4617 : : {
4618 : 617165 : bool success = true;
4619 : 617165 : for (int i = 1; i < l0; ++i)
4620 : : {
4621 : 616884 : rtx j = XVECEXP (trueop1, 0, i);
4622 : 616884 : if (!CONST_INT_P (j) || INTVAL (j) != i)
4623 : : {
4624 : : success = false;
4625 : : break;
4626 : : }
4627 : : }
4628 : 584163 : if (success)
4629 : : return subop0;
4630 : : }
4631 : 1057131 : if (i0 == l0 && !side_effects_p (op0) && mode == mode1)
4632 : : {
4633 : 420 : bool success = true;
4634 : 420 : for (int i = 1; i < l1; ++i)
4635 : : {
4636 : 378 : rtx j = XVECEXP (trueop1, 0, i);
4637 : 378 : if (!CONST_INT_P (j) || INTVAL (j) != i0 + i)
4638 : : {
4639 : : success = false;
4640 : : break;
4641 : : }
4642 : : }
4643 : 72 : if (success)
4644 : : return subop1;
4645 : : }
4646 : : }
4647 : :
4648 : : /* Simplify vec_select of a subreg of X to just a vec_select of X
4649 : : when X has same component mode as vec_select. */
4650 : 1864249 : unsigned HOST_WIDE_INT subreg_offset = 0;
4651 : 1864249 : if (GET_CODE (trueop0) == SUBREG
4652 : 320711 : && GET_MODE_INNER (mode)
4653 : 641422 : == GET_MODE_INNER (GET_MODE (SUBREG_REG (trueop0)))
4654 : 17710 : && GET_MODE_NUNITS (mode).is_constant (&l1)
4655 : 2184960 : && constant_multiple_p (subreg_memory_offset (trueop0),
4656 : 17710 : GET_MODE_UNIT_BITSIZE (mode),
4657 : : &subreg_offset))
4658 : : {
4659 : 8855 : poly_uint64 nunits
4660 : 17710 : = GET_MODE_NUNITS (GET_MODE (SUBREG_REG (trueop0)));
4661 : 8855 : bool success = true;
4662 : 59881 : for (int i = 0; i != l1; i++)
4663 : : {
4664 : 57113 : rtx idx = XVECEXP (trueop1, 0, i);
4665 : 57113 : if (!CONST_INT_P (idx)
4666 : 57113 : || maybe_ge (UINTVAL (idx) + subreg_offset, nunits))
4667 : : {
4668 : : success = false;
4669 : : break;
4670 : : }
4671 : : }
4672 : :
4673 : 8855 : if (success)
4674 : : {
4675 : 2768 : rtx par = trueop1;
4676 : 2768 : if (subreg_offset)
4677 : : {
4678 : 0 : rtvec vec = rtvec_alloc (l1);
4679 : 0 : for (int i = 0; i < l1; i++)
4680 : 0 : RTVEC_ELT (vec, i)
4681 : 0 : = GEN_INT (INTVAL (XVECEXP (trueop1, 0, i))
4682 : : + subreg_offset);
4683 : 0 : par = gen_rtx_PARALLEL (VOIDmode, vec);
4684 : : }
4685 : 2768 : return gen_rtx_VEC_SELECT (mode, SUBREG_REG (trueop0), par);
4686 : : }
4687 : : }
4688 : : }
4689 : :
4690 : 2529330 : if (XVECLEN (trueop1, 0) == 1
4691 : 667933 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
4692 : 667933 : && GET_CODE (trueop0) == VEC_CONCAT)
4693 : : {
4694 : 2164 : rtx vec = trueop0;
4695 : 2164 : offset = INTVAL (XVECEXP (trueop1, 0, 0)) * GET_MODE_SIZE (mode);
4696 : :
4697 : : /* Try to find the element in the VEC_CONCAT. */
4698 : 2164 : while (GET_MODE (vec) != mode
4699 : 4328 : && GET_CODE (vec) == VEC_CONCAT)
4700 : : {
4701 : 2164 : poly_int64 vec_size;
4702 : :
4703 : 2164 : if (CONST_INT_P (XEXP (vec, 0)))
4704 : : {
4705 : : /* vec_concat of two const_ints doesn't make sense with
4706 : : respect to modes. */
4707 : 1 : if (CONST_INT_P (XEXP (vec, 1)))
4708 : 0 : return 0;
4709 : :
4710 : 3 : vec_size = GET_MODE_SIZE (GET_MODE (trueop0))
4711 : 3 : - GET_MODE_SIZE (GET_MODE (XEXP (vec, 1)));
4712 : : }
4713 : : else
4714 : 4326 : vec_size = GET_MODE_SIZE (GET_MODE (XEXP (vec, 0)));
4715 : :
4716 : 2164 : if (known_lt (offset, vec_size))
4717 : 1488 : vec = XEXP (vec, 0);
4718 : 676 : else if (known_ge (offset, vec_size))
4719 : : {
4720 : 676 : offset -= vec_size;
4721 : 676 : vec = XEXP (vec, 1);
4722 : : }
4723 : : else
4724 : : break;
4725 : 2164 : vec = avoid_constant_pool_reference (vec);
4726 : : }
4727 : :
4728 : 2164 : if (GET_MODE (vec) == mode)
4729 : : return vec;
4730 : : }
4731 : :
4732 : : /* If we select elements in a vec_merge that all come from the same
4733 : : operand, select from that operand directly. */
4734 : 2527298 : if (GET_CODE (op0) == VEC_MERGE)
4735 : : {
4736 : 5896 : rtx trueop02 = avoid_constant_pool_reference (XEXP (op0, 2));
4737 : 5896 : if (CONST_INT_P (trueop02))
4738 : : {
4739 : 2656 : unsigned HOST_WIDE_INT sel = UINTVAL (trueop02);
4740 : 2656 : bool all_operand0 = true;
4741 : 2656 : bool all_operand1 = true;
4742 : 9483 : for (int i = 0; i < XVECLEN (trueop1, 0); i++)
4743 : : {
4744 : 6827 : rtx j = XVECEXP (trueop1, 0, i);
4745 : 6827 : if (sel & (HOST_WIDE_INT_1U << UINTVAL (j)))
4746 : : all_operand1 = false;
4747 : : else
4748 : 3296 : all_operand0 = false;
4749 : : }
4750 : 2656 : if (all_operand0 && !side_effects_p (XEXP (op0, 1)))
4751 : 481 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 0), op1);
4752 : 2175 : if (all_operand1 && !side_effects_p (XEXP (op0, 0)))
4753 : 18 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 1), op1);
4754 : : }
4755 : : }
4756 : :
4757 : : /* If we have two nested selects that are inverses of each
4758 : : other, replace them with the source operand. */
4759 : 2526799 : if (GET_CODE (trueop0) == VEC_SELECT
4760 : 53332 : && GET_MODE (XEXP (trueop0, 0)) == mode)
4761 : : {
4762 : 332 : rtx op0_subop1 = XEXP (trueop0, 1);
4763 : 332 : gcc_assert (GET_CODE (op0_subop1) == PARALLEL);
4764 : 664 : gcc_assert (known_eq (XVECLEN (trueop1, 0), GET_MODE_NUNITS (mode)));
4765 : :
4766 : : /* Apply the outer ordering vector to the inner one. (The inner
4767 : : ordering vector is expressly permitted to be of a different
4768 : : length than the outer one.) If the result is { 0, 1, ..., n-1 }
4769 : : then the two VEC_SELECTs cancel. */
4770 : 452 : for (int i = 0; i < XVECLEN (trueop1, 0); ++i)
4771 : : {
4772 : 452 : rtx x = XVECEXP (trueop1, 0, i);
4773 : 452 : if (!CONST_INT_P (x))
4774 : : return 0;
4775 : 452 : rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
4776 : 452 : if (!CONST_INT_P (y) || i != INTVAL (y))
4777 : : return 0;
4778 : : }
4779 : : return XEXP (trueop0, 0);
4780 : : }
4781 : :
4782 : : return 0;
4783 : 3504159 : case VEC_CONCAT:
4784 : 3504159 : {
4785 : 3504159 : machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
4786 : 3504159 : ? GET_MODE (trueop0)
4787 : 13444 : : GET_MODE_INNER (mode));
4788 : 3504159 : machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
4789 : 3504159 : ? GET_MODE (trueop1)
4790 : 146605 : : GET_MODE_INNER (mode));
4791 : :
4792 : 3504159 : gcc_assert (VECTOR_MODE_P (mode));
4793 : 14016636 : gcc_assert (known_eq (GET_MODE_SIZE (op0_mode)
4794 : : + GET_MODE_SIZE (op1_mode),
4795 : : GET_MODE_SIZE (mode)));
4796 : :
4797 : 3504159 : if (VECTOR_MODE_P (op0_mode))
4798 : 4148853 : gcc_assert (GET_MODE_INNER (mode)
4799 : : == GET_MODE_INNER (op0_mode));
4800 : : else
4801 : 4242416 : gcc_assert (GET_MODE_INNER (mode) == op0_mode);
4802 : :
4803 : 3504159 : if (VECTOR_MODE_P (op1_mode))
4804 : 4148853 : gcc_assert (GET_MODE_INNER (mode)
4805 : : == GET_MODE_INNER (op1_mode));
4806 : : else
4807 : 4242416 : gcc_assert (GET_MODE_INNER (mode) == op1_mode);
4808 : :
4809 : 3504159 : unsigned int n_elts, in_n_elts;
4810 : 3504159 : if ((GET_CODE (trueop0) == CONST_VECTOR
4811 : 3504159 : || CONST_SCALAR_INT_P (trueop0)
4812 : 3475626 : || CONST_DOUBLE_AS_FLOAT_P (trueop0))
4813 : 29630 : && (GET_CODE (trueop1) == CONST_VECTOR
4814 : 29630 : || CONST_SCALAR_INT_P (trueop1)
4815 : 22329 : || CONST_DOUBLE_AS_FLOAT_P (trueop1))
4816 : 14602 : && GET_MODE_NUNITS (mode).is_constant (&n_elts)
4817 : 3511460 : && GET_MODE_NUNITS (op0_mode).is_constant (&in_n_elts))
4818 : : {
4819 : 7301 : rtvec v = rtvec_alloc (n_elts);
4820 : 7301 : unsigned int i;
4821 : 122246 : for (i = 0; i < n_elts; i++)
4822 : : {
4823 : 107644 : if (i < in_n_elts)
4824 : : {
4825 : 53726 : if (!VECTOR_MODE_P (op0_mode))
4826 : 0 : RTVEC_ELT (v, i) = trueop0;
4827 : : else
4828 : 53726 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
4829 : : }
4830 : : else
4831 : : {
4832 : 53918 : if (!VECTOR_MODE_P (op1_mode))
4833 : 0 : RTVEC_ELT (v, i) = trueop1;
4834 : : else
4835 : 53918 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
4836 : : i - in_n_elts);
4837 : : }
4838 : : }
4839 : :
4840 : 21706 : return gen_rtx_CONST_VECTOR (mode, v);
4841 : : }
4842 : :
4843 : : /* Try to merge two VEC_SELECTs from the same vector into a single one.
4844 : : Restrict the transformation to avoid generating a VEC_SELECT with a
4845 : : mode unrelated to its operand. */
4846 : 3496858 : if (GET_CODE (trueop0) == VEC_SELECT
4847 : 93375 : && GET_CODE (trueop1) == VEC_SELECT
4848 : 21995 : && rtx_equal_p (XEXP (trueop0, 0), XEXP (trueop1, 0))
4849 : 3511263 : && GET_MODE_INNER (GET_MODE (XEXP (trueop0, 0)))
4850 : 28810 : == GET_MODE_INNER(mode))
4851 : : {
4852 : 14405 : rtx par0 = XEXP (trueop0, 1);
4853 : 14405 : rtx par1 = XEXP (trueop1, 1);
4854 : 14405 : int len0 = XVECLEN (par0, 0);
4855 : 14405 : int len1 = XVECLEN (par1, 0);
4856 : 14405 : rtvec vec = rtvec_alloc (len0 + len1);
4857 : 86099 : for (int i = 0; i < len0; i++)
4858 : 71694 : RTVEC_ELT (vec, i) = XVECEXP (par0, 0, i);
4859 : 86099 : for (int i = 0; i < len1; i++)
4860 : 71694 : RTVEC_ELT (vec, len0 + i) = XVECEXP (par1, 0, i);
4861 : 14405 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (trueop0, 0),
4862 : 14405 : gen_rtx_PARALLEL (VOIDmode, vec));
4863 : : }
4864 : : /* (vec_concat:
4865 : : (subreg_lowpart:N OP)
4866 : : (vec_select:N OP P)) --> OP when P selects the high half
4867 : : of the OP. */
4868 : 3482453 : if (GET_CODE (trueop0) == SUBREG
4869 : 401846 : && subreg_lowpart_p (trueop0)
4870 : 401004 : && GET_CODE (trueop1) == VEC_SELECT
4871 : 3 : && SUBREG_REG (trueop0) == XEXP (trueop1, 0)
4872 : 0 : && !side_effects_p (XEXP (trueop1, 0))
4873 : 3482453 : && vec_series_highpart_p (op1_mode, mode, XEXP (trueop1, 1)))
4874 : 0 : return XEXP (trueop1, 0);
4875 : : }
4876 : 3482453 : return 0;
4877 : :
4878 : 0 : default:
4879 : 0 : gcc_unreachable ();
4880 : : }
4881 : :
4882 : 298563008 : if (mode == GET_MODE (op0)
4883 : 258709688 : && mode == GET_MODE (op1)
4884 : 76329915 : && vec_duplicate_p (op0, &elt0)
4885 : 298634364 : && vec_duplicate_p (op1, &elt1))
4886 : : {
4887 : : /* Try applying the operator to ELT and see if that simplifies.
4888 : : We can duplicate the result if so.
4889 : :
4890 : : The reason we don't use simplify_gen_binary is that it isn't
4891 : : necessarily a win to convert things like:
4892 : :
4893 : : (plus:V (vec_duplicate:V (reg:S R1))
4894 : : (vec_duplicate:V (reg:S R2)))
4895 : :
4896 : : to:
4897 : :
4898 : : (vec_duplicate:V (plus:S (reg:S R1) (reg:S R2)))
4899 : :
4900 : : The first might be done entirely in vector registers while the
4901 : : second might need a move between register files. */
4902 : 708 : tem = simplify_binary_operation (code, GET_MODE_INNER (mode),
4903 : : elt0, elt1);
4904 : 354 : if (tem)
4905 : 2 : return gen_vec_duplicate (mode, tem);
4906 : : }
4907 : :
4908 : : return 0;
4909 : : }
4910 : :
4911 : : /* Return true if binary operation OP distributes over addition in operand
4912 : : OPNO, with the other operand being held constant. OPNO counts from 1. */
4913 : :
4914 : : static bool
4915 : 22682 : distributes_over_addition_p (rtx_code op, int opno)
4916 : : {
4917 : 22682 : switch (op)
4918 : : {
4919 : : case PLUS:
4920 : : case MINUS:
4921 : : case MULT:
4922 : : return true;
4923 : :
4924 : 96 : case ASHIFT:
4925 : 96 : return opno == 1;
4926 : :
4927 : 19934 : default:
4928 : 19934 : return false;
4929 : : }
4930 : : }
4931 : :
4932 : : rtx
4933 : 385001624 : simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
4934 : : rtx op0, rtx op1)
4935 : : {
4936 : 385001624 : if (VECTOR_MODE_P (mode)
4937 : 10782561 : && code != VEC_CONCAT
4938 : 7274061 : && GET_CODE (op0) == CONST_VECTOR
4939 : 57052 : && GET_CODE (op1) == CONST_VECTOR)
4940 : : {
4941 : 23371 : bool step_ok_p;
4942 : 23371 : if (CONST_VECTOR_STEPPED_P (op0)
4943 : 23371 : && CONST_VECTOR_STEPPED_P (op1))
4944 : : /* We can operate directly on the encoding if:
4945 : :
4946 : : a3 - a2 == a2 - a1 && b3 - b2 == b2 - b1
4947 : : implies
4948 : : (a3 op b3) - (a2 op b2) == (a2 op b2) - (a1 op b1)
4949 : :
4950 : : Addition and subtraction are the supported operators
4951 : : for which this is true. */
4952 : 689 : step_ok_p = (code == PLUS || code == MINUS);
4953 : 22682 : else if (CONST_VECTOR_STEPPED_P (op0))
4954 : : /* We can operate directly on stepped encodings if:
4955 : :
4956 : : a3 - a2 == a2 - a1
4957 : : implies:
4958 : : (a3 op c) - (a2 op c) == (a2 op c) - (a1 op c)
4959 : :
4960 : : which is true if (x -> x op c) distributes over addition. */
4961 : 1030 : step_ok_p = distributes_over_addition_p (code, 1);
4962 : : else
4963 : : /* Similarly in reverse. */
4964 : 21652 : step_ok_p = distributes_over_addition_p (code, 2);
4965 : 23371 : rtx_vector_builder builder;
4966 : 23371 : if (!builder.new_binary_operation (mode, op0, op1, step_ok_p))
4967 : : return 0;
4968 : :
4969 : 23371 : unsigned int count = builder.encoded_nelts ();
4970 : 98064 : for (unsigned int i = 0; i < count; i++)
4971 : : {
4972 : 149648 : rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
4973 : : CONST_VECTOR_ELT (op0, i),
4974 : 74824 : CONST_VECTOR_ELT (op1, i));
4975 : 74824 : if (!x || !valid_for_const_vector_p (mode, x))
4976 : 131 : return 0;
4977 : 74693 : builder.quick_push (x);
4978 : : }
4979 : 23240 : return builder.build ();
4980 : 23371 : }
4981 : :
4982 : 384978253 : if (VECTOR_MODE_P (mode)
4983 : 10759190 : && code == VEC_CONCAT
4984 : 3508500 : && (CONST_SCALAR_INT_P (op0)
4985 : 3493179 : || CONST_FIXED_P (op0)
4986 : 3493179 : || CONST_DOUBLE_AS_FLOAT_P (op0))
4987 : 18882 : && (CONST_SCALAR_INT_P (op1)
4988 : 17005 : || CONST_DOUBLE_AS_FLOAT_P (op1)
4989 : 14541 : || CONST_FIXED_P (op1)))
4990 : : {
4991 : : /* Both inputs have a constant number of elements, so the result
4992 : : must too. */
4993 : 4341 : unsigned n_elts = GET_MODE_NUNITS (mode).to_constant ();
4994 : 4341 : rtvec v = rtvec_alloc (n_elts);
4995 : :
4996 : 4341 : gcc_assert (n_elts >= 2);
4997 : 4341 : if (n_elts == 2)
4998 : : {
4999 : 4341 : gcc_assert (GET_CODE (op0) != CONST_VECTOR);
5000 : 4341 : gcc_assert (GET_CODE (op1) != CONST_VECTOR);
5001 : :
5002 : 4341 : RTVEC_ELT (v, 0) = op0;
5003 : 4341 : RTVEC_ELT (v, 1) = op1;
5004 : : }
5005 : : else
5006 : : {
5007 : 0 : unsigned op0_n_elts = GET_MODE_NUNITS (GET_MODE (op0)).to_constant ();
5008 : 0 : unsigned op1_n_elts = GET_MODE_NUNITS (GET_MODE (op1)).to_constant ();
5009 : 0 : unsigned i;
5010 : :
5011 : 0 : gcc_assert (GET_CODE (op0) == CONST_VECTOR);
5012 : 0 : gcc_assert (GET_CODE (op1) == CONST_VECTOR);
5013 : 0 : gcc_assert (op0_n_elts + op1_n_elts == n_elts);
5014 : :
5015 : 0 : for (i = 0; i < op0_n_elts; ++i)
5016 : 0 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op0, i);
5017 : 0 : for (i = 0; i < op1_n_elts; ++i)
5018 : 0 : RTVEC_ELT (v, op0_n_elts+i) = CONST_VECTOR_ELT (op1, i);
5019 : : }
5020 : :
5021 : 4341 : return gen_rtx_CONST_VECTOR (mode, v);
5022 : : }
5023 : :
5024 : 384973912 : if (SCALAR_FLOAT_MODE_P (mode)
5025 : 5989038 : && CONST_DOUBLE_AS_FLOAT_P (op0)
5026 : 90177 : && CONST_DOUBLE_AS_FLOAT_P (op1)
5027 : 47722 : && mode == GET_MODE (op0) && mode == GET_MODE (op1))
5028 : : {
5029 : 47722 : if (code == AND
5030 : : || code == IOR
5031 : 47722 : || code == XOR)
5032 : : {
5033 : 38446 : long tmp0[4];
5034 : 38446 : long tmp1[4];
5035 : 38446 : REAL_VALUE_TYPE r;
5036 : 38446 : int i;
5037 : :
5038 : 38446 : real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0),
5039 : 38446 : GET_MODE (op0));
5040 : 38446 : real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1),
5041 : 38446 : GET_MODE (op1));
5042 : 192230 : for (i = 0; i < 4; i++)
5043 : : {
5044 : 153784 : switch (code)
5045 : : {
5046 : 149544 : case AND:
5047 : 149544 : tmp0[i] &= tmp1[i];
5048 : 149544 : break;
5049 : 2248 : case IOR:
5050 : 2248 : tmp0[i] |= tmp1[i];
5051 : 2248 : break;
5052 : 1992 : case XOR:
5053 : 1992 : tmp0[i] ^= tmp1[i];
5054 : 1992 : break;
5055 : : default:
5056 : : gcc_unreachable ();
5057 : : }
5058 : : }
5059 : 38446 : real_from_target (&r, tmp0, mode);
5060 : 38446 : return const_double_from_real_value (r, mode);
5061 : : }
5062 : 9276 : else if (code == COPYSIGN)
5063 : : {
5064 : 0 : REAL_VALUE_TYPE f0, f1;
5065 : 0 : real_convert (&f0, mode, CONST_DOUBLE_REAL_VALUE (op0));
5066 : 0 : real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (op1));
5067 : 0 : real_copysign (&f0, &f1);
5068 : 0 : return const_double_from_real_value (f0, mode);
5069 : : }
5070 : : else
5071 : : {
5072 : 9276 : REAL_VALUE_TYPE f0, f1, value, result;
5073 : 9276 : const REAL_VALUE_TYPE *opr0, *opr1;
5074 : 9276 : bool inexact;
5075 : :
5076 : 9276 : opr0 = CONST_DOUBLE_REAL_VALUE (op0);
5077 : 9276 : opr1 = CONST_DOUBLE_REAL_VALUE (op1);
5078 : :
5079 : 9276 : if (HONOR_SNANS (mode)
5080 : 9276 : && (REAL_VALUE_ISSIGNALING_NAN (*opr0)
5081 : 651 : || REAL_VALUE_ISSIGNALING_NAN (*opr1)))
5082 : 10 : return 0;
5083 : :
5084 : 9266 : real_convert (&f0, mode, opr0);
5085 : 9266 : real_convert (&f1, mode, opr1);
5086 : :
5087 : 9266 : if (code == DIV
5088 : 4170 : && real_equal (&f1, &dconst0)
5089 : 12957 : && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
5090 : 3687 : return 0;
5091 : :
5092 : 27812 : if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
5093 : 5503 : && flag_trapping_math
5094 : 5360 : && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
5095 : : {
5096 : 5 : int s0 = REAL_VALUE_NEGATIVE (f0);
5097 : 5 : int s1 = REAL_VALUE_NEGATIVE (f1);
5098 : :
5099 : 5 : switch (code)
5100 : : {
5101 : 0 : case PLUS:
5102 : : /* Inf + -Inf = NaN plus exception. */
5103 : 0 : if (s0 != s1)
5104 : : return 0;
5105 : : break;
5106 : 0 : case MINUS:
5107 : : /* Inf - Inf = NaN plus exception. */
5108 : 0 : if (s0 == s1)
5109 : : return 0;
5110 : : break;
5111 : : case DIV:
5112 : : /* Inf / Inf = NaN plus exception. */
5113 : : return 0;
5114 : : default:
5115 : : break;
5116 : : }
5117 : : }
5118 : :
5119 : 8114 : if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
5120 : 1998 : && flag_trapping_math
5121 : 7494 : && ((REAL_VALUE_ISINF (f0) && real_equal (&f1, &dconst0))
5122 : 1916 : || (REAL_VALUE_ISINF (f1)
5123 : 10 : && real_equal (&f0, &dconst0))))
5124 : : /* Inf * 0 = NaN plus exception. */
5125 : 14 : return 0;
5126 : :
5127 : 5560 : inexact = real_arithmetic (&value, rtx_to_tree_code (code),
5128 : : &f0, &f1);
5129 : 5560 : real_convert (&result, mode, &value);
5130 : :
5131 : : /* Don't constant fold this floating point operation if
5132 : : the result has overflowed and flag_trapping_math. */
5133 : :
5134 : 5560 : if (flag_trapping_math
5135 : 21362 : && MODE_HAS_INFINITIES (mode)
5136 : 5341 : && REAL_VALUE_ISINF (result)
5137 : 801 : && !REAL_VALUE_ISINF (f0)
5138 : 6361 : && !REAL_VALUE_ISINF (f1))
5139 : : /* Overflow plus exception. */
5140 : 801 : return 0;
5141 : :
5142 : : /* Don't constant fold this floating point operation if the
5143 : : result may dependent upon the run-time rounding mode and
5144 : : flag_rounding_math is set, or if GCC's software emulation
5145 : : is unable to accurately represent the result. */
5146 : :
5147 : 4759 : if ((flag_rounding_math
5148 : 30803 : || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
5149 : 4759 : && (inexact || !real_identical (&result, &value)))
5150 : 353 : return NULL_RTX;
5151 : :
5152 : 4406 : return const_double_from_real_value (result, mode);
5153 : : }
5154 : : }
5155 : :
5156 : : /* We can fold some multi-word operations. */
5157 : 384926190 : scalar_int_mode int_mode;
5158 : 384926190 : if (is_a <scalar_int_mode> (mode, &int_mode)
5159 : 332725587 : && CONST_SCALAR_INT_P (op0)
5160 : 33474633 : && CONST_SCALAR_INT_P (op1)
5161 : 413196433 : && GET_MODE_PRECISION (int_mode) <= MAX_BITSIZE_MODE_ANY_INT)
5162 : : {
5163 : 28270243 : wide_int result;
5164 : 28270243 : wi::overflow_type overflow;
5165 : 28270243 : rtx_mode_t pop0 = rtx_mode_t (op0, int_mode);
5166 : 28270243 : rtx_mode_t pop1 = rtx_mode_t (op1, int_mode);
5167 : :
5168 : : #if TARGET_SUPPORTS_WIDE_INT == 0
5169 : : /* This assert keeps the simplification from producing a result
5170 : : that cannot be represented in a CONST_DOUBLE but a lot of
5171 : : upstream callers expect that this function never fails to
5172 : : simplify something and so you if you added this to the test
5173 : : above the code would die later anyway. If this assert
5174 : : happens, you just need to make the port support wide int. */
5175 : : gcc_assert (GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_DOUBLE_INT);
5176 : : #endif
5177 : 28270243 : switch (code)
5178 : : {
5179 : 928419 : case MINUS:
5180 : 928419 : result = wi::sub (pop0, pop1);
5181 : 928419 : break;
5182 : :
5183 : 22375423 : case PLUS:
5184 : 22375423 : result = wi::add (pop0, pop1);
5185 : 22375423 : break;
5186 : :
5187 : 232490 : case MULT:
5188 : 232490 : result = wi::mul (pop0, pop1);
5189 : 232490 : break;
5190 : :
5191 : 4052 : case DIV:
5192 : 4052 : result = wi::div_trunc (pop0, pop1, SIGNED, &overflow);
5193 : 4052 : if (overflow)
5194 : : return NULL_RTX;
5195 : : break;
5196 : :
5197 : 188 : case MOD:
5198 : 188 : result = wi::mod_trunc (pop0, pop1, SIGNED, &overflow);
5199 : 188 : if (overflow)
5200 : : return NULL_RTX;
5201 : : break;
5202 : :
5203 : 6447 : case UDIV:
5204 : 6447 : result = wi::div_trunc (pop0, pop1, UNSIGNED, &overflow);
5205 : 6447 : if (overflow)
5206 : : return NULL_RTX;
5207 : : break;
5208 : :
5209 : 7654 : case UMOD:
5210 : 7654 : result = wi::mod_trunc (pop0, pop1, UNSIGNED, &overflow);
5211 : 7654 : if (overflow)
5212 : : return NULL_RTX;
5213 : : break;
5214 : :
5215 : 365307 : case AND:
5216 : 365307 : result = wi::bit_and (pop0, pop1);
5217 : 365307 : break;
5218 : :
5219 : 173138 : case IOR:
5220 : 173138 : result = wi::bit_or (pop0, pop1);
5221 : 173138 : break;
5222 : :
5223 : 29992 : case XOR:
5224 : 29992 : result = wi::bit_xor (pop0, pop1);
5225 : 29992 : break;
5226 : :
5227 : 1728 : case SMIN:
5228 : 1728 : result = wi::smin (pop0, pop1);
5229 : 1728 : break;
5230 : :
5231 : 1717 : case SMAX:
5232 : 1717 : result = wi::smax (pop0, pop1);
5233 : 1717 : break;
5234 : :
5235 : 2592 : case UMIN:
5236 : 2592 : result = wi::umin (pop0, pop1);
5237 : 2592 : break;
5238 : :
5239 : 2424 : case UMAX:
5240 : 2424 : result = wi::umax (pop0, pop1);
5241 : 2424 : break;
5242 : :
5243 : 4104130 : case LSHIFTRT:
5244 : 4104130 : case ASHIFTRT:
5245 : 4104130 : case ASHIFT:
5246 : 4104130 : case SS_ASHIFT:
5247 : 4104130 : case US_ASHIFT:
5248 : 4104130 : {
5249 : : /* The shift count might be in SImode while int_mode might
5250 : : be narrower. On IA-64 it is even DImode. If the shift
5251 : : count is too large and doesn't fit into int_mode, we'd
5252 : : ICE. So, if int_mode is narrower than word, use
5253 : : word_mode for the shift count. */
5254 : 4104130 : if (GET_MODE (op1) == VOIDmode
5255 : 4529563 : && GET_MODE_PRECISION (int_mode) < BITS_PER_WORD)
5256 : 1149813 : pop1 = rtx_mode_t (op1, word_mode);
5257 : :
5258 : 4104130 : wide_int wop1 = pop1;
5259 : 4104130 : if (SHIFT_COUNT_TRUNCATED)
5260 : : wop1 = wi::umod_trunc (wop1, GET_MODE_PRECISION (int_mode));
5261 : 4104130 : else if (wi::geu_p (wop1, GET_MODE_PRECISION (int_mode)))
5262 : 29 : return NULL_RTX;
5263 : :
5264 : 4104101 : switch (code)
5265 : : {
5266 : 2220253 : case LSHIFTRT:
5267 : 2220253 : result = wi::lrshift (pop0, wop1);
5268 : 2220253 : break;
5269 : :
5270 : 48940 : case ASHIFTRT:
5271 : 48940 : result = wi::arshift (pop0, wop1);
5272 : 48940 : break;
5273 : :
5274 : 1834908 : case ASHIFT:
5275 : 1834908 : result = wi::lshift (pop0, wop1);
5276 : 1834908 : break;
5277 : :
5278 : 0 : case SS_ASHIFT:
5279 : 0 : if (wi::leu_p (wop1, wi::clrsb (pop0)))
5280 : 0 : result = wi::lshift (pop0, wop1);
5281 : 0 : else if (wi::neg_p (pop0))
5282 : 0 : result = wi::min_value (int_mode, SIGNED);
5283 : : else
5284 : 0 : result = wi::max_value (int_mode, SIGNED);
5285 : : break;
5286 : :
5287 : 0 : case US_ASHIFT:
5288 : 0 : if (wi::eq_p (pop0, 0))
5289 : 0 : result = pop0;
5290 : 0 : else if (wi::leu_p (wop1, wi::clz (pop0)))
5291 : 0 : result = wi::lshift (pop0, wop1);
5292 : : else
5293 : 0 : result = wi::max_value (int_mode, UNSIGNED);
5294 : : break;
5295 : :
5296 : 0 : default:
5297 : 0 : gcc_unreachable ();
5298 : : }
5299 : 4104101 : break;
5300 : 4104130 : }
5301 : 27386 : case ROTATE:
5302 : 27386 : case ROTATERT:
5303 : 27386 : {
5304 : : /* The rotate count might be in SImode while int_mode might
5305 : : be narrower. On IA-64 it is even DImode. If the shift
5306 : : count is too large and doesn't fit into int_mode, we'd
5307 : : ICE. So, if int_mode is narrower than word, use
5308 : : word_mode for the shift count. */
5309 : 27386 : if (GET_MODE (op1) == VOIDmode
5310 : 35537 : && GET_MODE_PRECISION (int_mode) < BITS_PER_WORD)
5311 : 17367 : pop1 = rtx_mode_t (op1, word_mode);
5312 : :
5313 : 27386 : if (wi::neg_p (pop1))
5314 : : return NULL_RTX;
5315 : :
5316 : 27316 : switch (code)
5317 : : {
5318 : 8410 : case ROTATE:
5319 : 8410 : result = wi::lrotate (pop0, pop1);
5320 : 8410 : break;
5321 : :
5322 : 18906 : case ROTATERT:
5323 : 18906 : result = wi::rrotate (pop0, pop1);
5324 : 18906 : break;
5325 : :
5326 : 0 : default:
5327 : 0 : gcc_unreachable ();
5328 : : }
5329 : : break;
5330 : : }
5331 : :
5332 : 1910 : case SS_PLUS:
5333 : 1910 : result = wi::add (pop0, pop1, SIGNED, &overflow);
5334 : 3764 : clamp_signed_saturation:
5335 : 3764 : if (overflow == wi::OVF_OVERFLOW)
5336 : 252 : result = wi::max_value (GET_MODE_PRECISION (int_mode), SIGNED);
5337 : 3512 : else if (overflow == wi::OVF_UNDERFLOW)
5338 : 227 : result = wi::min_value (GET_MODE_PRECISION (int_mode), SIGNED);
5339 : 3285 : else if (overflow != wi::OVF_NONE)
5340 : : return NULL_RTX;
5341 : : break;
5342 : :
5343 : 1868 : case US_PLUS:
5344 : 1868 : result = wi::add (pop0, pop1, UNSIGNED, &overflow);
5345 : 1868 : clamp_unsigned_saturation:
5346 : 1868 : if (overflow != wi::OVF_NONE)
5347 : 378 : result = wi::max_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
5348 : : break;
5349 : :
5350 : 1854 : case SS_MINUS:
5351 : 1854 : result = wi::sub (pop0, pop1, SIGNED, &overflow);
5352 : 1854 : goto clamp_signed_saturation;
5353 : :
5354 : 1516 : case US_MINUS:
5355 : 1516 : result = wi::sub (pop0, pop1, UNSIGNED, &overflow);
5356 : 1516 : if (overflow != wi::OVF_NONE)
5357 : 966 : result = wi::min_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
5358 : : break;
5359 : :
5360 : 0 : case SS_MULT:
5361 : 0 : result = wi::mul (pop0, pop1, SIGNED, &overflow);
5362 : 0 : goto clamp_signed_saturation;
5363 : :
5364 : 0 : case US_MULT:
5365 : 0 : result = wi::mul (pop0, pop1, UNSIGNED, &overflow);
5366 : 0 : goto clamp_unsigned_saturation;
5367 : :
5368 : 8 : case SMUL_HIGHPART:
5369 : 8 : result = wi::mul_high (pop0, pop1, SIGNED);
5370 : 8 : break;
5371 : :
5372 : 0 : case UMUL_HIGHPART:
5373 : 0 : result = wi::mul_high (pop0, pop1, UNSIGNED);
5374 : 0 : break;
5375 : :
5376 : : default:
5377 : : return NULL_RTX;
5378 : : }
5379 : 28269667 : return immed_wide_int_const (result, int_mode);
5380 : 28270243 : }
5381 : :
5382 : : /* Handle polynomial integers. */
5383 : : if (NUM_POLY_INT_COEFFS > 1
5384 : : && is_a <scalar_int_mode> (mode, &int_mode)
5385 : : && poly_int_rtx_p (op0)
5386 : : && poly_int_rtx_p (op1))
5387 : : {
5388 : : poly_wide_int result;
5389 : : switch (code)
5390 : : {
5391 : : case PLUS:
5392 : : result = wi::to_poly_wide (op0, mode) + wi::to_poly_wide (op1, mode);
5393 : : break;
5394 : :
5395 : : case MINUS:
5396 : : result = wi::to_poly_wide (op0, mode) - wi::to_poly_wide (op1, mode);
5397 : : break;
5398 : :
5399 : : case MULT:
5400 : : if (CONST_SCALAR_INT_P (op1))
5401 : : result = wi::to_poly_wide (op0, mode) * rtx_mode_t (op1, mode);
5402 : : else
5403 : : return NULL_RTX;
5404 : : break;
5405 : :
5406 : : case ASHIFT:
5407 : : if (CONST_SCALAR_INT_P (op1))
5408 : : {
5409 : : wide_int shift
5410 : : = rtx_mode_t (op1,
5411 : : GET_MODE (op1) == VOIDmode
5412 : : && GET_MODE_PRECISION (int_mode) < BITS_PER_WORD
5413 : : ? word_mode : mode);
5414 : : if (SHIFT_COUNT_TRUNCATED)
5415 : : shift = wi::umod_trunc (shift, GET_MODE_PRECISION (int_mode));
5416 : : else if (wi::geu_p (shift, GET_MODE_PRECISION (int_mode)))
5417 : : return NULL_RTX;
5418 : : result = wi::to_poly_wide (op0, mode) << shift;
5419 : : }
5420 : : else
5421 : : return NULL_RTX;
5422 : : break;
5423 : :
5424 : : case IOR:
5425 : : if (!CONST_SCALAR_INT_P (op1)
5426 : : || !can_ior_p (wi::to_poly_wide (op0, mode),
5427 : : rtx_mode_t (op1, mode), &result))
5428 : : return NULL_RTX;
5429 : : break;
5430 : :
5431 : : default:
5432 : : return NULL_RTX;
5433 : : }
5434 : : return immed_wide_int_const (result, int_mode);
5435 : : }
5436 : :
5437 : : return NULL_RTX;
5438 : : }
5439 : :
5440 : :
5441 : :
5442 : : /* Return a positive integer if X should sort after Y. The value
5443 : : returned is 1 if and only if X and Y are both regs. */
5444 : :
5445 : : static int
5446 : 91752625 : simplify_plus_minus_op_data_cmp (rtx x, rtx y)
5447 : : {
5448 : 91752625 : int result;
5449 : :
5450 : 91752625 : result = (commutative_operand_precedence (y)
5451 : 91752625 : - commutative_operand_precedence (x));
5452 : 91752625 : if (result)
5453 : 62769328 : return result + result;
5454 : :
5455 : : /* Group together equal REGs to do more simplification. */
5456 : 28983297 : if (REG_P (x) && REG_P (y))
5457 : 7035186 : return REGNO (x) > REGNO (y);
5458 : :
5459 : : return 0;
5460 : : }
5461 : :
5462 : : /* Simplify and canonicalize a PLUS or MINUS, at least one of whose
5463 : : operands may be another PLUS or MINUS.
5464 : :
5465 : : Rather than test for specific case, we do this by a brute-force method
5466 : : and do all possible simplifications until no more changes occur. Then
5467 : : we rebuild the operation.
5468 : :
5469 : : May return NULL_RTX when no changes were made. */
5470 : :
5471 : : rtx
5472 : 31020463 : simplify_context::simplify_plus_minus (rtx_code code, machine_mode mode,
5473 : : rtx op0, rtx op1)
5474 : : {
5475 : 31020463 : struct simplify_plus_minus_op_data
5476 : : {
5477 : : rtx op;
5478 : : short neg;
5479 : : } ops[16];
5480 : 31020463 : rtx result, tem;
5481 : 31020463 : int n_ops = 2;
5482 : 31020463 : int changed, n_constants, canonicalized = 0;
5483 : 31020463 : int i, j;
5484 : :
5485 : 31020463 : memset (ops, 0, sizeof ops);
5486 : :
5487 : : /* Set up the two operands and then expand them until nothing has been
5488 : : changed. If we run out of room in our array, give up; this should
5489 : : almost never happen. */
5490 : :
5491 : 31020463 : ops[0].op = op0;
5492 : 31020463 : ops[0].neg = 0;
5493 : 31020463 : ops[1].op = op1;
5494 : 31020463 : ops[1].neg = (code == MINUS);
5495 : :
5496 : 62896579 : do
5497 : : {
5498 : 62896579 : changed = 0;
5499 : 62896579 : n_constants = 0;
5500 : :
5501 : 254287460 : for (i = 0; i < n_ops; i++)
5502 : : {
5503 : 191390895 : rtx this_op = ops[i].op;
5504 : 191390895 : int this_neg = ops[i].neg;
5505 : 191390895 : enum rtx_code this_code = GET_CODE (this_op);
5506 : :
5507 : 191390895 : switch (this_code)
5508 : : {
5509 : 31226976 : case PLUS:
5510 : 31226976 : case MINUS:
5511 : 31226976 : if (n_ops == ARRAY_SIZE (ops))
5512 : : return NULL_RTX;
5513 : :
5514 : 31226962 : ops[n_ops].op = XEXP (this_op, 1);
5515 : 31226962 : ops[n_ops].neg = (this_code == MINUS) ^ this_neg;
5516 : 31226962 : n_ops++;
5517 : :
5518 : 31226962 : ops[i].op = XEXP (this_op, 0);
5519 : 31226962 : changed = 1;
5520 : : /* If this operand was negated then we will potentially
5521 : : canonicalize the expression. Similarly if we don't
5522 : : place the operands adjacent we're re-ordering the
5523 : : expression and thus might be performing a
5524 : : canonicalization. Ignore register re-ordering.
5525 : : ??? It might be better to shuffle the ops array here,
5526 : : but then (plus (plus (A, B), plus (C, D))) wouldn't
5527 : : be seen as non-canonical. */
5528 : 31226962 : if (this_neg
5529 : 30642378 : || (i != n_ops - 2
5530 : 30038318 : && !(REG_P (ops[i].op) && REG_P (ops[n_ops - 1].op))))
5531 : 191390881 : canonicalized = 1;
5532 : : break;
5533 : :
5534 : 1413 : case NEG:
5535 : 1413 : ops[i].op = XEXP (this_op, 0);
5536 : 1413 : ops[i].neg = ! this_neg;
5537 : 1413 : changed = 1;
5538 : 1413 : canonicalized = 1;
5539 : 1413 : break;
5540 : :
5541 : 1184539 : case CONST:
5542 : 1184539 : if (n_ops != ARRAY_SIZE (ops)
5543 : 1184539 : && GET_CODE (XEXP (this_op, 0)) == PLUS
5544 : 1077545 : && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
5545 : 1056549 : && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
5546 : : {
5547 : 1056549 : ops[i].op = XEXP (XEXP (this_op, 0), 0);
5548 : 1056549 : ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
5549 : 1056549 : ops[n_ops].neg = this_neg;
5550 : 1056549 : n_ops++;
5551 : 1056549 : changed = 1;
5552 : 1056549 : canonicalized = 1;
5553 : : }
5554 : : break;
5555 : :
5556 : 35610 : case NOT:
5557 : : /* ~a -> (-a - 1) */
5558 : 35610 : if (n_ops != ARRAY_SIZE (ops))
5559 : : {
5560 : 35610 : ops[n_ops].op = CONSTM1_RTX (mode);
5561 : 35610 : ops[n_ops++].neg = this_neg;
5562 : 35610 : ops[i].op = XEXP (this_op, 0);
5563 : 35610 : ops[i].neg = !this_neg;
5564 : 35610 : changed = 1;
5565 : 35610 : canonicalized = 1;
5566 : : }
5567 : : break;
5568 : :
5569 : 97985723 : CASE_CONST_SCALAR_INT:
5570 : 97985723 : case CONST_POLY_INT:
5571 : 97985723 : n_constants++;
5572 : 97985723 : if (this_neg)
5573 : : {
5574 : 924933 : ops[i].op = neg_poly_int_rtx (mode, this_op);
5575 : 924933 : ops[i].neg = 0;
5576 : 924933 : changed = 1;
5577 : 924933 : canonicalized = 1;
5578 : : }
5579 : : break;
5580 : :
5581 : : default:
5582 : : break;
5583 : : }
5584 : : }
5585 : : }
5586 : 62896565 : while (changed);
5587 : :
5588 : 31020449 : if (n_constants > 1)
5589 : 20290086 : canonicalized = 1;
5590 : :
5591 : 31020449 : gcc_assert (n_ops >= 2);
5592 : :
5593 : : /* If we only have two operands, we can avoid the loops. */
5594 : 31020449 : if (n_ops == 2)
5595 : : {
5596 : 0 : enum rtx_code code = ops[0].neg || ops[1].neg ? MINUS : PLUS;
5597 : 0 : rtx lhs, rhs;
5598 : :
5599 : : /* Get the two operands. Be careful with the order, especially for
5600 : : the cases where code == MINUS. */
5601 : 0 : if (ops[0].neg && ops[1].neg)
5602 : : {
5603 : 0 : lhs = gen_rtx_NEG (mode, ops[0].op);
5604 : 0 : rhs = ops[1].op;
5605 : : }
5606 : 0 : else if (ops[0].neg)
5607 : : {
5608 : 0 : lhs = ops[1].op;
5609 : 0 : rhs = ops[0].op;
5610 : : }
5611 : : else
5612 : : {
5613 : 0 : lhs = ops[0].op;
5614 : 0 : rhs = ops[1].op;
5615 : : }
5616 : :
5617 : 0 : return simplify_const_binary_operation (code, mode, lhs, rhs);
5618 : : }
5619 : :
5620 : : /* Now simplify each pair of operands until nothing changes. */
5621 : 51889812 : while (1)
5622 : : {
5623 : : /* Insertion sort is good enough for a small array. */
5624 : 136173709 : for (i = 1; i < n_ops; i++)
5625 : : {
5626 : 84283897 : struct simplify_plus_minus_op_data save;
5627 : 84283897 : int cmp;
5628 : :
5629 : 84283897 : j = i - 1;
5630 : 84283897 : cmp = simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op);
5631 : 84283897 : if (cmp <= 0)
5632 : 75156875 : continue;
5633 : : /* Just swapping registers doesn't count as canonicalization. */
5634 : 9127022 : if (cmp != 1)
5635 : 6650434 : canonicalized = 1;
5636 : :
5637 : 9127022 : save = ops[i];
5638 : 10877737 : do
5639 : 10877737 : ops[j + 1] = ops[j];
5640 : 10877737 : while (j--
5641 : 20004759 : && simplify_plus_minus_op_data_cmp (ops[j].op, save.op) > 0);
5642 : 9127022 : ops[j + 1] = save;
5643 : : }
5644 : :
5645 : 51889812 : changed = 0;
5646 : 136173709 : for (i = n_ops - 1; i > 0; i--)
5647 : 201550706 : for (j = i - 1; j >= 0; j--)
5648 : : {
5649 : 117903925 : rtx lhs = ops[j].op, rhs = ops[i].op;
5650 : 117903925 : int lneg = ops[j].neg, rneg = ops[i].neg;
5651 : :
5652 : 117903925 : if (lhs != 0 && rhs != 0)
5653 : : {
5654 : 96664003 : enum rtx_code ncode = PLUS;
5655 : :
5656 : 96664003 : if (lneg != rneg)
5657 : : {
5658 : 8259279 : ncode = MINUS;
5659 : 8259279 : if (lneg)
5660 : 5327748 : std::swap (lhs, rhs);
5661 : : }
5662 : 88404724 : else if (swap_commutative_operands_p (lhs, rhs))
5663 : 157939 : std::swap (lhs, rhs);
5664 : :
5665 : 96664003 : if ((GET_CODE (lhs) == CONST || CONST_INT_P (lhs))
5666 : 23732250 : && (GET_CODE (rhs) == CONST || CONST_INT_P (rhs)))
5667 : : {
5668 : 20420140 : rtx tem_lhs, tem_rhs;
5669 : :
5670 : 20420140 : tem_lhs = GET_CODE (lhs) == CONST ? XEXP (lhs, 0) : lhs;
5671 : 20420140 : tem_rhs = GET_CODE (rhs) == CONST ? XEXP (rhs, 0) : rhs;
5672 : 20420140 : tem = simplify_binary_operation (ncode, mode, tem_lhs,
5673 : : tem_rhs);
5674 : :
5675 : 20420140 : if (tem && !CONSTANT_P (tem))
5676 : 1500 : tem = gen_rtx_CONST (GET_MODE (tem), tem);
5677 : : }
5678 : : else
5679 : 76243863 : tem = simplify_binary_operation (ncode, mode, lhs, rhs);
5680 : :
5681 : 76245363 : if (tem)
5682 : : {
5683 : : /* Reject "simplifications" that just wrap the two
5684 : : arguments in a CONST. Failure to do so can result
5685 : : in infinite recursion with simplify_binary_operation
5686 : : when it calls us to simplify CONST operations.
5687 : : Also, if we find such a simplification, don't try
5688 : : any more combinations with this rhs: We must have
5689 : : something like symbol+offset, ie. one of the
5690 : : trivial CONST expressions we handle later. */
5691 : 21897227 : if (GET_CODE (tem) == CONST
5692 : 638616 : && GET_CODE (XEXP (tem, 0)) == ncode
5693 : 638081 : && XEXP (XEXP (tem, 0), 0) == lhs
5694 : 637116 : && XEXP (XEXP (tem, 0), 1) == rhs)
5695 : : break;
5696 : 21260111 : lneg &= rneg;
5697 : 21260111 : if (GET_CODE (tem) == NEG)
5698 : 35303 : tem = XEXP (tem, 0), lneg = !lneg;
5699 : 21260111 : if (poly_int_rtx_p (tem) && lneg)
5700 : 0 : tem = neg_poly_int_rtx (mode, tem), lneg = 0;
5701 : :
5702 : 21260111 : ops[i].op = tem;
5703 : 21260111 : ops[i].neg = lneg;
5704 : 21260111 : ops[j].op = NULL_RTX;
5705 : 21260111 : changed = 1;
5706 : 21260111 : canonicalized = 1;
5707 : : }
5708 : : }
5709 : : }
5710 : :
5711 : 51889812 : if (!changed)
5712 : : break;
5713 : :
5714 : : /* Pack all the operands to the lower-numbered entries. */
5715 : 83943360 : for (i = 0, j = 0; j < n_ops; j++)
5716 : 63073997 : if (ops[j].op)
5717 : : {
5718 : 41813886 : ops[i] = ops[j];
5719 : 41813886 : i++;
5720 : : }
5721 : : n_ops = i;
5722 : : }
5723 : :
5724 : : /* If nothing changed, check that rematerialization of rtl instructions
5725 : : is still required. */
5726 : 31020449 : if (!canonicalized)
5727 : : {
5728 : : /* Perform rematerialization if only all operands are registers and
5729 : : all operations are PLUS. */
5730 : : /* ??? Also disallow (non-global, non-frame) fixed registers to work
5731 : : around rs6000 and how it uses the CA register. See PR67145. */
5732 : 4278672 : for (i = 0; i < n_ops; i++)
5733 : 3445790 : if (ops[i].neg
5734 : 3235362 : || !REG_P (ops[i].op)
5735 : 6164138 : || (REGNO (ops[i].op) < FIRST_PSEUDO_REGISTER
5736 : 6609 : && fixed_regs[REGNO (ops[i].op)]
5737 : 159 : && !global_regs[REGNO (ops[i].op)]
5738 : 159 : && ops[i].op != frame_pointer_rtx
5739 : 41 : && ops[i].op != arg_pointer_rtx
5740 : 38 : && ops[i].op != stack_pointer_rtx))
5741 : : return NULL_RTX;
5742 : 832882 : goto gen_result;
5743 : : }
5744 : :
5745 : : /* Create (minus -C X) instead of (neg (const (plus X C))). */
5746 : 29460125 : if (n_ops == 2
5747 : 19797475 : && CONST_INT_P (ops[1].op)
5748 : 19479298 : && CONSTANT_P (ops[0].op)
5749 : 131 : && ops[0].neg)
5750 : 102 : return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
5751 : :
5752 : : /* We suppressed creation of trivial CONST expressions in the
5753 : : combination loop to avoid recursion. Create one manually now.
5754 : : The combination loop should have ensured that there is exactly
5755 : : one CONST_INT, and the sort will have ensured that it is last
5756 : : in the array and that any other constant will be next-to-last. */
5757 : :
5758 : 29460023 : if (n_ops > 1
5759 : 29017537 : && poly_int_rtx_p (ops[n_ops - 1].op)
5760 : 56581219 : && CONSTANT_P (ops[n_ops - 2].op))
5761 : : {
5762 : 1102107 : rtx value = ops[n_ops - 1].op;
5763 : 1102107 : if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg)
5764 : 531750 : value = neg_poly_int_rtx (mode, value);
5765 : 1102107 : if (CONST_INT_P (value))
5766 : : {
5767 : 2204214 : ops[n_ops - 2].op = plus_constant (mode, ops[n_ops - 2].op,
5768 : 1102107 : INTVAL (value));
5769 : 1102107 : n_ops--;
5770 : : }
5771 : : }
5772 : :
5773 : : /* Put a non-negated operand first, if possible. */
5774 : :
5775 : 30854852 : for (i = 0; i < n_ops && ops[i].neg; i++)
5776 : 1394829 : continue;
5777 : 29460023 : if (i == n_ops)
5778 : 7545 : ops[0].op = gen_rtx_NEG (mode, ops[0].op);
5779 : 29452478 : else if (i != 0)
5780 : : {
5781 : 1310300 : tem = ops[0].op;
5782 : 1310300 : ops[0] = ops[i];
5783 : 1310300 : ops[i].op = tem;
5784 : 1310300 : ops[i].neg = 1;
5785 : : }
5786 : :
5787 : : /* Now make the result by performing the requested operations. */
5788 : 28142178 : gen_result:
5789 : 30292905 : result = ops[0].op;
5790 : 69814025 : for (i = 1; i < n_ops; i++)
5791 : 79042240 : result = gen_rtx_fmt_ee (ops[i].neg ? MINUS : PLUS,
5792 : : mode, result, ops[i].op);
5793 : :
5794 : : return result;
5795 : 1394829 : }
5796 : :
5797 : : /* Check whether an operand is suitable for calling simplify_plus_minus. */
5798 : : static bool
5799 : 416185789 : plus_minus_operand_p (const_rtx x)
5800 : : {
5801 : 416185789 : return GET_CODE (x) == PLUS
5802 : 416185789 : || GET_CODE (x) == MINUS
5803 : 416185789 : || (GET_CODE (x) == CONST
5804 : 1549091 : && GET_CODE (XEXP (x, 0)) == PLUS
5805 : 998097 : && CONSTANT_P (XEXP (XEXP (x, 0), 0))
5806 : 929500 : && CONSTANT_P (XEXP (XEXP (x, 0), 1)));
5807 : : }
5808 : :
5809 : : /* Like simplify_binary_operation except used for relational operators.
5810 : : MODE is the mode of the result. If MODE is VOIDmode, both operands must
5811 : : not also be VOIDmode.
5812 : :
5813 : : CMP_MODE specifies in which mode the comparison is done in, so it is
5814 : : the mode of the operands. If CMP_MODE is VOIDmode, it is taken from
5815 : : the operands or, if both are VOIDmode, the operands are compared in
5816 : : "infinite precision". */
5817 : : rtx
5818 : 98028197 : simplify_context::simplify_relational_operation (rtx_code code,
5819 : : machine_mode mode,
5820 : : machine_mode cmp_mode,
5821 : : rtx op0, rtx op1)
5822 : : {
5823 : 98028197 : rtx tem, trueop0, trueop1;
5824 : :
5825 : 98028197 : if (cmp_mode == VOIDmode)
5826 : 20238745 : cmp_mode = GET_MODE (op0);
5827 : 20238745 : if (cmp_mode == VOIDmode)
5828 : 426116 : cmp_mode = GET_MODE (op1);
5829 : :
5830 : 98028197 : tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
5831 : 98028197 : if (tem)
5832 : 743227 : return relational_result (mode, cmp_mode, tem);
5833 : :
5834 : : /* For the following tests, ensure const0_rtx is op1. */
5835 : 97284970 : if (swap_commutative_operands_p (op0, op1)
5836 : 97284970 : || (op0 == const0_rtx && op1 != const0_rtx))
5837 : 2102600 : std::swap (op0, op1), code = swap_condition (code);
5838 : :
5839 : : /* If op0 is a compare, extract the comparison arguments from it. */
5840 : 97284970 : if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
5841 : 7921188 : return simplify_gen_relational (code, mode, VOIDmode,
5842 : 7921188 : XEXP (op0, 0), XEXP (op0, 1));
5843 : :
5844 : 89363782 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
5845 : : return NULL_RTX;
5846 : :
5847 : 63812088 : trueop0 = avoid_constant_pool_reference (op0);
5848 : 63812088 : trueop1 = avoid_constant_pool_reference (op1);
5849 : 63812088 : return simplify_relational_operation_1 (code, mode, cmp_mode,
5850 : 63812088 : trueop0, trueop1);
5851 : : }
5852 : :
5853 : : /* This part of simplify_relational_operation is only used when CMP_MODE
5854 : : is not in class MODE_CC (i.e. it is a real comparison).
5855 : :
5856 : : MODE is the mode of the result, while CMP_MODE specifies in which
5857 : : mode the comparison is done in, so it is the mode of the operands. */
5858 : :
5859 : : rtx
5860 : 63812088 : simplify_context::simplify_relational_operation_1 (rtx_code code,
5861 : : machine_mode mode,
5862 : : machine_mode cmp_mode,
5863 : : rtx op0, rtx op1)
5864 : : {
5865 : 63812088 : enum rtx_code op0code = GET_CODE (op0);
5866 : :
5867 : 63812088 : if (op1 == const0_rtx && COMPARISON_P (op0))
5868 : : {
5869 : : /* If op0 is a comparison, extract the comparison arguments
5870 : : from it. */
5871 : 424326 : if (code == NE)
5872 : : {
5873 : 204048 : if (GET_MODE (op0) == mode)
5874 : 203 : return simplify_rtx (op0);
5875 : : else
5876 : 203845 : return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
5877 : 203845 : XEXP (op0, 0), XEXP (op0, 1));
5878 : : }
5879 : 220278 : else if (code == EQ)
5880 : : {
5881 : 90714 : enum rtx_code new_code = reversed_comparison_code (op0, NULL);
5882 : 90714 : if (new_code != UNKNOWN)
5883 : 90398 : return simplify_gen_relational (new_code, mode, VOIDmode,
5884 : 90398 : XEXP (op0, 0), XEXP (op0, 1));
5885 : : }
5886 : : }
5887 : :
5888 : : /* (LTU/GEU (PLUS a C) C), where C is constant, can be simplified to
5889 : : (GEU/LTU a -C). Likewise for (LTU/GEU (PLUS a C) a). */
5890 : 63517642 : if ((code == LTU || code == GEU)
5891 : 3150381 : && GET_CODE (op0) == PLUS
5892 : 560550 : && CONST_INT_P (XEXP (op0, 1))
5893 : 336465 : && (rtx_equal_p (op1, XEXP (op0, 0))
5894 : 254647 : || rtx_equal_p (op1, XEXP (op0, 1)))
5895 : : /* (LTU/GEU (PLUS a 0) 0) is not the same as (GEU/LTU a 0). */
5896 : 63660544 : && XEXP (op0, 1) != const0_rtx)
5897 : : {
5898 : 142902 : rtx new_cmp
5899 : 142902 : = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
5900 : 144967 : return simplify_gen_relational ((code == LTU ? GEU : LTU), mode,
5901 : 142902 : cmp_mode, XEXP (op0, 0), new_cmp);
5902 : : }
5903 : :
5904 : : /* (GTU (PLUS a C) (C - 1)) where C is a non-zero constant can be
5905 : : transformed into (LTU a -C). */
5906 : 63374740 : if (code == GTU && GET_CODE (op0) == PLUS && CONST_INT_P (op1)
5907 : 291942 : && CONST_INT_P (XEXP (op0, 1))
5908 : 232963 : && (UINTVAL (op1) == UINTVAL (XEXP (op0, 1)) - 1)
5909 : 24196 : && XEXP (op0, 1) != const0_rtx)
5910 : : {
5911 : 24196 : rtx new_cmp
5912 : 24196 : = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
5913 : 24196 : return simplify_gen_relational (LTU, mode, cmp_mode,
5914 : 24196 : XEXP (op0, 0), new_cmp);
5915 : : }
5916 : :
5917 : : /* Canonicalize (LTU/GEU (PLUS a b) b) as (LTU/GEU (PLUS a b) a). */
5918 : 63350544 : if ((code == LTU || code == GEU)
5919 : 3007479 : && GET_CODE (op0) == PLUS
5920 : 417648 : && rtx_equal_p (op1, XEXP (op0, 1))
5921 : : /* Don't recurse "infinitely" for (LTU/GEU (PLUS b b) b). */
5922 : 63359628 : && !rtx_equal_p (op1, XEXP (op0, 0)))
5923 : 9084 : return simplify_gen_relational (code, mode, cmp_mode, op0,
5924 : 9084 : copy_rtx (XEXP (op0, 0)));
5925 : :
5926 : 63341460 : if (op1 == const0_rtx)
5927 : : {
5928 : : /* Canonicalize (GTU x 0) as (NE x 0). */
5929 : 29502800 : if (code == GTU)
5930 : 172060 : return simplify_gen_relational (NE, mode, cmp_mode, op0, op1);
5931 : : /* Canonicalize (LEU x 0) as (EQ x 0). */
5932 : 29330740 : if (code == LEU)
5933 : 35027 : return simplify_gen_relational (EQ, mode, cmp_mode, op0, op1);
5934 : : }
5935 : 33838660 : else if (op1 == const1_rtx)
5936 : : {
5937 : 2367562 : switch (code)
5938 : : {
5939 : 8460 : case GE:
5940 : : /* Canonicalize (GE x 1) as (GT x 0). */
5941 : 8460 : return simplify_gen_relational (GT, mode, cmp_mode,
5942 : 8460 : op0, const0_rtx);
5943 : 132186 : case GEU:
5944 : : /* Canonicalize (GEU x 1) as (NE x 0). */
5945 : 132186 : return simplify_gen_relational (NE, mode, cmp_mode,
5946 : 132186 : op0, const0_rtx);
5947 : 9453 : case LT:
5948 : : /* Canonicalize (LT x 1) as (LE x 0). */
5949 : 9453 : return simplify_gen_relational (LE, mode, cmp_mode,
5950 : 9453 : op0, const0_rtx);
5951 : 22464 : case LTU:
5952 : : /* Canonicalize (LTU x 1) as (EQ x 0). */
5953 : 22464 : return simplify_gen_relational (EQ, mode, cmp_mode,
5954 : 22464 : op0, const0_rtx);
5955 : : default:
5956 : : break;
5957 : : }
5958 : : }
5959 : 31471098 : else if (op1 == constm1_rtx)
5960 : : {
5961 : : /* Canonicalize (LE x -1) as (LT x 0). */
5962 : 893274 : if (code == LE)
5963 : 1575 : return simplify_gen_relational (LT, mode, cmp_mode, op0, const0_rtx);
5964 : : /* Canonicalize (GT x -1) as (GE x 0). */
5965 : 891699 : if (code == GT)
5966 : 5528 : return simplify_gen_relational (GE, mode, cmp_mode, op0, const0_rtx);
5967 : : }
5968 : :
5969 : : /* (eq/ne (plus x cst1) cst2) simplifies to (eq/ne x (cst2 - cst1)) */
5970 : 62954707 : if ((code == EQ || code == NE)
5971 : 47805321 : && (op0code == PLUS || op0code == MINUS)
5972 : 1875591 : && CONSTANT_P (op1)
5973 : 779476 : && CONSTANT_P (XEXP (op0, 1))
5974 : 436239 : && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
5975 : : {
5976 : 436207 : rtx x = XEXP (op0, 0);
5977 : 436207 : rtx c = XEXP (op0, 1);
5978 : 436207 : enum rtx_code invcode = op0code == PLUS ? MINUS : PLUS;
5979 : 436207 : rtx tem = simplify_gen_binary (invcode, cmp_mode, op1, c);
5980 : :
5981 : : /* Detect an infinite recursive condition, where we oscillate at this
5982 : : simplification case between:
5983 : : A + B == C <---> C - B == A,
5984 : : where A, B, and C are all constants with non-simplifiable expressions,
5985 : : usually SYMBOL_REFs. */
5986 : 436207 : if (GET_CODE (tem) == invcode
5987 : 46 : && CONSTANT_P (x)
5988 : 436225 : && rtx_equal_p (c, XEXP (tem, 1)))
5989 : : return NULL_RTX;
5990 : :
5991 : 436189 : return simplify_gen_relational (code, mode, cmp_mode, x, tem);
5992 : : }
5993 : :
5994 : : /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is
5995 : : the same as (zero_extract:SI FOO (const_int 1) BAR). */
5996 : 47369114 : scalar_int_mode int_mode, int_cmp_mode;
5997 : 47369114 : if (code == NE
5998 : 24911690 : && op1 == const0_rtx
5999 : 1823056 : && is_int_mode (mode, &int_mode)
6000 : 62477253 : && is_a <scalar_int_mode> (cmp_mode, &int_cmp_mode)
6001 : : /* ??? Work-around BImode bugs in the ia64 backend. */
6002 : 1823056 : && int_mode != BImode
6003 : 1823038 : && int_cmp_mode != BImode
6004 : 1823038 : && nonzero_bits (op0, int_cmp_mode) == 1
6005 : 47369114 : && STORE_FLAG_VALUE == 1)
6006 : 82494 : return GET_MODE_SIZE (int_mode) > GET_MODE_SIZE (int_cmp_mode)
6007 : 41247 : ? simplify_gen_unary (ZERO_EXTEND, int_mode, op0, int_cmp_mode)
6008 : 11813 : : lowpart_subreg (int_mode, op0, int_cmp_mode);
6009 : :
6010 : : /* (eq/ne (xor x y) 0) simplifies to (eq/ne x y). */
6011 : 62477253 : if ((code == EQ || code == NE)
6012 : 47327867 : && op1 == const0_rtx
6013 : 26190322 : && op0code == XOR)
6014 : 15623 : return simplify_gen_relational (code, mode, cmp_mode,
6015 : 15623 : XEXP (op0, 0), XEXP (op0, 1));
6016 : :
6017 : : /* (eq/ne (xor x y) x) simplifies to (eq/ne y 0). */
6018 : 47312244 : if ((code == EQ || code == NE)
6019 : 47312244 : && op0code == XOR
6020 : 3316 : && rtx_equal_p (XEXP (op0, 0), op1)
6021 : 0 : && !side_effects_p (XEXP (op0, 0)))
6022 : 0 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 1),
6023 : 0 : CONST0_RTX (mode));
6024 : :
6025 : : /* Likewise (eq/ne (xor x y) y) simplifies to (eq/ne x 0). */
6026 : 62461630 : if ((code == EQ || code == NE)
6027 : 47312244 : && op0code == XOR
6028 : 3316 : && rtx_equal_p (XEXP (op0, 1), op1)
6029 : 62461720 : && !side_effects_p (XEXP (op0, 1)))
6030 : 90 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6031 : 90 : CONST0_RTX (mode));
6032 : :
6033 : : /* (eq/ne (xor x C1) C2) simplifies to (eq/ne x (C1^C2)). */
6034 : 62461540 : if ((code == EQ || code == NE)
6035 : 47312154 : && op0code == XOR
6036 : 3226 : && CONST_SCALAR_INT_P (op1)
6037 : 533 : && CONST_SCALAR_INT_P (XEXP (op0, 1)))
6038 : 79 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6039 : : simplify_gen_binary (XOR, cmp_mode,
6040 : 79 : XEXP (op0, 1), op1));
6041 : :
6042 : : /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or
6043 : : constant folding if x/y is a constant. */
6044 : 47312075 : if ((code == EQ || code == NE)
6045 : 47312075 : && (op0code == AND || op0code == IOR)
6046 : 3003420 : && !side_effects_p (op1)
6047 : 3003376 : && op1 != CONST0_RTX (cmp_mode))
6048 : : {
6049 : : /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to
6050 : : (eq/ne (and (not y) x) 0). */
6051 : 480024 : if ((op0code == AND && rtx_equal_p (XEXP (op0, 0), op1))
6052 : 959241 : || (op0code == IOR && rtx_equal_p (XEXP (op0, 1), op1)))
6053 : : {
6054 : 20108 : rtx not_y = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 1),
6055 : : cmp_mode);
6056 : 20108 : rtx lhs = simplify_gen_binary (AND, cmp_mode, not_y, XEXP (op0, 0));
6057 : :
6058 : 20108 : return simplify_gen_relational (code, mode, cmp_mode, lhs,
6059 : 20108 : CONST0_RTX (cmp_mode));
6060 : : }
6061 : :
6062 : : /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to
6063 : : (eq/ne (and (not x) y) 0). */
6064 : 459972 : if ((op0code == AND && rtx_equal_p (XEXP (op0, 1), op1))
6065 : 894332 : || (op0code == IOR && rtx_equal_p (XEXP (op0, 0), op1)))
6066 : : {
6067 : 44831 : rtx not_x = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 0),
6068 : : cmp_mode);
6069 : 44831 : rtx lhs = simplify_gen_binary (AND, cmp_mode, not_x, XEXP (op0, 1));
6070 : :
6071 : 44831 : return simplify_gen_relational (code, mode, cmp_mode, lhs,
6072 : 44831 : CONST0_RTX (cmp_mode));
6073 : : }
6074 : : }
6075 : :
6076 : : /* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped. */
6077 : 62396522 : if ((code == EQ || code == NE)
6078 : 47247136 : && GET_CODE (op0) == BSWAP
6079 : 100 : && CONST_SCALAR_INT_P (op1))
6080 : 23 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6081 : : simplify_gen_unary (BSWAP, cmp_mode,
6082 : 23 : op1, cmp_mode));
6083 : :
6084 : : /* (eq/ne (bswap x) (bswap y)) simplifies to (eq/ne x y). */
6085 : 47247113 : if ((code == EQ || code == NE)
6086 : 47247113 : && GET_CODE (op0) == BSWAP
6087 : 77 : && GET_CODE (op1) == BSWAP)
6088 : 0 : return simplify_gen_relational (code, mode, cmp_mode,
6089 : 0 : XEXP (op0, 0), XEXP (op1, 0));
6090 : :
6091 : 62396499 : if (op0code == POPCOUNT && op1 == const0_rtx)
6092 : 0 : switch (code)
6093 : : {
6094 : 0 : case EQ:
6095 : 0 : case LE:
6096 : 0 : case LEU:
6097 : : /* (eq (popcount x) (const_int 0)) -> (eq x (const_int 0)). */
6098 : 0 : return simplify_gen_relational (EQ, mode, GET_MODE (XEXP (op0, 0)),
6099 : 0 : XEXP (op0, 0), const0_rtx);
6100 : :
6101 : 0 : case NE:
6102 : 0 : case GT:
6103 : 0 : case GTU:
6104 : : /* (ne (popcount x) (const_int 0)) -> (ne x (const_int 0)). */
6105 : 0 : return simplify_gen_relational (NE, mode, GET_MODE (XEXP (op0, 0)),
6106 : 0 : XEXP (op0, 0), const0_rtx);
6107 : :
6108 : : default:
6109 : : break;
6110 : : }
6111 : :
6112 : : /* (ne:SI (subreg:QI (ashift:SI x 7) 0) 0) -> (and:SI x 1). */
6113 : 62396499 : if (code == NE
6114 : 24821007 : && op1 == const0_rtx
6115 : 13008135 : && (op0code == TRUNCATE
6116 : 13008135 : || (partial_subreg_p (op0)
6117 : 190746 : && subreg_lowpart_p (op0)))
6118 : 167594 : && SCALAR_INT_MODE_P (mode)
6119 : 62396499 : && STORE_FLAG_VALUE == 1)
6120 : : {
6121 : 31421 : rtx tmp = XEXP (op0, 0);
6122 : 31421 : if (GET_CODE (tmp) == ASHIFT
6123 : 1449 : && GET_MODE (tmp) == mode
6124 : 172 : && CONST_INT_P (XEXP (tmp, 1))
6125 : 172 : && is_int_mode (GET_MODE (op0), &int_mode)
6126 : 31593 : && INTVAL (XEXP (tmp, 1)) == GET_MODE_PRECISION (int_mode) - 1)
6127 : 172 : return simplify_gen_binary (AND, mode, XEXP (tmp, 0), const1_rtx);
6128 : : }
6129 : : return NULL_RTX;
6130 : : }
6131 : :
6132 : : enum
6133 : : {
6134 : : CMP_EQ = 1,
6135 : : CMP_LT = 2,
6136 : : CMP_GT = 4,
6137 : : CMP_LTU = 8,
6138 : : CMP_GTU = 16
6139 : : };
6140 : :
6141 : :
6142 : : /* Convert the known results for EQ, LT, GT, LTU, GTU contained in
6143 : : KNOWN_RESULT to a CONST_INT, based on the requested comparison CODE
6144 : : For KNOWN_RESULT to make sense it should be either CMP_EQ, or the
6145 : : logical OR of one of (CMP_LT, CMP_GT) and one of (CMP_LTU, CMP_GTU).
6146 : : For floating-point comparisons, assume that the operands were ordered. */
6147 : :
6148 : : static rtx
6149 : 521883 : comparison_result (enum rtx_code code, int known_results)
6150 : : {
6151 : 521883 : switch (code)
6152 : : {
6153 : 105610 : case EQ:
6154 : 105610 : case UNEQ:
6155 : 105610 : return (known_results & CMP_EQ) ? const_true_rtx : const0_rtx;
6156 : 387793 : case NE:
6157 : 387793 : case LTGT:
6158 : 387793 : return (known_results & CMP_EQ) ? const0_rtx : const_true_rtx;
6159 : :
6160 : 1073 : case LT:
6161 : 1073 : case UNLT:
6162 : 1073 : return (known_results & CMP_LT) ? const_true_rtx : const0_rtx;
6163 : 235 : case GE:
6164 : 235 : case UNGE:
6165 : 235 : return (known_results & CMP_LT) ? const0_rtx : const_true_rtx;
6166 : :
6167 : 3814 : case GT:
6168 : 3814 : case UNGT:
6169 : 3814 : return (known_results & CMP_GT) ? const_true_rtx : const0_rtx;
6170 : 5307 : case LE:
6171 : 5307 : case UNLE:
6172 : 5307 : return (known_results & CMP_GT) ? const0_rtx : const_true_rtx;
6173 : :
6174 : 1852 : case LTU:
6175 : 1852 : return (known_results & CMP_LTU) ? const_true_rtx : const0_rtx;
6176 : 549 : case GEU:
6177 : 549 : return (known_results & CMP_LTU) ? const0_rtx : const_true_rtx;
6178 : :
6179 : 13960 : case GTU:
6180 : 13960 : return (known_results & CMP_GTU) ? const_true_rtx : const0_rtx;
6181 : 1682 : case LEU:
6182 : 1682 : return (known_results & CMP_GTU) ? const0_rtx : const_true_rtx;
6183 : :
6184 : 0 : case ORDERED:
6185 : 0 : return const_true_rtx;
6186 : 8 : case UNORDERED:
6187 : 8 : return const0_rtx;
6188 : 0 : default:
6189 : 0 : gcc_unreachable ();
6190 : : }
6191 : : }
6192 : :
6193 : : /* Check if the given comparison (done in the given MODE) is actually
6194 : : a tautology or a contradiction. If the mode is VOIDmode, the
6195 : : comparison is done in "infinite precision". If no simplification
6196 : : is possible, this function returns zero. Otherwise, it returns
6197 : : either const_true_rtx or const0_rtx. */
6198 : :
6199 : : rtx
6200 : 98028197 : simplify_const_relational_operation (enum rtx_code code,
6201 : : machine_mode mode,
6202 : : rtx op0, rtx op1)
6203 : : {
6204 : 103353752 : rtx tem;
6205 : 103353752 : rtx trueop0;
6206 : 103353752 : rtx trueop1;
6207 : :
6208 : 103353752 : gcc_assert (mode != VOIDmode
6209 : : || (GET_MODE (op0) == VOIDmode
6210 : : && GET_MODE (op1) == VOIDmode));
6211 : :
6212 : : /* We only handle MODE_CC comparisons that are COMPARE against zero. */
6213 : 103353752 : if (GET_MODE_CLASS (mode) == MODE_CC
6214 : 33477150 : && (op1 != const0_rtx
6215 : 33477150 : || GET_CODE (op0) != COMPARE))
6216 : : return NULL_RTX;
6217 : :
6218 : : /* If op0 is a compare, extract the comparison arguments from it. */
6219 : 77802058 : if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
6220 : : {
6221 : 7925456 : op1 = XEXP (op0, 1);
6222 : 7925456 : op0 = XEXP (op0, 0);
6223 : :
6224 : 7925456 : if (GET_MODE (op0) != VOIDmode)
6225 : 7831850 : mode = GET_MODE (op0);
6226 : 93606 : else if (GET_MODE (op1) != VOIDmode)
6227 : 84456 : mode = GET_MODE (op1);
6228 : : else
6229 : : return 0;
6230 : : }
6231 : :
6232 : : /* We can't simplify MODE_CC values since we don't know what the
6233 : : actual comparison is. */
6234 : 77792908 : if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
6235 : : return 0;
6236 : :
6237 : : /* Make sure the constant is second. */
6238 : 77792908 : if (swap_commutative_operands_p (op0, op1))
6239 : : {
6240 : 2496013 : std::swap (op0, op1);
6241 : 2496013 : code = swap_condition (code);
6242 : : }
6243 : :
6244 : 77792908 : trueop0 = avoid_constant_pool_reference (op0);
6245 : 77792908 : trueop1 = avoid_constant_pool_reference (op1);
6246 : :
6247 : : /* For integer comparisons of A and B maybe we can simplify A - B and can
6248 : : then simplify a comparison of that with zero. If A and B are both either
6249 : : a register or a CONST_INT, this can't help; testing for these cases will
6250 : : prevent infinite recursion here and speed things up.
6251 : :
6252 : : We can only do this for EQ and NE comparisons as otherwise we may
6253 : : lose or introduce overflow which we cannot disregard as undefined as
6254 : : we do not know the signedness of the operation on either the left or
6255 : : the right hand side of the comparison. */
6256 : :
6257 : 77792908 : if (INTEGRAL_MODE_P (mode) && trueop1 != const0_rtx
6258 : 37115381 : && (code == EQ || code == NE)
6259 : 24014269 : && ! ((REG_P (op0) || CONST_INT_P (trueop0))
6260 : 16955279 : && (REG_P (op1) || CONST_INT_P (trueop1)))
6261 : 9432587 : && (tem = simplify_binary_operation (MINUS, mode, op0, op1)) != 0
6262 : : /* We cannot do this if tem is a nonzero address. */
6263 : 5325557 : && ! nonzero_address_p (tem))
6264 : 5325555 : return simplify_const_relational_operation (signed_condition (code),
6265 : 5325555 : mode, tem, const0_rtx);
6266 : :
6267 : 72467353 : if (! HONOR_NANS (mode) && code == ORDERED)
6268 : 0 : return const_true_rtx;
6269 : :
6270 : 72467353 : if (! HONOR_NANS (mode) && code == UNORDERED)
6271 : 0 : return const0_rtx;
6272 : :
6273 : : /* For modes without NaNs, if the two operands are equal, we know the
6274 : : result except if they have side-effects. Even with NaNs we know
6275 : : the result of unordered comparisons and, if signaling NaNs are
6276 : : irrelevant, also the result of LT/GT/LTGT. */
6277 : 72467353 : if ((! HONOR_NANS (trueop0)
6278 : 1729073 : || code == UNEQ || code == UNLE || code == UNGE
6279 : : || ((code == LT || code == GT || code == LTGT)
6280 : 681807 : && ! HONOR_SNANS (trueop0)))
6281 : 71513215 : && rtx_equal_p (trueop0, trueop1)
6282 : 72873518 : && ! side_effects_p (trueop0))
6283 : 406161 : return comparison_result (code, CMP_EQ);
6284 : :
6285 : : /* If the operands are floating-point constants, see if we can fold
6286 : : the result. */
6287 : 72061192 : if (CONST_DOUBLE_AS_FLOAT_P (trueop0)
6288 : 1284 : && CONST_DOUBLE_AS_FLOAT_P (trueop1)
6289 : 1284 : && SCALAR_FLOAT_MODE_P (GET_MODE (trueop0)))
6290 : : {
6291 : 1284 : const REAL_VALUE_TYPE *d0 = CONST_DOUBLE_REAL_VALUE (trueop0);
6292 : 1284 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
6293 : :
6294 : : /* Comparisons are unordered iff at least one of the values is NaN. */
6295 : 1284 : if (REAL_VALUE_ISNAN (*d0) || REAL_VALUE_ISNAN (*d1))
6296 : 60 : switch (code)
6297 : : {
6298 : 0 : case UNEQ:
6299 : 0 : case UNLT:
6300 : 0 : case UNGT:
6301 : 0 : case UNLE:
6302 : 0 : case UNGE:
6303 : 0 : case NE:
6304 : 0 : case UNORDERED:
6305 : 0 : return const_true_rtx;
6306 : 60 : case EQ:
6307 : 60 : case LT:
6308 : 60 : case GT:
6309 : 60 : case LE:
6310 : 60 : case GE:
6311 : 60 : case LTGT:
6312 : 60 : case ORDERED:
6313 : 60 : return const0_rtx;
6314 : : default:
6315 : : return 0;
6316 : : }
6317 : :
6318 : 1262 : return comparison_result (code,
6319 : 1262 : (real_equal (d0, d1) ? CMP_EQ :
6320 : 1262 : real_less (d0, d1) ? CMP_LT : CMP_GT));
6321 : : }
6322 : :
6323 : : /* Otherwise, see if the operands are both integers. */
6324 : 72059908 : if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
6325 : 69837765 : && CONST_SCALAR_INT_P (trueop0) && CONST_SCALAR_INT_P (trueop1))
6326 : : {
6327 : : /* It would be nice if we really had a mode here. However, the
6328 : : largest int representable on the target is as good as
6329 : : infinite. */
6330 : 114498 : machine_mode cmode = (mode == VOIDmode) ? MAX_MODE_INT : mode;
6331 : 114498 : rtx_mode_t ptrueop0 = rtx_mode_t (trueop0, cmode);
6332 : 114498 : rtx_mode_t ptrueop1 = rtx_mode_t (trueop1, cmode);
6333 : :
6334 : 114498 : if (wi::eq_p (ptrueop0, ptrueop1))
6335 : 0 : return comparison_result (code, CMP_EQ);
6336 : : else
6337 : : {
6338 : 114498 : int cr = wi::lts_p (ptrueop0, ptrueop1) ? CMP_LT : CMP_GT;
6339 : 114498 : cr |= wi::ltu_p (ptrueop0, ptrueop1) ? CMP_LTU : CMP_GTU;
6340 : 114498 : return comparison_result (code, cr);
6341 : : }
6342 : : }
6343 : :
6344 : : /* Optimize comparisons with upper and lower bounds. */
6345 : 71945410 : scalar_int_mode int_mode;
6346 : 71945410 : if (CONST_INT_P (trueop1)
6347 : 52243426 : && is_a <scalar_int_mode> (mode, &int_mode)
6348 : 52243426 : && HWI_COMPUTABLE_MODE_P (int_mode)
6349 : 123666950 : && !side_effects_p (trueop0))
6350 : : {
6351 : 51633817 : int sign;
6352 : 51633817 : unsigned HOST_WIDE_INT nonzero = nonzero_bits (trueop0, int_mode);
6353 : 51633817 : HOST_WIDE_INT val = INTVAL (trueop1);
6354 : 51633817 : HOST_WIDE_INT mmin, mmax;
6355 : :
6356 : 51633817 : if (code == GEU
6357 : 51633817 : || code == LEU
6358 : 49417673 : || code == GTU
6359 : 49417673 : || code == LTU)
6360 : : sign = 0;
6361 : : else
6362 : 51633817 : sign = 1;
6363 : :
6364 : : /* Get a reduced range if the sign bit is zero. */
6365 : 51633817 : if (nonzero <= (GET_MODE_MASK (int_mode) >> 1))
6366 : : {
6367 : 5141897 : mmin = 0;
6368 : 5141897 : mmax = nonzero;
6369 : : }
6370 : : else
6371 : : {
6372 : 46491920 : rtx mmin_rtx, mmax_rtx;
6373 : 46491920 : get_mode_bounds (int_mode, sign, int_mode, &mmin_rtx, &mmax_rtx);
6374 : :
6375 : 46491920 : mmin = INTVAL (mmin_rtx);
6376 : 46491920 : mmax = INTVAL (mmax_rtx);
6377 : 46491920 : if (sign)
6378 : : {
6379 : 42297844 : unsigned int sign_copies
6380 : 42297844 : = num_sign_bit_copies (trueop0, int_mode);
6381 : :
6382 : 42297844 : mmin >>= (sign_copies - 1);
6383 : 42297844 : mmax >>= (sign_copies - 1);
6384 : : }
6385 : : }
6386 : :
6387 : 51633817 : switch (code)
6388 : : {
6389 : : /* x >= y is always true for y <= mmin, always false for y > mmax. */
6390 : 326318 : case GEU:
6391 : 326318 : if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
6392 : 10141 : return const_true_rtx;
6393 : 316177 : if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
6394 : 45 : return const0_rtx;
6395 : : break;
6396 : 842180 : case GE:
6397 : 842180 : if (val <= mmin)
6398 : 1677 : return const_true_rtx;
6399 : 840503 : if (val > mmax)
6400 : 0 : return const0_rtx;
6401 : : break;
6402 : :
6403 : : /* x <= y is always true for y >= mmax, always false for y < mmin. */
6404 : 1889826 : case LEU:
6405 : 1889826 : if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
6406 : 8005 : return const_true_rtx;
6407 : 1881821 : if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
6408 : 0 : return const0_rtx;
6409 : : break;
6410 : 1536226 : case LE:
6411 : 1536226 : if (val >= mmax)
6412 : 201 : return const_true_rtx;
6413 : 1536025 : if (val < mmin)
6414 : 0 : return const0_rtx;
6415 : : break;
6416 : :
6417 : 19561956 : case EQ:
6418 : : /* x == y is always false for y out of range. */
6419 : 19561956 : if (val < mmin || val > mmax)
6420 : 382 : return const0_rtx;
6421 : : break;
6422 : :
6423 : : /* x > y is always false for y >= mmax, always true for y < mmin. */
6424 : 1959825 : case GTU:
6425 : 1959825 : if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
6426 : 136472 : return const0_rtx;
6427 : 1823353 : if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
6428 : 0 : return const_true_rtx;
6429 : : break;
6430 : 1468974 : case GT:
6431 : 1468974 : if (val >= mmax)
6432 : 80 : return const0_rtx;
6433 : 1468894 : if (val < mmin)
6434 : 6 : return const_true_rtx;
6435 : : break;
6436 : :
6437 : : /* x < y is always false for y <= mmin, always true for y > mmax. */
6438 : 516495 : case LTU:
6439 : 516495 : if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
6440 : 2776 : return const0_rtx;
6441 : 513719 : if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
6442 : 55812 : return const_true_rtx;
6443 : : break;
6444 : 857794 : case LT:
6445 : 857794 : if (val <= mmin)
6446 : 2038 : return const0_rtx;
6447 : 855756 : if (val > mmax)
6448 : 2844 : return const_true_rtx;
6449 : : break;
6450 : :
6451 : 22674223 : case NE:
6452 : : /* x != y is always true for y out of range. */
6453 : 22674223 : if (val < mmin || val > mmax)
6454 : 141 : return const_true_rtx;
6455 : : break;
6456 : :
6457 : : default:
6458 : : break;
6459 : : }
6460 : : }
6461 : :
6462 : : /* Optimize integer comparisons with zero. */
6463 : 71724790 : if (is_a <scalar_int_mode> (mode, &int_mode)
6464 : 69544212 : && trueop1 == const0_rtx
6465 : 38174296 : && !side_effects_p (trueop0))
6466 : : {
6467 : : /* Some addresses are known to be nonzero. We don't know
6468 : : their sign, but equality comparisons are known. */
6469 : 38085148 : if (nonzero_address_p (trueop0))
6470 : : {
6471 : 464 : if (code == EQ || code == LEU)
6472 : 302 : return const0_rtx;
6473 : 162 : if (code == NE || code == GTU)
6474 : 162 : return const_true_rtx;
6475 : : }
6476 : :
6477 : : /* See if the first operand is an IOR with a constant. If so, we
6478 : : may be able to determine the result of this comparison. */
6479 : 38084684 : if (GET_CODE (op0) == IOR)
6480 : : {
6481 : 509215 : rtx inner_const = avoid_constant_pool_reference (XEXP (op0, 1));
6482 : 509215 : if (CONST_INT_P (inner_const) && inner_const != const0_rtx)
6483 : : {
6484 : 276 : int sign_bitnum = GET_MODE_PRECISION (int_mode) - 1;
6485 : 552 : int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
6486 : 276 : && (UINTVAL (inner_const)
6487 : 276 : & (HOST_WIDE_INT_1U
6488 : : << sign_bitnum)));
6489 : :
6490 : 276 : switch (code)
6491 : : {
6492 : : case EQ:
6493 : : case LEU:
6494 : : return const0_rtx;
6495 : 4 : case NE:
6496 : 4 : case GTU:
6497 : 4 : return const_true_rtx;
6498 : 68 : case LT:
6499 : 68 : case LE:
6500 : 68 : if (has_sign)
6501 : 0 : return const_true_rtx;
6502 : : break;
6503 : 200 : case GT:
6504 : 200 : case GE:
6505 : 200 : if (has_sign)
6506 : : return const0_rtx;
6507 : : break;
6508 : : default:
6509 : : break;
6510 : : }
6511 : : }
6512 : : }
6513 : : }
6514 : :
6515 : : /* Optimize comparison of ABS with zero. */
6516 : 38395589 : if (trueop1 == CONST0_RTX (mode) && !side_effects_p (trueop0)
6517 : 110030338 : && (GET_CODE (trueop0) == ABS
6518 : 38305755 : || (GET_CODE (trueop0) == FLOAT_EXTEND
6519 : 48 : && GET_CODE (XEXP (trueop0, 0)) == ABS)))
6520 : : {
6521 : 457 : switch (code)
6522 : : {
6523 : 8 : case LT:
6524 : : /* Optimize abs(x) < 0.0. */
6525 : 8 : if (!INTEGRAL_MODE_P (mode) && !HONOR_SNANS (mode))
6526 : 0 : return const0_rtx;
6527 : : break;
6528 : :
6529 : 42 : case GE:
6530 : : /* Optimize abs(x) >= 0.0. */
6531 : 42 : if (!INTEGRAL_MODE_P (mode) && !HONOR_NANS (mode))
6532 : 0 : return const_true_rtx;
6533 : : break;
6534 : :
6535 : 0 : case UNGE:
6536 : : /* Optimize ! (abs(x) < 0.0). */
6537 : 0 : return const_true_rtx;
6538 : :
6539 : : default:
6540 : : break;
6541 : : }
6542 : : }
6543 : :
6544 : : return 0;
6545 : : }
6546 : :
6547 : : /* Recognize expressions of the form (X CMP 0) ? VAL : OP (X)
6548 : : where OP is CLZ or CTZ and VAL is the value from CLZ_DEFINED_VALUE_AT_ZERO
6549 : : or CTZ_DEFINED_VALUE_AT_ZERO respectively and return OP (X) if the expression
6550 : : can be simplified to that or NULL_RTX if not.
6551 : : Assume X is compared against zero with CMP_CODE and the true
6552 : : arm is TRUE_VAL and the false arm is FALSE_VAL. */
6553 : :
6554 : : rtx
6555 : 24429568 : simplify_context::simplify_cond_clz_ctz (rtx x, rtx_code cmp_code,
6556 : : rtx true_val, rtx false_val)
6557 : : {
6558 : 24429568 : if (cmp_code != EQ && cmp_code != NE)
6559 : : return NULL_RTX;
6560 : :
6561 : : /* Result on X == 0 and X !=0 respectively. */
6562 : 17758001 : rtx on_zero, on_nonzero;
6563 : 17758001 : if (cmp_code == EQ)
6564 : : {
6565 : : on_zero = true_val;
6566 : : on_nonzero = false_val;
6567 : : }
6568 : : else
6569 : : {
6570 : 9373025 : on_zero = false_val;
6571 : 9373025 : on_nonzero = true_val;
6572 : : }
6573 : :
6574 : 17758001 : rtx_code op_code = GET_CODE (on_nonzero);
6575 : 17758001 : if ((op_code != CLZ && op_code != CTZ)
6576 : 1224 : || !rtx_equal_p (XEXP (on_nonzero, 0), x)
6577 : 17758648 : || !CONST_INT_P (on_zero))
6578 : 17757810 : return NULL_RTX;
6579 : :
6580 : 191 : HOST_WIDE_INT op_val;
6581 : 191 : scalar_int_mode mode ATTRIBUTE_UNUSED
6582 : 191 : = as_a <scalar_int_mode> (GET_MODE (XEXP (on_nonzero, 0)));
6583 : 0 : if (((op_code == CLZ && CLZ_DEFINED_VALUE_AT_ZERO (mode, op_val))
6584 : 382 : || (op_code == CTZ && CTZ_DEFINED_VALUE_AT_ZERO (mode, op_val)))
6585 : 191 : && op_val == INTVAL (on_zero))
6586 : : return on_nonzero;
6587 : :
6588 : : return NULL_RTX;
6589 : : }
6590 : :
6591 : : /* Try to simplify X given that it appears within operand OP of a
6592 : : VEC_MERGE operation whose mask is MASK. X need not use the same
6593 : : vector mode as the VEC_MERGE, but it must have the same number of
6594 : : elements.
6595 : :
6596 : : Return the simplified X on success, otherwise return NULL_RTX. */
6597 : :
6598 : : rtx
6599 : 1204412 : simplify_context::simplify_merge_mask (rtx x, rtx mask, int op)
6600 : : {
6601 : 1204412 : gcc_assert (VECTOR_MODE_P (GET_MODE (x)));
6602 : 2408824 : poly_uint64 nunits = GET_MODE_NUNITS (GET_MODE (x));
6603 : 1204412 : if (GET_CODE (x) == VEC_MERGE && rtx_equal_p (XEXP (x, 2), mask))
6604 : : {
6605 : 5034 : if (side_effects_p (XEXP (x, 1 - op)))
6606 : : return NULL_RTX;
6607 : :
6608 : 4786 : return XEXP (x, op);
6609 : : }
6610 : 1199378 : if (UNARY_P (x)
6611 : 169975 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
6612 : 1398584 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits))
6613 : : {
6614 : 24837 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
6615 : 24837 : if (top0)
6616 : 496 : return simplify_gen_unary (GET_CODE (x), GET_MODE (x), top0,
6617 : 496 : GET_MODE (XEXP (x, 0)));
6618 : : }
6619 : 1198882 : if (BINARY_P (x)
6620 : 148020 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
6621 : 295996 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
6622 : 122991 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
6623 : 1445837 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits))
6624 : : {
6625 : 98935 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
6626 : 98935 : rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
6627 : 98935 : if (top0 || top1)
6628 : : {
6629 : 556 : if (COMPARISON_P (x))
6630 : 0 : return simplify_gen_relational (GET_CODE (x), GET_MODE (x),
6631 : 0 : GET_MODE (XEXP (x, 0)) != VOIDmode
6632 : : ? GET_MODE (XEXP (x, 0))
6633 : 0 : : GET_MODE (XEXP (x, 1)),
6634 : : top0 ? top0 : XEXP (x, 0),
6635 : 0 : top1 ? top1 : XEXP (x, 1));
6636 : : else
6637 : 556 : return simplify_gen_binary (GET_CODE (x), GET_MODE (x),
6638 : : top0 ? top0 : XEXP (x, 0),
6639 : 556 : top1 ? top1 : XEXP (x, 1));
6640 : : }
6641 : : }
6642 : 1198326 : if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY
6643 : 18448 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
6644 : 36896 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
6645 : 18448 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
6646 : 36896 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits)
6647 : 18448 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 2)))
6648 : 1219016 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 2))), nunits))
6649 : : {
6650 : 2242 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
6651 : 2242 : rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
6652 : 2242 : rtx top2 = simplify_merge_mask (XEXP (x, 2), mask, op);
6653 : 2242 : if (top0 || top1 || top2)
6654 : 496 : return simplify_gen_ternary (GET_CODE (x), GET_MODE (x),
6655 : 496 : GET_MODE (XEXP (x, 0)),
6656 : : top0 ? top0 : XEXP (x, 0),
6657 : : top1 ? top1 : XEXP (x, 1),
6658 : 496 : top2 ? top2 : XEXP (x, 2));
6659 : : }
6660 : : return NULL_RTX;
6661 : : }
6662 : :
6663 : :
6664 : : /* Simplify CODE, an operation with result mode MODE and three operands,
6665 : : OP0, OP1, and OP2. OP0_MODE was the mode of OP0 before it became
6666 : : a constant. Return 0 if no simplifications is possible. */
6667 : :
6668 : : rtx
6669 : 31648719 : simplify_context::simplify_ternary_operation (rtx_code code, machine_mode mode,
6670 : : machine_mode op0_mode,
6671 : : rtx op0, rtx op1, rtx op2)
6672 : : {
6673 : 31648719 : bool any_change = false;
6674 : 31648719 : rtx tem, trueop2;
6675 : 31648719 : scalar_int_mode int_mode, int_op0_mode;
6676 : 31648719 : unsigned int n_elts;
6677 : :
6678 : 31648719 : switch (code)
6679 : : {
6680 : 228258 : case FMA:
6681 : : /* Simplify negations around the multiplication. */
6682 : : /* -a * -b + c => a * b + c. */
6683 : 228258 : if (GET_CODE (op0) == NEG)
6684 : : {
6685 : 51273 : tem = simplify_unary_operation (NEG, mode, op1, mode);
6686 : 51273 : if (tem)
6687 : 176 : op1 = tem, op0 = XEXP (op0, 0), any_change = true;
6688 : : }
6689 : 176985 : else if (GET_CODE (op1) == NEG)
6690 : : {
6691 : 661 : tem = simplify_unary_operation (NEG, mode, op0, mode);
6692 : 661 : if (tem)
6693 : 0 : op0 = tem, op1 = XEXP (op1, 0), any_change = true;
6694 : : }
6695 : :
6696 : : /* Canonicalize the two multiplication operands. */
6697 : : /* a * -b + c => -b * a + c. */
6698 : 228258 : if (swap_commutative_operands_p (op0, op1))
6699 : 18849 : std::swap (op0, op1), any_change = true;
6700 : :
6701 : 228258 : if (any_change)
6702 : 19014 : return gen_rtx_FMA (mode, op0, op1, op2);
6703 : : return NULL_RTX;
6704 : :
6705 : 481315 : case SIGN_EXTRACT:
6706 : 481315 : case ZERO_EXTRACT:
6707 : 481315 : if (CONST_INT_P (op0)
6708 : 8364 : && CONST_INT_P (op1)
6709 : 8364 : && CONST_INT_P (op2)
6710 : 21 : && is_a <scalar_int_mode> (mode, &int_mode)
6711 : 21 : && INTVAL (op1) + INTVAL (op2) <= GET_MODE_PRECISION (int_mode)
6712 : 481336 : && HWI_COMPUTABLE_MODE_P (int_mode))
6713 : : {
6714 : : /* Extracting a bit-field from a constant */
6715 : 21 : unsigned HOST_WIDE_INT val = UINTVAL (op0);
6716 : 21 : HOST_WIDE_INT op1val = INTVAL (op1);
6717 : 21 : HOST_WIDE_INT op2val = INTVAL (op2);
6718 : 21 : if (!BITS_BIG_ENDIAN)
6719 : 21 : val >>= op2val;
6720 : : else if (is_a <scalar_int_mode> (op0_mode, &int_op0_mode))
6721 : : val >>= GET_MODE_PRECISION (int_op0_mode) - op2val - op1val;
6722 : : else
6723 : : /* Not enough information to calculate the bit position. */
6724 : : break;
6725 : :
6726 : 21 : if (HOST_BITS_PER_WIDE_INT != op1val)
6727 : : {
6728 : : /* First zero-extend. */
6729 : 20 : val &= (HOST_WIDE_INT_1U << op1val) - 1;
6730 : : /* If desired, propagate sign bit. */
6731 : 20 : if (code == SIGN_EXTRACT
6732 : 5 : && (val & (HOST_WIDE_INT_1U << (op1val - 1)))
6733 : 5 : != 0)
6734 : 2 : val |= ~ ((HOST_WIDE_INT_1U << op1val) - 1);
6735 : : }
6736 : :
6737 : 21 : return gen_int_mode (val, int_mode);
6738 : : }
6739 : : break;
6740 : :
6741 : 30373759 : case IF_THEN_ELSE:
6742 : 30373759 : if (CONST_INT_P (op0))
6743 : 190427 : return op0 != const0_rtx ? op1 : op2;
6744 : :
6745 : : /* Convert c ? a : a into "a". */
6746 : 30183332 : if (rtx_equal_p (op1, op2) && ! side_effects_p (op0))
6747 : : return op1;
6748 : :
6749 : : /* Convert a != b ? a : b into "a". */
6750 : 30183292 : if (GET_CODE (op0) == NE
6751 : 11697439 : && ! side_effects_p (op0)
6752 : 11659587 : && ! HONOR_NANS (mode)
6753 : 11657826 : && ! HONOR_SIGNED_ZEROS (mode)
6754 : 41841118 : && ((rtx_equal_p (XEXP (op0, 0), op1)
6755 : 53931 : && rtx_equal_p (XEXP (op0, 1), op2))
6756 : 11657825 : || (rtx_equal_p (XEXP (op0, 0), op2)
6757 : 1687 : && rtx_equal_p (XEXP (op0, 1), op1))))
6758 : 1 : return op1;
6759 : :
6760 : : /* Convert a == b ? a : b into "b". */
6761 : 30183291 : if (GET_CODE (op0) == EQ
6762 : 9849471 : && ! side_effects_p (op0)
6763 : 9838850 : && ! HONOR_NANS (mode)
6764 : 9753361 : && ! HONOR_SIGNED_ZEROS (mode)
6765 : 39936652 : && ((rtx_equal_p (XEXP (op0, 0), op1)
6766 : 13970 : && rtx_equal_p (XEXP (op0, 1), op2))
6767 : 9753350 : || (rtx_equal_p (XEXP (op0, 0), op2)
6768 : 4081 : && rtx_equal_p (XEXP (op0, 1), op1))))
6769 : 21 : return op2;
6770 : :
6771 : : /* Convert (!c) != {0,...,0} ? a : b into
6772 : : c != {0,...,0} ? b : a for vector modes. */
6773 : 30183270 : if (VECTOR_MODE_P (GET_MODE (op1))
6774 : 11763 : && GET_CODE (op0) == NE
6775 : 529 : && GET_CODE (XEXP (op0, 0)) == NOT
6776 : 0 : && GET_CODE (XEXP (op0, 1)) == CONST_VECTOR)
6777 : : {
6778 : 0 : rtx cv = XEXP (op0, 1);
6779 : 0 : int nunits;
6780 : 0 : bool ok = true;
6781 : 0 : if (!CONST_VECTOR_NUNITS (cv).is_constant (&nunits))
6782 : : ok = false;
6783 : : else
6784 : 0 : for (int i = 0; i < nunits; ++i)
6785 : 0 : if (CONST_VECTOR_ELT (cv, i) != const0_rtx)
6786 : : {
6787 : : ok = false;
6788 : : break;
6789 : : }
6790 : 0 : if (ok)
6791 : : {
6792 : 0 : rtx new_op0 = gen_rtx_NE (GET_MODE (op0),
6793 : : XEXP (XEXP (op0, 0), 0),
6794 : : XEXP (op0, 1));
6795 : 0 : rtx retval = gen_rtx_IF_THEN_ELSE (mode, new_op0, op2, op1);
6796 : 0 : return retval;
6797 : : }
6798 : : }
6799 : :
6800 : : /* Convert x == 0 ? N : clz (x) into clz (x) when
6801 : : CLZ_DEFINED_VALUE_AT_ZERO is defined to N for the mode of x.
6802 : : Similarly for ctz (x). */
6803 : 30182163 : if (COMPARISON_P (op0) && !side_effects_p (op0)
6804 : 60280012 : && XEXP (op0, 1) == const0_rtx)
6805 : : {
6806 : 24429568 : rtx simplified
6807 : 24429568 : = simplify_cond_clz_ctz (XEXP (op0, 0), GET_CODE (op0),
6808 : : op1, op2);
6809 : 24429568 : if (simplified)
6810 : : return simplified;
6811 : : }
6812 : :
6813 : 30183270 : if (COMPARISON_P (op0) && ! side_effects_p (op0))
6814 : : {
6815 : 60193484 : machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
6816 : 30096742 : ? GET_MODE (XEXP (op0, 1))
6817 : : : GET_MODE (XEXP (op0, 0)));
6818 : 30096742 : rtx temp;
6819 : :
6820 : : /* Look for happy constants in op1 and op2. */
6821 : 30096742 : if (CONST_INT_P (op1) && CONST_INT_P (op2))
6822 : : {
6823 : 142116 : HOST_WIDE_INT t = INTVAL (op1);
6824 : 142116 : HOST_WIDE_INT f = INTVAL (op2);
6825 : :
6826 : 142116 : if (t == STORE_FLAG_VALUE && f == 0)
6827 : 30520 : code = GET_CODE (op0);
6828 : 111596 : else if (t == 0 && f == STORE_FLAG_VALUE)
6829 : : {
6830 : 29586 : enum rtx_code tmp;
6831 : 29586 : tmp = reversed_comparison_code (op0, NULL);
6832 : 29586 : if (tmp == UNKNOWN)
6833 : : break;
6834 : : code = tmp;
6835 : : }
6836 : : else
6837 : : break;
6838 : :
6839 : 54591 : return simplify_gen_relational (code, mode, cmp_mode,
6840 : 54591 : XEXP (op0, 0), XEXP (op0, 1));
6841 : : }
6842 : :
6843 : 29954626 : temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
6844 : : cmp_mode, XEXP (op0, 0),
6845 : : XEXP (op0, 1));
6846 : :
6847 : : /* See if any simplifications were possible. */
6848 : 29954626 : if (temp)
6849 : : {
6850 : 6830 : if (CONST_INT_P (temp))
6851 : 86 : return temp == const0_rtx ? op2 : op1;
6852 : 6784 : else if (temp)
6853 : 6784 : return gen_rtx_IF_THEN_ELSE (mode, temp, op1, op2);
6854 : : }
6855 : : }
6856 : : break;
6857 : :
6858 : 565387 : case VEC_MERGE:
6859 : 565387 : gcc_assert (GET_MODE (op0) == mode);
6860 : 565387 : gcc_assert (GET_MODE (op1) == mode);
6861 : 565387 : gcc_assert (VECTOR_MODE_P (mode));
6862 : 565387 : trueop2 = avoid_constant_pool_reference (op2);
6863 : 565387 : if (CONST_INT_P (trueop2)
6864 : 901872 : && GET_MODE_NUNITS (mode).is_constant (&n_elts))
6865 : : {
6866 : 336485 : unsigned HOST_WIDE_INT sel = UINTVAL (trueop2);
6867 : 336485 : unsigned HOST_WIDE_INT mask;
6868 : 336485 : if (n_elts == HOST_BITS_PER_WIDE_INT)
6869 : : mask = -1;
6870 : : else
6871 : 335365 : mask = (HOST_WIDE_INT_1U << n_elts) - 1;
6872 : :
6873 : 336485 : if (!(sel & mask) && !side_effects_p (op0))
6874 : 478 : return op1;
6875 : 336007 : if ((sel & mask) == mask && !side_effects_p (op1))
6876 : 9178 : return op0;
6877 : :
6878 : 326829 : rtx trueop0 = avoid_constant_pool_reference (op0);
6879 : 326829 : rtx trueop1 = avoid_constant_pool_reference (op1);
6880 : 326829 : if (GET_CODE (trueop0) == CONST_VECTOR
6881 : 9592 : && GET_CODE (trueop1) == CONST_VECTOR)
6882 : : {
6883 : 4982 : rtvec v = rtvec_alloc (n_elts);
6884 : 4982 : unsigned int i;
6885 : :
6886 : 53952 : for (i = 0; i < n_elts; i++)
6887 : 43988 : RTVEC_ELT (v, i) = ((sel & (HOST_WIDE_INT_1U << i))
6888 : 43988 : ? CONST_VECTOR_ELT (trueop0, i)
6889 : 24992 : : CONST_VECTOR_ELT (trueop1, i));
6890 : 4982 : return gen_rtx_CONST_VECTOR (mode, v);
6891 : : }
6892 : :
6893 : : /* Replace (vec_merge (vec_merge a b m) c n) with (vec_merge b c n)
6894 : : if no element from a appears in the result. */
6895 : 321847 : if (GET_CODE (op0) == VEC_MERGE)
6896 : : {
6897 : 15830 : tem = avoid_constant_pool_reference (XEXP (op0, 2));
6898 : 15830 : if (CONST_INT_P (tem))
6899 : : {
6900 : 1250 : unsigned HOST_WIDE_INT sel0 = UINTVAL (tem);
6901 : 1250 : if (!(sel & sel0 & mask) && !side_effects_p (XEXP (op0, 0)))
6902 : 91 : return simplify_gen_ternary (code, mode, mode,
6903 : 91 : XEXP (op0, 1), op1, op2);
6904 : 1159 : if (!(sel & ~sel0 & mask) && !side_effects_p (XEXP (op0, 1)))
6905 : 790 : return simplify_gen_ternary (code, mode, mode,
6906 : 790 : XEXP (op0, 0), op1, op2);
6907 : : }
6908 : : }
6909 : 320966 : if (GET_CODE (op1) == VEC_MERGE)
6910 : : {
6911 : 171 : tem = avoid_constant_pool_reference (XEXP (op1, 2));
6912 : 171 : if (CONST_INT_P (tem))
6913 : : {
6914 : 154 : unsigned HOST_WIDE_INT sel1 = UINTVAL (tem);
6915 : 154 : if (!(~sel & sel1 & mask) && !side_effects_p (XEXP (op1, 0)))
6916 : 94 : return simplify_gen_ternary (code, mode, mode,
6917 : 94 : op0, XEXP (op1, 1), op2);
6918 : 60 : if (!(~sel & ~sel1 & mask) && !side_effects_p (XEXP (op1, 1)))
6919 : 1 : return simplify_gen_ternary (code, mode, mode,
6920 : 1 : op0, XEXP (op1, 0), op2);
6921 : : }
6922 : : }
6923 : :
6924 : : /* Replace (vec_merge (vec_duplicate (vec_select a parallel (i))) a 1 << i)
6925 : : with a. */
6926 : 320871 : if (GET_CODE (op0) == VEC_DUPLICATE
6927 : 118051 : && GET_CODE (XEXP (op0, 0)) == VEC_SELECT
6928 : 452 : && GET_CODE (XEXP (XEXP (op0, 0), 1)) == PARALLEL
6929 : 439374 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (op0, 0))), 1))
6930 : : {
6931 : 386 : tem = XVECEXP ((XEXP (XEXP (op0, 0), 1)), 0, 0);
6932 : 386 : if (CONST_INT_P (tem) && CONST_INT_P (op2))
6933 : : {
6934 : 386 : if (XEXP (XEXP (op0, 0), 0) == op1
6935 : 1 : && UINTVAL (op2) == HOST_WIDE_INT_1U << UINTVAL (tem))
6936 : : return op1;
6937 : : }
6938 : : }
6939 : : /* Replace (vec_merge (vec_duplicate (X)) (const_vector [A, B])
6940 : : (const_int N))
6941 : : with (vec_concat (X) (B)) if N == 1 or
6942 : : (vec_concat (A) (X)) if N == 2. */
6943 : 320870 : if (GET_CODE (op0) == VEC_DUPLICATE
6944 : 118050 : && GET_CODE (op1) == CONST_VECTOR
6945 : 109696 : && known_eq (CONST_VECTOR_NUNITS (op1), 2)
6946 : 540 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6947 : 321140 : && IN_RANGE (sel, 1, 2))
6948 : : {
6949 : 268 : rtx newop0 = XEXP (op0, 0);
6950 : 268 : rtx newop1 = CONST_VECTOR_ELT (op1, 2 - sel);
6951 : 268 : if (sel == 2)
6952 : 32 : std::swap (newop0, newop1);
6953 : 268 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6954 : : }
6955 : : /* Replace (vec_merge (vec_duplicate x) (vec_concat (y) (z)) (const_int N))
6956 : : with (vec_concat x z) if N == 1, or (vec_concat y x) if N == 2.
6957 : : Only applies for vectors of two elements. */
6958 : 320602 : if (GET_CODE (op0) == VEC_DUPLICATE
6959 : 117782 : && GET_CODE (op1) == VEC_CONCAT
6960 : 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6961 : 320602 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6962 : 320602 : && IN_RANGE (sel, 1, 2))
6963 : : {
6964 : 0 : rtx newop0 = XEXP (op0, 0);
6965 : 0 : rtx newop1 = XEXP (op1, 2 - sel);
6966 : 0 : rtx otherop = XEXP (op1, sel - 1);
6967 : 0 : if (sel == 2)
6968 : 0 : std::swap (newop0, newop1);
6969 : : /* Don't want to throw away the other part of the vec_concat if
6970 : : it has side-effects. */
6971 : 0 : if (!side_effects_p (otherop))
6972 : 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6973 : : }
6974 : :
6975 : : /* Replace:
6976 : :
6977 : : (vec_merge:outer (vec_duplicate:outer x:inner)
6978 : : (subreg:outer y:inner 0)
6979 : : (const_int N))
6980 : :
6981 : : with (vec_concat:outer x:inner y:inner) if N == 1,
6982 : : or (vec_concat:outer y:inner x:inner) if N == 2.
6983 : :
6984 : : Implicitly, this means we have a paradoxical subreg, but such
6985 : : a check is cheap, so make it anyway.
6986 : :
6987 : : Only applies for vectors of two elements. */
6988 : 320602 : if (GET_CODE (op0) == VEC_DUPLICATE
6989 : 117782 : && GET_CODE (op1) == SUBREG
6990 : 45783 : && GET_MODE (op1) == GET_MODE (op0)
6991 : 45783 : && GET_MODE (SUBREG_REG (op1)) == GET_MODE (XEXP (op0, 0))
6992 : 0 : && paradoxical_subreg_p (op1)
6993 : 0 : && subreg_lowpart_p (op1)
6994 : 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6995 : 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6996 : 320602 : && IN_RANGE (sel, 1, 2))
6997 : : {
6998 : 0 : rtx newop0 = XEXP (op0, 0);
6999 : 0 : rtx newop1 = SUBREG_REG (op1);
7000 : 0 : if (sel == 2)
7001 : 0 : std::swap (newop0, newop1);
7002 : 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7003 : : }
7004 : :
7005 : : /* Same as above but with switched operands:
7006 : : Replace (vec_merge:outer (subreg:outer x:inner 0)
7007 : : (vec_duplicate:outer y:inner)
7008 : : (const_int N))
7009 : :
7010 : : with (vec_concat:outer x:inner y:inner) if N == 1,
7011 : : or (vec_concat:outer y:inner x:inner) if N == 2. */
7012 : 320602 : if (GET_CODE (op1) == VEC_DUPLICATE
7013 : 19981 : && GET_CODE (op0) == SUBREG
7014 : 16693 : && GET_MODE (op0) == GET_MODE (op1)
7015 : 16693 : && GET_MODE (SUBREG_REG (op0)) == GET_MODE (XEXP (op1, 0))
7016 : 0 : && paradoxical_subreg_p (op0)
7017 : 0 : && subreg_lowpart_p (op0)
7018 : 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
7019 : 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7020 : 320602 : && IN_RANGE (sel, 1, 2))
7021 : : {
7022 : 0 : rtx newop0 = SUBREG_REG (op0);
7023 : 0 : rtx newop1 = XEXP (op1, 0);
7024 : 0 : if (sel == 2)
7025 : 0 : std::swap (newop0, newop1);
7026 : 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7027 : : }
7028 : :
7029 : : /* Replace (vec_merge (vec_duplicate x) (vec_duplicate y)
7030 : : (const_int n))
7031 : : with (vec_concat x y) or (vec_concat y x) depending on value
7032 : : of N. */
7033 : 320602 : if (GET_CODE (op0) == VEC_DUPLICATE
7034 : 117782 : && GET_CODE (op1) == VEC_DUPLICATE
7035 : 186 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7036 : 320602 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
7037 : 320602 : && IN_RANGE (sel, 1, 2))
7038 : : {
7039 : 0 : rtx newop0 = XEXP (op0, 0);
7040 : 0 : rtx newop1 = XEXP (op1, 0);
7041 : 0 : if (sel == 2)
7042 : 0 : std::swap (newop0, newop1);
7043 : :
7044 : 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7045 : : }
7046 : : }
7047 : :
7048 : 549504 : if (rtx_equal_p (op0, op1)
7049 : 549504 : && !side_effects_p (op2) && !side_effects_p (op1))
7050 : : return op0;
7051 : :
7052 : 549492 : if (!side_effects_p (op2))
7053 : : {
7054 : 546875 : rtx top0
7055 : 546875 : = may_trap_p (op0) ? NULL_RTX : simplify_merge_mask (op0, op2, 0);
7056 : 546875 : rtx top1
7057 : 546875 : = may_trap_p (op1) ? NULL_RTX : simplify_merge_mask (op1, op2, 1);
7058 : 546875 : if (top0 || top1)
7059 : 396 : return simplify_gen_ternary (code, mode, mode,
7060 : : top0 ? top0 : op0,
7061 : 322 : top1 ? top1 : op1, op2);
7062 : : }
7063 : :
7064 : : break;
7065 : :
7066 : 0 : default:
7067 : 0 : gcc_unreachable ();
7068 : : }
7069 : :
7070 : : return 0;
7071 : : }
7072 : :
7073 : : /* Try to calculate NUM_BYTES bytes of the target memory image of X,
7074 : : starting at byte FIRST_BYTE. Return true on success and add the
7075 : : bytes to BYTES, such that each byte has BITS_PER_UNIT bits and such
7076 : : that the bytes follow target memory order. Leave BYTES unmodified
7077 : : on failure.
7078 : :
7079 : : MODE is the mode of X. The caller must reserve NUM_BYTES bytes in
7080 : : BYTES before calling this function. */
7081 : :
7082 : : bool
7083 : 11167420 : native_encode_rtx (machine_mode mode, rtx x, vec<target_unit> &bytes,
7084 : : unsigned int first_byte, unsigned int num_bytes)
7085 : : {
7086 : : /* Check the mode is sensible. */
7087 : 11167420 : gcc_assert (GET_MODE (x) == VOIDmode
7088 : : ? is_a <scalar_int_mode> (mode)
7089 : : : mode == GET_MODE (x));
7090 : :
7091 : 11167420 : if (GET_CODE (x) == CONST_VECTOR)
7092 : : {
7093 : : /* CONST_VECTOR_ELT follows target memory order, so no shuffling
7094 : : is necessary. The only complication is that MODE_VECTOR_BOOL
7095 : : vectors can have several elements per byte. */
7096 : 755078 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
7097 : : GET_MODE_NUNITS (mode));
7098 : 377539 : unsigned int elt = first_byte * BITS_PER_UNIT / elt_bits;
7099 : 377539 : if (elt_bits < BITS_PER_UNIT)
7100 : : {
7101 : : /* This is the only case in which elements can be smaller than
7102 : : a byte. */
7103 : 0 : gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
7104 : 0 : auto mask = GET_MODE_MASK (GET_MODE_INNER (mode));
7105 : 0 : for (unsigned int i = 0; i < num_bytes; ++i)
7106 : : {
7107 : 0 : target_unit value = 0;
7108 : 0 : for (unsigned int j = 0; j < BITS_PER_UNIT; j += elt_bits)
7109 : : {
7110 : 0 : value |= (INTVAL (CONST_VECTOR_ELT (x, elt)) & mask) << j;
7111 : 0 : elt += 1;
7112 : : }
7113 : 0 : bytes.quick_push (value);
7114 : : }
7115 : : return true;
7116 : : }
7117 : :
7118 : 377539 : unsigned int start = bytes.length ();
7119 : 377539 : unsigned int elt_bytes = GET_MODE_UNIT_SIZE (mode);
7120 : : /* Make FIRST_BYTE relative to ELT. */
7121 : 377539 : first_byte %= elt_bytes;
7122 : 1761886 : while (num_bytes > 0)
7123 : : {
7124 : : /* Work out how many bytes we want from element ELT. */
7125 : 1384347 : unsigned int chunk_bytes = MIN (num_bytes, elt_bytes - first_byte);
7126 : 2768694 : if (!native_encode_rtx (GET_MODE_INNER (mode),
7127 : : CONST_VECTOR_ELT (x, elt), bytes,
7128 : : first_byte, chunk_bytes))
7129 : : {
7130 : 0 : bytes.truncate (start);
7131 : 0 : return false;
7132 : : }
7133 : 1384347 : elt += 1;
7134 : 1384347 : first_byte = 0;
7135 : 1384347 : num_bytes -= chunk_bytes;
7136 : : }
7137 : : return true;
7138 : : }
7139 : :
7140 : : /* All subsequent cases are limited to scalars. */
7141 : 10789881 : scalar_mode smode;
7142 : 10819337 : if (!is_a <scalar_mode> (mode, &smode))
7143 : : return false;
7144 : :
7145 : : /* Make sure that the region is in range. */
7146 : 10789881 : unsigned int end_byte = first_byte + num_bytes;
7147 : 10789881 : unsigned int mode_bytes = GET_MODE_SIZE (smode);
7148 : 10789881 : gcc_assert (end_byte <= mode_bytes);
7149 : :
7150 : 10789881 : if (CONST_SCALAR_INT_P (x))
7151 : : {
7152 : : /* The target memory layout is affected by both BYTES_BIG_ENDIAN
7153 : : and WORDS_BIG_ENDIAN. Use the subreg machinery to get the lsb
7154 : : position of each byte. */
7155 : 10270318 : rtx_mode_t value (x, smode);
7156 : 10270318 : wide_int_ref value_wi (value);
7157 : 45924150 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
7158 : : {
7159 : : /* Always constant because the inputs are. */
7160 : 35653832 : unsigned int lsb
7161 : 35653832 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
7162 : : /* Operate directly on the encoding rather than using
7163 : : wi::extract_uhwi, so that we preserve the sign or zero
7164 : : extension for modes that are not a whole number of bits in
7165 : : size. (Zero extension is only used for the combination of
7166 : : innermode == BImode && STORE_FLAG_VALUE == 1). */
7167 : 35653832 : unsigned int elt = lsb / HOST_BITS_PER_WIDE_INT;
7168 : 35653832 : unsigned int shift = lsb % HOST_BITS_PER_WIDE_INT;
7169 : 35653832 : unsigned HOST_WIDE_INT uhwi = value_wi.elt (elt);
7170 : 35653832 : bytes.quick_push (uhwi >> shift);
7171 : : }
7172 : 10270318 : return true;
7173 : : }
7174 : :
7175 : 519563 : if (CONST_DOUBLE_P (x))
7176 : : {
7177 : : /* real_to_target produces an array of integers in target memory order.
7178 : : All integers before the last one have 32 bits; the last one may
7179 : : have 32 bits or fewer, depending on whether the mode bitsize
7180 : : is divisible by 32. Each of these integers is then laid out
7181 : : in target memory as any other integer would be. */
7182 : 490107 : long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
7183 : 490107 : real_to_target (el32, CONST_DOUBLE_REAL_VALUE (x), smode);
7184 : :
7185 : : /* The (maximum) number of target bytes per element of el32. */
7186 : 490107 : unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
7187 : 490107 : gcc_assert (bytes_per_el32 != 0);
7188 : :
7189 : : /* Build up the integers in a similar way to the CONST_SCALAR_INT_P
7190 : : handling above. */
7191 : 3383844 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
7192 : : {
7193 : 2893737 : unsigned int index = byte / bytes_per_el32;
7194 : 2893737 : unsigned int subbyte = byte % bytes_per_el32;
7195 : 2893737 : unsigned int int_bytes = MIN (bytes_per_el32,
7196 : : mode_bytes - index * bytes_per_el32);
7197 : : /* Always constant because the inputs are. */
7198 : 2893737 : unsigned int lsb
7199 : 2893737 : = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
7200 : 2893737 : bytes.quick_push ((unsigned long) el32[index] >> lsb);
7201 : : }
7202 : 490107 : return true;
7203 : : }
7204 : :
7205 : 29456 : if (GET_CODE (x) == CONST_FIXED)
7206 : : {
7207 : 0 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
7208 : : {
7209 : : /* Always constant because the inputs are. */
7210 : 0 : unsigned int lsb
7211 : 0 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
7212 : 0 : unsigned HOST_WIDE_INT piece = CONST_FIXED_VALUE_LOW (x);
7213 : 0 : if (lsb >= HOST_BITS_PER_WIDE_INT)
7214 : : {
7215 : 0 : lsb -= HOST_BITS_PER_WIDE_INT;
7216 : 0 : piece = CONST_FIXED_VALUE_HIGH (x);
7217 : : }
7218 : 0 : bytes.quick_push (piece >> lsb);
7219 : : }
7220 : : return true;
7221 : : }
7222 : :
7223 : : return false;
7224 : : }
7225 : :
7226 : : /* Read a vector of mode MODE from the target memory image given by BYTES,
7227 : : starting at byte FIRST_BYTE. The vector is known to be encodable using
7228 : : NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each,
7229 : : and BYTES is known to have enough bytes to supply NPATTERNS *
7230 : : NELTS_PER_PATTERN vector elements. Each element of BYTES contains
7231 : : BITS_PER_UNIT bits and the bytes are in target memory order.
7232 : :
7233 : : Return the vector on success, otherwise return NULL_RTX. */
7234 : :
7235 : : rtx
7236 : 102696 : native_decode_vector_rtx (machine_mode mode, const vec<target_unit> &bytes,
7237 : : unsigned int first_byte, unsigned int npatterns,
7238 : : unsigned int nelts_per_pattern)
7239 : : {
7240 : 102696 : rtx_vector_builder builder (mode, npatterns, nelts_per_pattern);
7241 : :
7242 : 205392 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
7243 : : GET_MODE_NUNITS (mode));
7244 : 102696 : if (elt_bits < BITS_PER_UNIT)
7245 : : {
7246 : : /* This is the only case in which elements can be smaller than a byte.
7247 : : Element 0 is always in the lsb of the containing byte. */
7248 : 0 : gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
7249 : 0 : for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
7250 : : {
7251 : 0 : unsigned int bit_index = first_byte * BITS_PER_UNIT + i * elt_bits;
7252 : 0 : unsigned int byte_index = bit_index / BITS_PER_UNIT;
7253 : 0 : unsigned int lsb = bit_index % BITS_PER_UNIT;
7254 : 0 : unsigned int value = bytes[byte_index] >> lsb;
7255 : 0 : builder.quick_push (gen_int_mode (value, GET_MODE_INNER (mode)));
7256 : : }
7257 : : }
7258 : : else
7259 : : {
7260 : 434310 : for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
7261 : : {
7262 : 663228 : rtx x = native_decode_rtx (GET_MODE_INNER (mode), bytes, first_byte);
7263 : 331614 : if (!x)
7264 : 0 : return NULL_RTX;
7265 : 331614 : builder.quick_push (x);
7266 : 331614 : first_byte += elt_bits / BITS_PER_UNIT;
7267 : : }
7268 : : }
7269 : 102696 : return builder.build ();
7270 : 102696 : }
7271 : :
7272 : : /* Read an rtx of mode MODE from the target memory image given by BYTES,
7273 : : starting at byte FIRST_BYTE. Each element of BYTES contains BITS_PER_UNIT
7274 : : bits and the bytes are in target memory order. The image has enough
7275 : : values to specify all bytes of MODE.
7276 : :
7277 : : Return the rtx on success, otherwise return NULL_RTX. */
7278 : :
7279 : : rtx
7280 : 9800104 : native_decode_rtx (machine_mode mode, const vec<target_unit> &bytes,
7281 : : unsigned int first_byte)
7282 : : {
7283 : 9800104 : if (VECTOR_MODE_P (mode))
7284 : : {
7285 : : /* If we know at compile time how many elements there are,
7286 : : pull each element directly from BYTES. */
7287 : 19399 : unsigned int nelts;
7288 : 38798 : if (GET_MODE_NUNITS (mode).is_constant (&nelts))
7289 : 19399 : return native_decode_vector_rtx (mode, bytes, first_byte, nelts, 1);
7290 : : return NULL_RTX;
7291 : : }
7292 : :
7293 : 9780705 : scalar_int_mode imode;
7294 : 9780705 : if (is_a <scalar_int_mode> (mode, &imode)
7295 : 9780705 : && GET_MODE_PRECISION (imode) <= MAX_BITSIZE_MODE_ANY_INT)
7296 : : {
7297 : : /* Pull the bytes msb first, so that we can use simple
7298 : : shift-and-insert wide_int operations. */
7299 : 9684375 : unsigned int size = GET_MODE_SIZE (imode);
7300 : 9684375 : wide_int result (wi::zero (GET_MODE_PRECISION (imode)));
7301 : 46020412 : for (unsigned int i = 0; i < size; ++i)
7302 : : {
7303 : 36336037 : unsigned int lsb = (size - i - 1) * BITS_PER_UNIT;
7304 : : /* Always constant because the inputs are. */
7305 : 36336037 : unsigned int subbyte
7306 : 36336037 : = subreg_size_offset_from_lsb (1, size, lsb).to_constant ();
7307 : 36336037 : result <<= BITS_PER_UNIT;
7308 : 36336037 : result |= bytes[first_byte + subbyte];
7309 : : }
7310 : 9684375 : return immed_wide_int_const (result, imode);
7311 : 9684375 : }
7312 : :
7313 : 96330 : scalar_float_mode fmode;
7314 : 96330 : if (is_a <scalar_float_mode> (mode, &fmode))
7315 : : {
7316 : : /* We need to build an array of integers in target memory order.
7317 : : All integers before the last one have 32 bits; the last one may
7318 : : have 32 bits or fewer, depending on whether the mode bitsize
7319 : : is divisible by 32. */
7320 : 96301 : long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
7321 : 96301 : unsigned int num_el32 = CEIL (GET_MODE_BITSIZE (fmode), 32);
7322 : 96301 : memset (el32, 0, num_el32 * sizeof (long));
7323 : :
7324 : : /* The (maximum) number of target bytes per element of el32. */
7325 : 96301 : unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
7326 : 96301 : gcc_assert (bytes_per_el32 != 0);
7327 : :
7328 : 96301 : unsigned int mode_bytes = GET_MODE_SIZE (fmode);
7329 : 709061 : for (unsigned int byte = 0; byte < mode_bytes; ++byte)
7330 : : {
7331 : 612760 : unsigned int index = byte / bytes_per_el32;
7332 : 612760 : unsigned int subbyte = byte % bytes_per_el32;
7333 : 612760 : unsigned int int_bytes = MIN (bytes_per_el32,
7334 : : mode_bytes - index * bytes_per_el32);
7335 : : /* Always constant because the inputs are. */
7336 : 612760 : unsigned int lsb
7337 : 612760 : = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
7338 : 612760 : el32[index] |= (unsigned long) bytes[first_byte + byte] << lsb;
7339 : : }
7340 : 96301 : REAL_VALUE_TYPE r;
7341 : 96301 : real_from_target (&r, el32, fmode);
7342 : 96301 : return const_double_from_real_value (r, fmode);
7343 : : }
7344 : :
7345 : 29 : if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
7346 : : {
7347 : 0 : scalar_mode smode = as_a <scalar_mode> (mode);
7348 : 0 : FIXED_VALUE_TYPE f;
7349 : 0 : f.data.low = 0;
7350 : 0 : f.data.high = 0;
7351 : 0 : f.mode = smode;
7352 : :
7353 : 0 : unsigned int mode_bytes = GET_MODE_SIZE (smode);
7354 : 0 : for (unsigned int byte = 0; byte < mode_bytes; ++byte)
7355 : : {
7356 : : /* Always constant because the inputs are. */
7357 : 0 : unsigned int lsb
7358 : 0 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
7359 : 0 : unsigned HOST_WIDE_INT unit = bytes[first_byte + byte];
7360 : 0 : if (lsb >= HOST_BITS_PER_WIDE_INT)
7361 : 0 : f.data.high |= unit << (lsb - HOST_BITS_PER_WIDE_INT);
7362 : : else
7363 : 0 : f.data.low |= unit << lsb;
7364 : : }
7365 : 0 : return CONST_FIXED_FROM_FIXED_VALUE (f, mode);
7366 : : }
7367 : :
7368 : : return NULL_RTX;
7369 : : }
7370 : :
7371 : : /* Simplify a byte offset BYTE into CONST_VECTOR X. The main purpose
7372 : : is to convert a runtime BYTE value into a constant one. */
7373 : :
7374 : : static poly_uint64
7375 : 181809 : simplify_const_vector_byte_offset (rtx x, poly_uint64 byte)
7376 : : {
7377 : : /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
7378 : 181809 : machine_mode mode = GET_MODE (x);
7379 : 363618 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
7380 : : GET_MODE_NUNITS (mode));
7381 : : /* The number of bits needed to encode one element from each pattern. */
7382 : 181809 : unsigned int sequence_bits = CONST_VECTOR_NPATTERNS (x) * elt_bits;
7383 : :
7384 : : /* Identify the start point in terms of a sequence number and a byte offset
7385 : : within that sequence. */
7386 : 181809 : poly_uint64 first_sequence;
7387 : 181809 : unsigned HOST_WIDE_INT subbit;
7388 : 181809 : if (can_div_trunc_p (byte * BITS_PER_UNIT, sequence_bits,
7389 : : &first_sequence, &subbit))
7390 : : {
7391 : 181809 : unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
7392 : 181809 : if (nelts_per_pattern == 1)
7393 : : /* This is a duplicated vector, so the value of FIRST_SEQUENCE
7394 : : doesn't matter. */
7395 : 139810 : byte = subbit / BITS_PER_UNIT;
7396 : 41999 : else if (nelts_per_pattern == 2 && known_gt (first_sequence, 0U))
7397 : : {
7398 : : /* The subreg drops the first element from each pattern and
7399 : : only uses the second element. Find the first sequence
7400 : : that starts on a byte boundary. */
7401 : 6997 : subbit += least_common_multiple (sequence_bits, BITS_PER_UNIT);
7402 : 6997 : byte = subbit / BITS_PER_UNIT;
7403 : : }
7404 : : }
7405 : 181809 : return byte;
7406 : : }
7407 : :
7408 : : /* Subroutine of simplify_subreg in which:
7409 : :
7410 : : - X is known to be a CONST_VECTOR
7411 : : - OUTERMODE is known to be a vector mode
7412 : :
7413 : : Try to handle the subreg by operating on the CONST_VECTOR encoding
7414 : : rather than on each individual element of the CONST_VECTOR.
7415 : :
7416 : : Return the simplified subreg on success, otherwise return NULL_RTX. */
7417 : :
7418 : : static rtx
7419 : 88269 : simplify_const_vector_subreg (machine_mode outermode, rtx x,
7420 : : machine_mode innermode, unsigned int first_byte)
7421 : : {
7422 : : /* Paradoxical subregs of vectors have dubious semantics. */
7423 : 88269 : if (paradoxical_subreg_p (outermode, innermode))
7424 : : return NULL_RTX;
7425 : :
7426 : : /* We can only preserve the semantics of a stepped pattern if the new
7427 : : vector element is the same as the original one. */
7428 : 88196 : if (CONST_VECTOR_STEPPED_P (x)
7429 : 104226 : && GET_MODE_INNER (outermode) != GET_MODE_INNER (innermode))
7430 : : return NULL_RTX;
7431 : :
7432 : : /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
7433 : 83297 : unsigned int x_elt_bits
7434 : 83297 : = vector_element_size (GET_MODE_PRECISION (innermode),
7435 : : GET_MODE_NUNITS (innermode));
7436 : 83297 : unsigned int out_elt_bits
7437 : 83297 : = vector_element_size (GET_MODE_PRECISION (outermode),
7438 : : GET_MODE_NUNITS (outermode));
7439 : :
7440 : : /* The number of bits needed to encode one element from every pattern
7441 : : of the original vector. */
7442 : 83297 : unsigned int x_sequence_bits = CONST_VECTOR_NPATTERNS (x) * x_elt_bits;
7443 : :
7444 : : /* The number of bits needed to encode one element from every pattern
7445 : : of the result. */
7446 : 83297 : unsigned int out_sequence_bits
7447 : 83297 : = least_common_multiple (x_sequence_bits, out_elt_bits);
7448 : :
7449 : : /* Work out the number of interleaved patterns in the output vector
7450 : : and the number of encoded elements per pattern. */
7451 : 83297 : unsigned int out_npatterns = out_sequence_bits / out_elt_bits;
7452 : 83297 : unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
7453 : :
7454 : : /* The encoding scheme requires the number of elements to be a multiple
7455 : : of the number of patterns, so that each pattern appears at least once
7456 : : and so that the same number of elements appear from each pattern. */
7457 : 83297 : bool ok_p = multiple_p (GET_MODE_NUNITS (outermode), out_npatterns);
7458 : 83297 : unsigned int const_nunits;
7459 : 173776 : if (GET_MODE_NUNITS (outermode).is_constant (&const_nunits)
7460 : 83297 : && (!ok_p || out_npatterns * nelts_per_pattern > const_nunits))
7461 : : {
7462 : : /* Either the encoding is invalid, or applying it would give us
7463 : : more elements than we need. Just encode each element directly. */
7464 : 7182 : out_npatterns = const_nunits;
7465 : 7182 : nelts_per_pattern = 1;
7466 : : }
7467 : 76115 : else if (!ok_p)
7468 : : return NULL_RTX;
7469 : :
7470 : : /* Get enough bytes of X to form the new encoding. */
7471 : 83297 : unsigned int buffer_bits = out_npatterns * nelts_per_pattern * out_elt_bits;
7472 : 83297 : unsigned int buffer_bytes = CEIL (buffer_bits, BITS_PER_UNIT);
7473 : 83297 : auto_vec<target_unit, 128> buffer (buffer_bytes);
7474 : 83297 : if (!native_encode_rtx (innermode, x, buffer, first_byte, buffer_bytes))
7475 : : return NULL_RTX;
7476 : :
7477 : : /* Reencode the bytes as OUTERMODE. */
7478 : 83297 : return native_decode_vector_rtx (outermode, buffer, 0, out_npatterns,
7479 : 83297 : nelts_per_pattern);
7480 : 83297 : }
7481 : :
7482 : : /* Try to simplify a subreg of a constant by encoding the subreg region
7483 : : as a sequence of target bytes and reading them back in the new mode.
7484 : : Return the new value on success, otherwise return null.
7485 : :
7486 : : The subreg has outer mode OUTERMODE, inner mode INNERMODE, inner value X
7487 : : and byte offset FIRST_BYTE. */
7488 : :
7489 : : static rtx
7490 : 9202570 : simplify_immed_subreg (fixed_size_mode outermode, rtx x,
7491 : : machine_mode innermode, unsigned int first_byte)
7492 : : {
7493 : 9202570 : unsigned int buffer_bytes = GET_MODE_SIZE (outermode);
7494 : 9202570 : auto_vec<target_unit, 128> buffer (buffer_bytes);
7495 : :
7496 : : /* Some ports misuse CCmode. */
7497 : 9202570 : if (GET_MODE_CLASS (outermode) == MODE_CC && CONST_INT_P (x))
7498 : : return x;
7499 : :
7500 : : /* Paradoxical subregs read undefined values for bytes outside of the
7501 : : inner value. However, we have traditionally always sign-extended
7502 : : integer constants and zero-extended others. */
7503 : 9202050 : unsigned int inner_bytes = buffer_bytes;
7504 : 9202050 : if (paradoxical_subreg_p (outermode, innermode))
7505 : : {
7506 : 714840 : if (!GET_MODE_SIZE (innermode).is_constant (&inner_bytes))
7507 : 0 : return NULL_RTX;
7508 : :
7509 : 357420 : target_unit filler = 0;
7510 : 357420 : if (CONST_SCALAR_INT_P (x) && wi::neg_p (rtx_mode_t (x, innermode)))
7511 : 32871 : filler = -1;
7512 : :
7513 : : /* Add any leading bytes due to big-endian layout. The number of
7514 : : bytes must be constant because both modes have constant size. */
7515 : 357420 : unsigned int leading_bytes
7516 : 357420 : = -byte_lowpart_offset (outermode, innermode).to_constant ();
7517 : 357420 : for (unsigned int i = 0; i < leading_bytes; ++i)
7518 : 0 : buffer.quick_push (filler);
7519 : :
7520 : 357420 : if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
7521 : 0 : return NULL_RTX;
7522 : :
7523 : : /* Add any trailing bytes due to little-endian layout. */
7524 : 4043570 : while (buffer.length () < buffer_bytes)
7525 : 1664365 : buffer.quick_push (filler);
7526 : : }
7527 : 8844630 : else if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
7528 : : return NULL_RTX;
7529 : 9202050 : rtx ret = native_decode_rtx (outermode, buffer, 0);
7530 : 9202050 : if (ret && FLOAT_MODE_P (outermode))
7531 : : {
7532 : 68588 : auto_vec<target_unit, 128> buffer2 (buffer_bytes);
7533 : 68588 : if (!native_encode_rtx (outermode, ret, buffer2, 0, buffer_bytes))
7534 : : return NULL_RTX;
7535 : 659069 : for (unsigned int i = 0; i < buffer_bytes; ++i)
7536 : 590520 : if (buffer[i] != buffer2[i])
7537 : : return NULL_RTX;
7538 : 68588 : }
7539 : : return ret;
7540 : 9202570 : }
7541 : :
7542 : : /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
7543 : : Return 0 if no simplifications are possible. */
7544 : : rtx
7545 : 61540719 : simplify_context::simplify_subreg (machine_mode outermode, rtx op,
7546 : : machine_mode innermode, poly_uint64 byte)
7547 : : {
7548 : : /* Little bit of sanity checking. */
7549 : 61540719 : gcc_assert (innermode != VOIDmode);
7550 : 61540719 : gcc_assert (outermode != VOIDmode);
7551 : 61540719 : gcc_assert (innermode != BLKmode);
7552 : 61540719 : gcc_assert (outermode != BLKmode);
7553 : :
7554 : 61540719 : gcc_assert (GET_MODE (op) == innermode
7555 : : || GET_MODE (op) == VOIDmode);
7556 : :
7557 : 123081438 : poly_uint64 outersize = GET_MODE_SIZE (outermode);
7558 : 61540719 : if (!multiple_p (byte, outersize))
7559 : : return NULL_RTX;
7560 : :
7561 : 123081434 : poly_uint64 innersize = GET_MODE_SIZE (innermode);
7562 : 61540717 : if (maybe_ge (byte, innersize))
7563 : : return NULL_RTX;
7564 : :
7565 : 61540717 : if (outermode == innermode && known_eq (byte, 0U))
7566 : 3936511 : return op;
7567 : :
7568 : 57604206 : if (GET_CODE (op) == CONST_VECTOR)
7569 : 181809 : byte = simplify_const_vector_byte_offset (op, byte);
7570 : :
7571 : 115208412 : if (multiple_p (byte, GET_MODE_UNIT_SIZE (innermode)))
7572 : : {
7573 : 52002305 : rtx elt;
7574 : :
7575 : 45614953 : if (VECTOR_MODE_P (outermode)
7576 : 12774704 : && GET_MODE_INNER (outermode) == GET_MODE_INNER (innermode)
7577 : 53527786 : && vec_duplicate_p (op, &elt))
7578 : 8223 : return gen_vec_duplicate (outermode, elt);
7579 : :
7580 : 52000359 : if (outermode == GET_MODE_INNER (innermode)
7581 : 52000359 : && vec_duplicate_p (op, &elt))
7582 : 6277 : return elt;
7583 : : }
7584 : :
7585 : 57595983 : if (CONST_SCALAR_INT_P (op)
7586 : 48513873 : || CONST_DOUBLE_AS_FLOAT_P (op)
7587 : 48488799 : || CONST_FIXED_P (op)
7588 : 48488799 : || GET_CODE (op) == CONST_VECTOR)
7589 : : {
7590 : 9285867 : unsigned HOST_WIDE_INT cbyte;
7591 : 9285867 : if (byte.is_constant (&cbyte))
7592 : : {
7593 : 9285867 : if (GET_CODE (op) == CONST_VECTOR && VECTOR_MODE_P (outermode))
7594 : : {
7595 : 88269 : rtx tmp = simplify_const_vector_subreg (outermode, op,
7596 : : innermode, cbyte);
7597 : 88269 : if (tmp)
7598 : 9285867 : return tmp;
7599 : : }
7600 : :
7601 : 9202570 : fixed_size_mode fs_outermode;
7602 : 9202570 : if (is_a <fixed_size_mode> (outermode, &fs_outermode))
7603 : 9202570 : return simplify_immed_subreg (fs_outermode, op, innermode, cbyte);
7604 : : }
7605 : : }
7606 : :
7607 : : /* Changing mode twice with SUBREG => just change it once,
7608 : : or not at all if changing back op starting mode. */
7609 : 48310116 : if (GET_CODE (op) == SUBREG)
7610 : : {
7611 : 1258939 : machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
7612 : 2517878 : poly_uint64 innermostsize = GET_MODE_SIZE (innermostmode);
7613 : 1258939 : rtx newx;
7614 : :
7615 : 1258939 : if (outermode == innermostmode
7616 : 631790 : && known_eq (byte, 0U)
7617 : 1890729 : && known_eq (SUBREG_BYTE (op), 0))
7618 : 631790 : return SUBREG_REG (op);
7619 : :
7620 : : /* Work out the memory offset of the final OUTERMODE value relative
7621 : : to the inner value of OP. */
7622 : 627149 : poly_int64 mem_offset = subreg_memory_offset (outermode,
7623 : : innermode, byte);
7624 : 627149 : poly_int64 op_mem_offset = subreg_memory_offset (op);
7625 : 627149 : poly_int64 final_offset = mem_offset + op_mem_offset;
7626 : :
7627 : : /* See whether resulting subreg will be paradoxical. */
7628 : 627149 : if (!paradoxical_subreg_p (outermode, innermostmode))
7629 : : {
7630 : : /* Bail out in case resulting subreg would be incorrect. */
7631 : 1024246 : if (maybe_lt (final_offset, 0)
7632 : 1024246 : || maybe_ge (poly_uint64 (final_offset), innermostsize)
7633 : 1024246 : || !multiple_p (final_offset, outersize))
7634 : 0 : return NULL_RTX;
7635 : : }
7636 : : else
7637 : : {
7638 : 115026 : poly_int64 required_offset = subreg_memory_offset (outermode,
7639 : 115026 : innermostmode, 0);
7640 : 115026 : if (maybe_ne (final_offset, required_offset))
7641 : 0 : return NULL_RTX;
7642 : : /* Paradoxical subregs always have byte offset 0. */
7643 : 115026 : final_offset = 0;
7644 : : }
7645 : :
7646 : : /* Recurse for further possible simplifications. */
7647 : 627149 : newx = simplify_subreg (outermode, SUBREG_REG (op), innermostmode,
7648 : : final_offset);
7649 : 627149 : if (newx)
7650 : : return newx;
7651 : 1254050 : if (validate_subreg (outermode, innermostmode,
7652 : 627025 : SUBREG_REG (op), final_offset))
7653 : : {
7654 : 580163 : newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
7655 : 580163 : if (SUBREG_PROMOTED_VAR_P (op)
7656 : 58 : && SUBREG_PROMOTED_SIGN (op) >= 0
7657 : 58 : && GET_MODE_CLASS (outermode) == MODE_INT
7658 : 5 : && known_ge (outersize, innersize)
7659 : 4 : && known_le (outersize, innermostsize)
7660 : 580167 : && subreg_lowpart_p (newx))
7661 : : {
7662 : 4 : SUBREG_PROMOTED_VAR_P (newx) = 1;
7663 : 4 : SUBREG_PROMOTED_SET (newx, SUBREG_PROMOTED_GET (op));
7664 : : }
7665 : 580163 : return newx;
7666 : : }
7667 : : return NULL_RTX;
7668 : : }
7669 : :
7670 : : /* SUBREG of a hard register => just change the register number
7671 : : and/or mode. If the hard register is not valid in that mode,
7672 : : suppress this simplification. If the hard register is the stack,
7673 : : frame, or argument pointer, leave this as a SUBREG. */
7674 : :
7675 : 47051177 : if (REG_P (op) && HARD_REGISTER_P (op))
7676 : : {
7677 : 10191415 : unsigned int regno, final_regno;
7678 : :
7679 : 10191415 : regno = REGNO (op);
7680 : 10191415 : final_regno = simplify_subreg_regno (regno, innermode, byte, outermode);
7681 : 10191415 : if (HARD_REGISTER_NUM_P (final_regno))
7682 : : {
7683 : 10177022 : rtx x = gen_rtx_REG_offset (op, outermode, final_regno,
7684 : : subreg_memory_offset (outermode,
7685 : : innermode, byte));
7686 : :
7687 : : /* Propagate original regno. We don't have any way to specify
7688 : : the offset inside original regno, so do so only for lowpart.
7689 : : The information is used only by alias analysis that cannot
7690 : : grog partial register anyway. */
7691 : :
7692 : 10177022 : if (known_eq (subreg_lowpart_offset (outermode, innermode), byte))
7693 : 7610470 : ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op);
7694 : 10177022 : return x;
7695 : : }
7696 : : }
7697 : :
7698 : : /* If we have a SUBREG of a register that we are replacing and we are
7699 : : replacing it with a MEM, make a new MEM and try replacing the
7700 : : SUBREG with it. Don't do this if the MEM has a mode-dependent address
7701 : : or if we would be widening it. */
7702 : :
7703 : 36874155 : if (MEM_P (op)
7704 : 1468545 : && ! mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op))
7705 : : /* Allow splitting of volatile memory references in case we don't
7706 : : have instruction to move the whole thing. */
7707 : 1468542 : && (! MEM_VOLATILE_P (op)
7708 : 43784 : || ! have_insn_for (SET, innermode))
7709 : : && !(STRICT_ALIGNMENT && MEM_ALIGN (op) < GET_MODE_ALIGNMENT (outermode))
7710 : 38298913 : && known_le (outersize, innersize))
7711 : 715237 : return adjust_address_nv (op, outermode, byte);
7712 : :
7713 : : /* Handle complex or vector values represented as CONCAT or VEC_CONCAT
7714 : : of two parts. */
7715 : 36158918 : if (GET_CODE (op) == CONCAT
7716 : 36158918 : || GET_CODE (op) == VEC_CONCAT)
7717 : : {
7718 : 221457 : poly_uint64 final_offset;
7719 : 221457 : rtx part, res;
7720 : :
7721 : 221457 : machine_mode part_mode = GET_MODE (XEXP (op, 0));
7722 : 221457 : if (part_mode == VOIDmode)
7723 : 159 : part_mode = GET_MODE_INNER (GET_MODE (op));
7724 : 442914 : poly_uint64 part_size = GET_MODE_SIZE (part_mode);
7725 : 221457 : if (known_lt (byte, part_size))
7726 : : {
7727 : 207732 : part = XEXP (op, 0);
7728 : 207732 : final_offset = byte;
7729 : : }
7730 : 13725 : else if (known_ge (byte, part_size))
7731 : : {
7732 : 13725 : part = XEXP (op, 1);
7733 : 13725 : final_offset = byte - part_size;
7734 : : }
7735 : : else
7736 : : return NULL_RTX;
7737 : :
7738 : 221457 : if (maybe_gt (final_offset + outersize, part_size))
7739 : : return NULL_RTX;
7740 : :
7741 : 32774 : part_mode = GET_MODE (part);
7742 : 32774 : if (part_mode == VOIDmode)
7743 : 0 : part_mode = GET_MODE_INNER (GET_MODE (op));
7744 : 32774 : res = simplify_subreg (outermode, part, part_mode, final_offset);
7745 : 32774 : if (res)
7746 : : return res;
7747 : 176 : if (validate_subreg (outermode, part_mode, part, final_offset))
7748 : 170 : return gen_rtx_SUBREG (outermode, part, final_offset);
7749 : : return NULL_RTX;
7750 : : }
7751 : :
7752 : : /* Simplify
7753 : : (subreg (vec_merge (X)
7754 : : (vector)
7755 : : (const_int ((1 << N) | M)))
7756 : : (N * sizeof (outermode)))
7757 : : to
7758 : : (subreg (X) (N * sizeof (outermode)))
7759 : : */
7760 : 35937461 : unsigned int idx;
7761 : 71874922 : if (constant_multiple_p (byte, GET_MODE_SIZE (outermode), &idx)
7762 : 35937461 : && idx < HOST_BITS_PER_WIDE_INT
7763 : 35937461 : && GET_CODE (op) == VEC_MERGE
7764 : 260906 : && GET_MODE_INNER (innermode) == outermode
7765 : 5077 : && CONST_INT_P (XEXP (op, 2))
7766 : 35942047 : && (UINTVAL (XEXP (op, 2)) & (HOST_WIDE_INT_1U << idx)) != 0)
7767 : 4580 : return simplify_gen_subreg (outermode, XEXP (op, 0), innermode, byte);
7768 : :
7769 : : /* A SUBREG resulting from a zero extension may fold to zero if
7770 : : it extracts higher bits that the ZERO_EXTEND's source bits. */
7771 : 35932881 : if (GET_CODE (op) == ZERO_EXTEND && SCALAR_INT_MODE_P (innermode))
7772 : : {
7773 : 233522 : poly_uint64 bitpos = subreg_lsb_1 (outermode, innermode, byte);
7774 : 233522 : if (known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (XEXP (op, 0)))))
7775 : 47469 : return CONST0_RTX (outermode);
7776 : : }
7777 : :
7778 : : /* Optimize SUBREGS of scalar integral ASHIFT by a valid constant. */
7779 : 35885412 : if (GET_CODE (op) == ASHIFT
7780 : 911530 : && SCALAR_INT_MODE_P (innermode)
7781 : 885276 : && CONST_INT_P (XEXP (op, 1))
7782 : 821710 : && INTVAL (XEXP (op, 1)) > 0
7783 : 37618651 : && known_gt (GET_MODE_BITSIZE (innermode), INTVAL (XEXP (op, 1))))
7784 : : {
7785 : 821708 : HOST_WIDE_INT val = INTVAL (XEXP (op, 1));
7786 : : /* A lowpart SUBREG of a ASHIFT by a constant may fold to zero. */
7787 : 821708 : if (known_eq (subreg_lowpart_offset (outermode, innermode), byte)
7788 : 1601794 : && known_le (GET_MODE_BITSIZE (outermode), val))
7789 : 216556 : return CONST0_RTX (outermode);
7790 : : /* Optimize the highpart SUBREG of a suitable ASHIFT (ZERO_EXTEND). */
7791 : 644992 : if (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
7792 : 40740 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == outermode
7793 : 40505 : && known_eq (GET_MODE_BITSIZE (outermode), val)
7794 : 79680 : && known_eq (GET_MODE_BITSIZE (innermode), 2 * val)
7795 : 685732 : && known_eq (subreg_highpart_offset (outermode, innermode), byte))
7796 : 39840 : return XEXP (XEXP (op, 0), 0);
7797 : : }
7798 : :
7799 : : /* Attempt to simplify WORD_MODE SUBREGs of bitwise expressions. */
7800 : 35668856 : if (outermode == word_mode
7801 : 12827858 : && (GET_CODE (op) == IOR || GET_CODE (op) == XOR || GET_CODE (op) == AND)
7802 : 36119774 : && SCALAR_INT_MODE_P (innermode))
7803 : : {
7804 : 450053 : rtx op0 = simplify_subreg (outermode, XEXP (op, 0), innermode, byte);
7805 : 450053 : rtx op1 = simplify_subreg (outermode, XEXP (op, 1), innermode, byte);
7806 : 450053 : if (op0 && op1)
7807 : 134734 : return simplify_gen_binary (GET_CODE (op), outermode, op0, op1);
7808 : : }
7809 : :
7810 : 35534122 : scalar_int_mode int_outermode, int_innermode;
7811 : 35534122 : if (is_a <scalar_int_mode> (outermode, &int_outermode)
7812 : 30707839 : && is_a <scalar_int_mode> (innermode, &int_innermode)
7813 : 66241961 : && known_eq (byte, subreg_lowpart_offset (int_outermode, int_innermode)))
7814 : : {
7815 : : /* Handle polynomial integers. The upper bits of a paradoxical
7816 : : subreg are undefined, so this is safe regardless of whether
7817 : : we're truncating or extending. */
7818 : 27642867 : if (CONST_POLY_INT_P (op))
7819 : : {
7820 : : poly_wide_int val
7821 : : = poly_wide_int::from (const_poly_int_value (op),
7822 : : GET_MODE_PRECISION (int_outermode),
7823 : : SIGNED);
7824 : : return immed_wide_int_const (val, int_outermode);
7825 : : }
7826 : :
7827 : 27642867 : if (GET_MODE_PRECISION (int_outermode)
7828 : 27642867 : < GET_MODE_PRECISION (int_innermode))
7829 : : {
7830 : 17176845 : rtx tem = simplify_truncation (int_outermode, op, int_innermode);
7831 : 17176845 : if (tem)
7832 : : return tem;
7833 : : }
7834 : : }
7835 : :
7836 : : /* If the outer mode is not integral, try taking a subreg with the equivalent
7837 : : integer outer mode and then bitcasting the result.
7838 : : Other simplifications rely on integer to integer subregs and we'd
7839 : : potentially miss out on optimizations otherwise. */
7840 : 69088684 : if (known_gt (GET_MODE_SIZE (innermode),
7841 : : GET_MODE_SIZE (outermode))
7842 : 19164989 : && SCALAR_INT_MODE_P (innermode)
7843 : 18331382 : && !SCALAR_INT_MODE_P (outermode)
7844 : 53772377 : && int_mode_for_size (GET_MODE_BITSIZE (outermode),
7845 : 63046 : 0).exists (&int_outermode))
7846 : : {
7847 : 63046 : rtx tem = simplify_subreg (int_outermode, op, innermode, byte);
7848 : 63046 : if (tem)
7849 : 486 : return lowpart_subreg (outermode, tem, int_outermode);
7850 : : }
7851 : :
7852 : : /* If OP is a vector comparison and the subreg is not changing the
7853 : : number of elements or the size of the elements, change the result
7854 : : of the comparison to the new mode. */
7855 : 34543856 : if (COMPARISON_P (op)
7856 : 180806 : && VECTOR_MODE_P (outermode)
7857 : 129706 : && VECTOR_MODE_P (innermode)
7858 : 259402 : && known_eq (GET_MODE_NUNITS (outermode), GET_MODE_NUNITS (innermode))
7859 : 34812536 : && known_eq (GET_MODE_UNIT_SIZE (outermode),
7860 : : GET_MODE_UNIT_SIZE (innermode)))
7861 : 87530 : return simplify_gen_relational (GET_CODE (op), outermode, innermode,
7862 : 87530 : XEXP (op, 0), XEXP (op, 1));
7863 : : return NULL_RTX;
7864 : : }
7865 : :
7866 : : /* Make a SUBREG operation or equivalent if it folds. */
7867 : :
7868 : : rtx
7869 : 39350370 : simplify_context::simplify_gen_subreg (machine_mode outermode, rtx op,
7870 : : machine_mode innermode,
7871 : : poly_uint64 byte)
7872 : : {
7873 : 39350370 : rtx newx;
7874 : :
7875 : 39350370 : newx = simplify_subreg (outermode, op, innermode, byte);
7876 : 39350370 : if (newx)
7877 : : return newx;
7878 : :
7879 : 18138326 : if (GET_CODE (op) == SUBREG
7880 : 18138326 : || GET_CODE (op) == CONCAT
7881 : 18112647 : || GET_MODE (op) == VOIDmode)
7882 : : return NULL_RTX;
7883 : :
7884 : 20109283 : if (MODE_COMPOSITE_P (outermode)
7885 : 0 : && (CONST_SCALAR_INT_P (op)
7886 : 0 : || CONST_DOUBLE_AS_FLOAT_P (op)
7887 : 0 : || CONST_FIXED_P (op)
7888 : 0 : || GET_CODE (op) == CONST_VECTOR))
7889 : 0 : return NULL_RTX;
7890 : :
7891 : 18112629 : if (validate_subreg (outermode, innermode, op, byte))
7892 : 18100026 : return gen_rtx_SUBREG (outermode, op, byte);
7893 : :
7894 : : return NULL_RTX;
7895 : : }
7896 : :
7897 : : /* Generates a subreg to get the least significant part of EXPR (in mode
7898 : : INNER_MODE) to OUTER_MODE. */
7899 : :
7900 : : rtx
7901 : 29128677 : simplify_context::lowpart_subreg (machine_mode outer_mode, rtx expr,
7902 : : machine_mode inner_mode)
7903 : : {
7904 : 29128677 : return simplify_gen_subreg (outer_mode, expr, inner_mode,
7905 : 29128677 : subreg_lowpart_offset (outer_mode, inner_mode));
7906 : : }
7907 : :
7908 : : /* Generate RTX to select element at INDEX out of vector OP. */
7909 : :
7910 : : rtx
7911 : 482225 : simplify_context::simplify_gen_vec_select (rtx op, unsigned int index)
7912 : : {
7913 : 482225 : gcc_assert (VECTOR_MODE_P (GET_MODE (op)));
7914 : :
7915 : 482225 : scalar_mode imode = GET_MODE_INNER (GET_MODE (op));
7916 : :
7917 : 964450 : if (known_eq (index * GET_MODE_SIZE (imode),
7918 : : subreg_lowpart_offset (imode, GET_MODE (op))))
7919 : : {
7920 : 482095 : rtx res = lowpart_subreg (imode, op, GET_MODE (op));
7921 : 482095 : if (res)
7922 : : return res;
7923 : : }
7924 : :
7925 : 130 : rtx tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, GEN_INT (index)));
7926 : 130 : return gen_rtx_VEC_SELECT (imode, op, tmp);
7927 : : }
7928 : :
7929 : :
7930 : : /* Simplify X, an rtx expression.
7931 : :
7932 : : Return the simplified expression or NULL if no simplifications
7933 : : were possible.
7934 : :
7935 : : This is the preferred entry point into the simplification routines;
7936 : : however, we still allow passes to call the more specific routines.
7937 : :
7938 : : Right now GCC has three (yes, three) major bodies of RTL simplification
7939 : : code that need to be unified.
7940 : :
7941 : : 1. fold_rtx in cse.cc. This code uses various CSE specific
7942 : : information to aid in RTL simplification.
7943 : :
7944 : : 2. simplify_rtx in combine.cc. Similar to fold_rtx, except that
7945 : : it uses combine specific information to aid in RTL
7946 : : simplification.
7947 : :
7948 : : 3. The routines in this file.
7949 : :
7950 : :
7951 : : Long term we want to only have one body of simplification code; to
7952 : : get to that state I recommend the following steps:
7953 : :
7954 : : 1. Pour over fold_rtx & simplify_rtx and move any simplifications
7955 : : which are not pass dependent state into these routines.
7956 : :
7957 : : 2. As code is moved by #1, change fold_rtx & simplify_rtx to
7958 : : use this routine whenever possible.
7959 : :
7960 : : 3. Allow for pass dependent state to be provided to these
7961 : : routines and add simplifications based on the pass dependent
7962 : : state. Remove code from cse.cc & combine.cc that becomes
7963 : : redundant/dead.
7964 : :
7965 : : It will take time, but ultimately the compiler will be easier to
7966 : : maintain and improve. It's totally silly that when we add a
7967 : : simplification that it needs to be added to 4 places (3 for RTL
7968 : : simplification and 1 for tree simplification. */
7969 : :
7970 : : rtx
7971 : 40029830 : simplify_rtx (const_rtx x)
7972 : : {
7973 : 40029830 : const enum rtx_code code = GET_CODE (x);
7974 : 40029830 : const machine_mode mode = GET_MODE (x);
7975 : :
7976 : 40029830 : switch (GET_RTX_CLASS (code))
7977 : : {
7978 : 707371 : case RTX_UNARY:
7979 : 1414742 : return simplify_unary_operation (code, mode,
7980 : 707371 : XEXP (x, 0), GET_MODE (XEXP (x, 0)));
7981 : 22020030 : case RTX_COMM_ARITH:
7982 : 22020030 : if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
7983 : 400415 : return simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
7984 : :
7985 : : /* Fall through. */
7986 : :
7987 : 26759931 : case RTX_BIN_ARITH:
7988 : 26759931 : return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
7989 : :
7990 : 56504 : case RTX_TERNARY:
7991 : 56504 : case RTX_BITFIELD_OPS:
7992 : 56504 : return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
7993 : 56504 : XEXP (x, 0), XEXP (x, 1),
7994 : 56504 : XEXP (x, 2));
7995 : :
7996 : 163416 : case RTX_COMPARE:
7997 : 163416 : case RTX_COMM_COMPARE:
7998 : 163416 : return simplify_relational_operation (code, mode,
7999 : 163416 : ((GET_MODE (XEXP (x, 0))
8000 : : != VOIDmode)
8001 : : ? GET_MODE (XEXP (x, 0))
8002 : 393 : : GET_MODE (XEXP (x, 1))),
8003 : 163416 : XEXP (x, 0),
8004 : 326832 : XEXP (x, 1));
8005 : :
8006 : 217977 : case RTX_EXTRA:
8007 : 217977 : if (code == SUBREG)
8008 : 1760 : return simplify_subreg (mode, SUBREG_REG (x),
8009 : 1760 : GET_MODE (SUBREG_REG (x)),
8010 : 1760 : SUBREG_BYTE (x));
8011 : : break;
8012 : :
8013 : 5538163 : case RTX_OBJ:
8014 : 5538163 : if (code == LO_SUM)
8015 : : {
8016 : : /* Convert (lo_sum (high FOO) FOO) to FOO. */
8017 : 0 : if (GET_CODE (XEXP (x, 0)) == HIGH
8018 : 0 : && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
8019 : 0 : return XEXP (x, 1);
8020 : : }
8021 : : break;
8022 : :
8023 : : default:
8024 : : break;
8025 : : }
8026 : : return NULL;
8027 : : }
8028 : :
8029 : : #if CHECKING_P
8030 : :
8031 : : namespace selftest {
8032 : :
8033 : : /* Make a unique pseudo REG of mode MODE for use by selftests. */
8034 : :
8035 : : static rtx
8036 : 2632 : make_test_reg (machine_mode mode)
8037 : : {
8038 : 2632 : static int test_reg_num = LAST_VIRTUAL_REGISTER + 1;
8039 : :
8040 : 2632 : return gen_rtx_REG (mode, test_reg_num++);
8041 : : }
8042 : :
8043 : : static void
8044 : 40 : test_scalar_int_ops (machine_mode mode)
8045 : : {
8046 : 40 : rtx op0 = make_test_reg (mode);
8047 : 40 : rtx op1 = make_test_reg (mode);
8048 : 40 : rtx six = GEN_INT (6);
8049 : :
8050 : 40 : rtx neg_op0 = simplify_gen_unary (NEG, mode, op0, mode);
8051 : 40 : rtx not_op0 = simplify_gen_unary (NOT, mode, op0, mode);
8052 : 40 : rtx bswap_op0 = simplify_gen_unary (BSWAP, mode, op0, mode);
8053 : :
8054 : 40 : rtx and_op0_op1 = simplify_gen_binary (AND, mode, op0, op1);
8055 : 40 : rtx ior_op0_op1 = simplify_gen_binary (IOR, mode, op0, op1);
8056 : 40 : rtx xor_op0_op1 = simplify_gen_binary (XOR, mode, op0, op1);
8057 : :
8058 : 40 : rtx and_op0_6 = simplify_gen_binary (AND, mode, op0, six);
8059 : 40 : rtx and_op1_6 = simplify_gen_binary (AND, mode, op1, six);
8060 : :
8061 : : /* Test some binary identities. */
8062 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, op0, const0_rtx));
8063 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, const0_rtx, op0));
8064 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MINUS, mode, op0, const0_rtx));
8065 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, op0, const1_rtx));
8066 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, const1_rtx, op0));
8067 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (DIV, mode, op0, const1_rtx));
8068 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, constm1_rtx));
8069 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, constm1_rtx, op0));
8070 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, const0_rtx));
8071 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, const0_rtx, op0));
8072 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, op0, const0_rtx));
8073 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, const0_rtx, op0));
8074 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFT, mode, op0, const0_rtx));
8075 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATE, mode, op0, const0_rtx));
8076 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFTRT, mode, op0, const0_rtx));
8077 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (LSHIFTRT, mode, op0, const0_rtx));
8078 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATERT, mode, op0, const0_rtx));
8079 : :
8080 : : /* Test some self-inverse operations. */
8081 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (NEG, mode, neg_op0, mode));
8082 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (NOT, mode, not_op0, mode));
8083 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (BSWAP, mode, bswap_op0, mode));
8084 : :
8085 : : /* Test some reflexive operations. */
8086 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, op0));
8087 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, op0));
8088 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (SMIN, mode, op0, op0));
8089 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (SMAX, mode, op0, op0));
8090 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (UMIN, mode, op0, op0));
8091 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (UMAX, mode, op0, op0));
8092 : :
8093 : 40 : ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (MINUS, mode, op0, op0));
8094 : 40 : ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (XOR, mode, op0, op0));
8095 : :
8096 : : /* Test simplify_distributive_operation. */
8097 : 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, xor_op0_op1, six),
8098 : : simplify_gen_binary (XOR, mode, and_op0_6, and_op1_6));
8099 : 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, ior_op0_op1, six),
8100 : : simplify_gen_binary (IOR, mode, and_op0_6, and_op1_6));
8101 : 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, and_op0_op1, six),
8102 : : simplify_gen_binary (AND, mode, and_op0_6, and_op1_6));
8103 : :
8104 : : /* Test useless extensions are eliminated. */
8105 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (TRUNCATE, mode, op0, mode));
8106 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (ZERO_EXTEND, mode, op0, mode));
8107 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (SIGN_EXTEND, mode, op0, mode));
8108 : 40 : ASSERT_RTX_EQ (op0, lowpart_subreg (mode, op0, mode));
8109 : 40 : }
8110 : :
8111 : : /* Verify some simplifications of integer extension/truncation.
8112 : : Machine mode BMODE is the guaranteed wider than SMODE. */
8113 : :
8114 : : static void
8115 : 24 : test_scalar_int_ext_ops (machine_mode bmode, machine_mode smode)
8116 : : {
8117 : 24 : rtx sreg = make_test_reg (smode);
8118 : :
8119 : : /* Check truncation of extension. */
8120 : 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
8121 : : simplify_gen_unary (ZERO_EXTEND, bmode,
8122 : : sreg, smode),
8123 : : bmode),
8124 : : sreg);
8125 : 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
8126 : : simplify_gen_unary (SIGN_EXTEND, bmode,
8127 : : sreg, smode),
8128 : : bmode),
8129 : : sreg);
8130 : 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
8131 : : lowpart_subreg (bmode, sreg, smode),
8132 : : bmode),
8133 : : sreg);
8134 : 24 : }
8135 : :
8136 : : /* Verify more simplifications of integer extension/truncation.
8137 : : BMODE is wider than MMODE which is wider than SMODE. */
8138 : :
8139 : : static void
8140 : 16 : test_scalar_int_ext_ops2 (machine_mode bmode, machine_mode mmode,
8141 : : machine_mode smode)
8142 : : {
8143 : 16 : rtx breg = make_test_reg (bmode);
8144 : 16 : rtx mreg = make_test_reg (mmode);
8145 : 16 : rtx sreg = make_test_reg (smode);
8146 : :
8147 : : /* Check truncate of truncate. */
8148 : 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
8149 : : simplify_gen_unary (TRUNCATE, mmode,
8150 : : breg, bmode),
8151 : : mmode),
8152 : : simplify_gen_unary (TRUNCATE, smode, breg, bmode));
8153 : :
8154 : : /* Check extension of extension. */
8155 : 16 : ASSERT_RTX_EQ (simplify_gen_unary (ZERO_EXTEND, bmode,
8156 : : simplify_gen_unary (ZERO_EXTEND, mmode,
8157 : : sreg, smode),
8158 : : mmode),
8159 : : simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
8160 : 16 : ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
8161 : : simplify_gen_unary (SIGN_EXTEND, mmode,
8162 : : sreg, smode),
8163 : : mmode),
8164 : : simplify_gen_unary (SIGN_EXTEND, bmode, sreg, smode));
8165 : 16 : ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
8166 : : simplify_gen_unary (ZERO_EXTEND, mmode,
8167 : : sreg, smode),
8168 : : mmode),
8169 : : simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
8170 : :
8171 : : /* Check truncation of extension. */
8172 : 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
8173 : : simplify_gen_unary (ZERO_EXTEND, bmode,
8174 : : mreg, mmode),
8175 : : bmode),
8176 : : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
8177 : 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
8178 : : simplify_gen_unary (SIGN_EXTEND, bmode,
8179 : : mreg, mmode),
8180 : : bmode),
8181 : : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
8182 : 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
8183 : : lowpart_subreg (bmode, mreg, mmode),
8184 : : bmode),
8185 : : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
8186 : 16 : }
8187 : :
8188 : :
8189 : : /* Verify some simplifications involving scalar expressions. */
8190 : :
8191 : : static void
8192 : 4 : test_scalar_ops ()
8193 : : {
8194 : 524 : for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
8195 : : {
8196 : 520 : machine_mode mode = (machine_mode) i;
8197 : 520 : if (SCALAR_INT_MODE_P (mode) && mode != BImode)
8198 : 40 : test_scalar_int_ops (mode);
8199 : : }
8200 : :
8201 : 4 : test_scalar_int_ext_ops (HImode, QImode);
8202 : 4 : test_scalar_int_ext_ops (SImode, QImode);
8203 : 4 : test_scalar_int_ext_ops (SImode, HImode);
8204 : 4 : test_scalar_int_ext_ops (DImode, QImode);
8205 : 4 : test_scalar_int_ext_ops (DImode, HImode);
8206 : 4 : test_scalar_int_ext_ops (DImode, SImode);
8207 : :
8208 : 4 : test_scalar_int_ext_ops2 (SImode, HImode, QImode);
8209 : 4 : test_scalar_int_ext_ops2 (DImode, HImode, QImode);
8210 : 4 : test_scalar_int_ext_ops2 (DImode, SImode, QImode);
8211 : 4 : test_scalar_int_ext_ops2 (DImode, SImode, HImode);
8212 : 4 : }
8213 : :
8214 : : /* Test vector simplifications involving VEC_DUPLICATE in which the
8215 : : operands and result have vector mode MODE. SCALAR_REG is a pseudo
8216 : : register that holds one element of MODE. */
8217 : :
8218 : : static void
8219 : 248 : test_vector_ops_duplicate (machine_mode mode, rtx scalar_reg)
8220 : : {
8221 : 248 : scalar_mode inner_mode = GET_MODE_INNER (mode);
8222 : 248 : rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
8223 : 496 : poly_uint64 nunits = GET_MODE_NUNITS (mode);
8224 : 248 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
8225 : : {
8226 : : /* Test some simple unary cases with VEC_DUPLICATE arguments. */
8227 : 128 : rtx not_scalar_reg = gen_rtx_NOT (inner_mode, scalar_reg);
8228 : 128 : rtx duplicate_not = gen_rtx_VEC_DUPLICATE (mode, not_scalar_reg);
8229 : 128 : ASSERT_RTX_EQ (duplicate,
8230 : : simplify_unary_operation (NOT, mode,
8231 : : duplicate_not, mode));
8232 : :
8233 : 128 : rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
8234 : 128 : rtx duplicate_neg = gen_rtx_VEC_DUPLICATE (mode, neg_scalar_reg);
8235 : 128 : ASSERT_RTX_EQ (duplicate,
8236 : : simplify_unary_operation (NEG, mode,
8237 : : duplicate_neg, mode));
8238 : :
8239 : : /* Test some simple binary cases with VEC_DUPLICATE arguments. */
8240 : 128 : ASSERT_RTX_EQ (duplicate,
8241 : : simplify_binary_operation (PLUS, mode, duplicate,
8242 : : CONST0_RTX (mode)));
8243 : :
8244 : 128 : ASSERT_RTX_EQ (duplicate,
8245 : : simplify_binary_operation (MINUS, mode, duplicate,
8246 : : CONST0_RTX (mode)));
8247 : :
8248 : 128 : ASSERT_RTX_PTR_EQ (CONST0_RTX (mode),
8249 : : simplify_binary_operation (MINUS, mode, duplicate,
8250 : : duplicate));
8251 : : }
8252 : :
8253 : : /* Test a scalar VEC_SELECT of a VEC_DUPLICATE. */
8254 : 248 : rtx zero_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const0_rtx));
8255 : 248 : ASSERT_RTX_PTR_EQ (scalar_reg,
8256 : : simplify_binary_operation (VEC_SELECT, inner_mode,
8257 : : duplicate, zero_par));
8258 : :
8259 : 248 : unsigned HOST_WIDE_INT const_nunits;
8260 : 248 : if (nunits.is_constant (&const_nunits))
8261 : : {
8262 : : /* And again with the final element. */
8263 : 248 : rtx last_index = gen_int_mode (const_nunits - 1, word_mode);
8264 : 248 : rtx last_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, last_index));
8265 : 248 : ASSERT_RTX_PTR_EQ (scalar_reg,
8266 : : simplify_binary_operation (VEC_SELECT, inner_mode,
8267 : : duplicate, last_par));
8268 : :
8269 : : /* Test a scalar subreg of a VEC_MERGE of a VEC_DUPLICATE. */
8270 : : /* Skip this test for vectors of booleans, because offset is in bytes,
8271 : : while vec_merge indices are in elements (usually bits). */
8272 : 248 : if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
8273 : : {
8274 : 248 : rtx vector_reg = make_test_reg (mode);
8275 : 4748 : for (unsigned HOST_WIDE_INT i = 0; i < const_nunits; i++)
8276 : : {
8277 : 4512 : if (i >= HOST_BITS_PER_WIDE_INT)
8278 : : break;
8279 : 4500 : rtx mask = GEN_INT ((HOST_WIDE_INT_1U << i) | (i + 1));
8280 : 4500 : rtx vm = gen_rtx_VEC_MERGE (mode, duplicate, vector_reg, mask);
8281 : 9000 : poly_uint64 offset = i * GET_MODE_SIZE (inner_mode);
8282 : :
8283 : 4500 : ASSERT_RTX_EQ (scalar_reg,
8284 : : simplify_gen_subreg (inner_mode, vm,
8285 : : mode, offset));
8286 : : }
8287 : : }
8288 : : }
8289 : :
8290 : : /* Test a scalar subreg of a VEC_DUPLICATE. */
8291 : 248 : poly_uint64 offset = subreg_lowpart_offset (inner_mode, mode);
8292 : 248 : ASSERT_RTX_EQ (scalar_reg,
8293 : : simplify_gen_subreg (inner_mode, duplicate,
8294 : : mode, offset));
8295 : :
8296 : 248 : machine_mode narrower_mode;
8297 : 248 : if (maybe_ne (nunits, 2U)
8298 : 208 : && multiple_p (nunits, 2)
8299 : 444 : && mode_for_vector (inner_mode, 2).exists (&narrower_mode)
8300 : 444 : && VECTOR_MODE_P (narrower_mode))
8301 : : {
8302 : : /* Test VEC_DUPLICATE of a vector. */
8303 : 196 : rtx_vector_builder nbuilder (narrower_mode, 2, 1);
8304 : 196 : nbuilder.quick_push (const0_rtx);
8305 : 196 : nbuilder.quick_push (const1_rtx);
8306 : 196 : rtx_vector_builder builder (mode, 2, 1);
8307 : 196 : builder.quick_push (const0_rtx);
8308 : 196 : builder.quick_push (const1_rtx);
8309 : 196 : ASSERT_RTX_EQ (builder.build (),
8310 : : simplify_unary_operation (VEC_DUPLICATE, mode,
8311 : : nbuilder.build (),
8312 : : narrower_mode));
8313 : :
8314 : : /* Test VEC_SELECT of a vector. */
8315 : 196 : rtx vec_par
8316 : 196 : = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, const1_rtx, const0_rtx));
8317 : 196 : rtx narrower_duplicate
8318 : 196 : = gen_rtx_VEC_DUPLICATE (narrower_mode, scalar_reg);
8319 : 196 : ASSERT_RTX_EQ (narrower_duplicate,
8320 : : simplify_binary_operation (VEC_SELECT, narrower_mode,
8321 : : duplicate, vec_par));
8322 : :
8323 : : /* Test a vector subreg of a VEC_DUPLICATE. */
8324 : 196 : poly_uint64 offset = subreg_lowpart_offset (narrower_mode, mode);
8325 : 196 : ASSERT_RTX_EQ (narrower_duplicate,
8326 : : simplify_gen_subreg (narrower_mode, duplicate,
8327 : : mode, offset));
8328 : 196 : }
8329 : 248 : }
8330 : :
8331 : : /* Test vector simplifications involving VEC_SERIES in which the
8332 : : operands and result have vector mode MODE. SCALAR_REG is a pseudo
8333 : : register that holds one element of MODE. */
8334 : :
8335 : : static void
8336 : 96 : test_vector_ops_series (machine_mode mode, rtx scalar_reg)
8337 : : {
8338 : : /* Test unary cases with VEC_SERIES arguments. */
8339 : 96 : scalar_mode inner_mode = GET_MODE_INNER (mode);
8340 : 96 : rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
8341 : 96 : rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
8342 : 96 : rtx series_0_r = gen_rtx_VEC_SERIES (mode, const0_rtx, scalar_reg);
8343 : 96 : rtx series_0_nr = gen_rtx_VEC_SERIES (mode, const0_rtx, neg_scalar_reg);
8344 : 96 : rtx series_nr_1 = gen_rtx_VEC_SERIES (mode, neg_scalar_reg, const1_rtx);
8345 : 96 : rtx series_r_m1 = gen_rtx_VEC_SERIES (mode, scalar_reg, constm1_rtx);
8346 : 96 : rtx series_r_r = gen_rtx_VEC_SERIES (mode, scalar_reg, scalar_reg);
8347 : 96 : rtx series_nr_nr = gen_rtx_VEC_SERIES (mode, neg_scalar_reg,
8348 : : neg_scalar_reg);
8349 : 96 : ASSERT_RTX_EQ (series_0_r,
8350 : : simplify_unary_operation (NEG, mode, series_0_nr, mode));
8351 : 96 : ASSERT_RTX_EQ (series_r_m1,
8352 : : simplify_unary_operation (NEG, mode, series_nr_1, mode));
8353 : 96 : ASSERT_RTX_EQ (series_r_r,
8354 : : simplify_unary_operation (NEG, mode, series_nr_nr, mode));
8355 : :
8356 : : /* Test that a VEC_SERIES with a zero step is simplified away. */
8357 : 96 : ASSERT_RTX_EQ (duplicate,
8358 : : simplify_binary_operation (VEC_SERIES, mode,
8359 : : scalar_reg, const0_rtx));
8360 : :
8361 : : /* Test PLUS and MINUS with VEC_SERIES. */
8362 : 96 : rtx series_0_1 = gen_const_vec_series (mode, const0_rtx, const1_rtx);
8363 : 96 : rtx series_0_m1 = gen_const_vec_series (mode, const0_rtx, constm1_rtx);
8364 : 96 : rtx series_r_1 = gen_rtx_VEC_SERIES (mode, scalar_reg, const1_rtx);
8365 : 96 : ASSERT_RTX_EQ (series_r_r,
8366 : : simplify_binary_operation (PLUS, mode, series_0_r,
8367 : : duplicate));
8368 : 96 : ASSERT_RTX_EQ (series_r_1,
8369 : : simplify_binary_operation (PLUS, mode, duplicate,
8370 : : series_0_1));
8371 : 96 : ASSERT_RTX_EQ (series_r_m1,
8372 : : simplify_binary_operation (PLUS, mode, duplicate,
8373 : : series_0_m1));
8374 : 96 : ASSERT_RTX_EQ (series_0_r,
8375 : : simplify_binary_operation (MINUS, mode, series_r_r,
8376 : : duplicate));
8377 : 96 : ASSERT_RTX_EQ (series_r_m1,
8378 : : simplify_binary_operation (MINUS, mode, duplicate,
8379 : : series_0_1));
8380 : 96 : ASSERT_RTX_EQ (series_r_1,
8381 : : simplify_binary_operation (MINUS, mode, duplicate,
8382 : : series_0_m1));
8383 : 96 : ASSERT_RTX_EQ (series_0_m1,
8384 : : simplify_binary_operation (VEC_SERIES, mode, const0_rtx,
8385 : : constm1_rtx));
8386 : :
8387 : : /* Test NEG on constant vector series. */
8388 : 96 : ASSERT_RTX_EQ (series_0_m1,
8389 : : simplify_unary_operation (NEG, mode, series_0_1, mode));
8390 : 96 : ASSERT_RTX_EQ (series_0_1,
8391 : : simplify_unary_operation (NEG, mode, series_0_m1, mode));
8392 : :
8393 : : /* Test PLUS and MINUS on constant vector series. */
8394 : 96 : rtx scalar2 = gen_int_mode (2, inner_mode);
8395 : 96 : rtx scalar3 = gen_int_mode (3, inner_mode);
8396 : 96 : rtx series_1_1 = gen_const_vec_series (mode, const1_rtx, const1_rtx);
8397 : 96 : rtx series_0_2 = gen_const_vec_series (mode, const0_rtx, scalar2);
8398 : 96 : rtx series_1_3 = gen_const_vec_series (mode, const1_rtx, scalar3);
8399 : 96 : ASSERT_RTX_EQ (series_1_1,
8400 : : simplify_binary_operation (PLUS, mode, series_0_1,
8401 : : CONST1_RTX (mode)));
8402 : 96 : ASSERT_RTX_EQ (series_0_m1,
8403 : : simplify_binary_operation (PLUS, mode, CONST0_RTX (mode),
8404 : : series_0_m1));
8405 : 96 : ASSERT_RTX_EQ (series_1_3,
8406 : : simplify_binary_operation (PLUS, mode, series_1_1,
8407 : : series_0_2));
8408 : 96 : ASSERT_RTX_EQ (series_0_1,
8409 : : simplify_binary_operation (MINUS, mode, series_1_1,
8410 : : CONST1_RTX (mode)));
8411 : 96 : ASSERT_RTX_EQ (series_1_1,
8412 : : simplify_binary_operation (MINUS, mode, CONST1_RTX (mode),
8413 : : series_0_m1));
8414 : 96 : ASSERT_RTX_EQ (series_1_1,
8415 : : simplify_binary_operation (MINUS, mode, series_1_3,
8416 : : series_0_2));
8417 : :
8418 : : /* Test MULT between constant vectors. */
8419 : 96 : rtx vec2 = gen_const_vec_duplicate (mode, scalar2);
8420 : 96 : rtx vec3 = gen_const_vec_duplicate (mode, scalar3);
8421 : 96 : rtx scalar9 = gen_int_mode (9, inner_mode);
8422 : 96 : rtx series_3_9 = gen_const_vec_series (mode, scalar3, scalar9);
8423 : 96 : ASSERT_RTX_EQ (series_0_2,
8424 : : simplify_binary_operation (MULT, mode, series_0_1, vec2));
8425 : 96 : ASSERT_RTX_EQ (series_3_9,
8426 : : simplify_binary_operation (MULT, mode, vec3, series_1_3));
8427 : 96 : if (!GET_MODE_NUNITS (mode).is_constant ())
8428 : : ASSERT_FALSE (simplify_binary_operation (MULT, mode, series_0_1,
8429 : : series_0_1));
8430 : :
8431 : : /* Test ASHIFT between constant vectors. */
8432 : 96 : ASSERT_RTX_EQ (series_0_2,
8433 : : simplify_binary_operation (ASHIFT, mode, series_0_1,
8434 : : CONST1_RTX (mode)));
8435 : 96 : if (!GET_MODE_NUNITS (mode).is_constant ())
8436 : : ASSERT_FALSE (simplify_binary_operation (ASHIFT, mode, CONST1_RTX (mode),
8437 : : series_0_1));
8438 : 96 : }
8439 : :
8440 : : static rtx
8441 : 3472 : simplify_merge_mask (rtx x, rtx mask, int op)
8442 : : {
8443 : 0 : return simplify_context ().simplify_merge_mask (x, mask, op);
8444 : : }
8445 : :
8446 : : /* Verify simplify_merge_mask works correctly. */
8447 : :
8448 : : static void
8449 : 248 : test_vec_merge (machine_mode mode)
8450 : : {
8451 : 248 : rtx op0 = make_test_reg (mode);
8452 : 248 : rtx op1 = make_test_reg (mode);
8453 : 248 : rtx op2 = make_test_reg (mode);
8454 : 248 : rtx op3 = make_test_reg (mode);
8455 : 248 : rtx op4 = make_test_reg (mode);
8456 : 248 : rtx op5 = make_test_reg (mode);
8457 : 248 : rtx mask1 = make_test_reg (SImode);
8458 : 248 : rtx mask2 = make_test_reg (SImode);
8459 : 248 : rtx vm1 = gen_rtx_VEC_MERGE (mode, op0, op1, mask1);
8460 : 248 : rtx vm2 = gen_rtx_VEC_MERGE (mode, op2, op3, mask1);
8461 : 248 : rtx vm3 = gen_rtx_VEC_MERGE (mode, op4, op5, mask1);
8462 : :
8463 : : /* Simple vec_merge. */
8464 : 248 : ASSERT_EQ (op0, simplify_merge_mask (vm1, mask1, 0));
8465 : 248 : ASSERT_EQ (op1, simplify_merge_mask (vm1, mask1, 1));
8466 : 248 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 0));
8467 : 248 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 1));
8468 : :
8469 : : /* Nested vec_merge.
8470 : : It's tempting to make this simplify right down to opN, but we don't
8471 : : because all the simplify_* functions assume that the operands have
8472 : : already been simplified. */
8473 : 248 : rtx nvm = gen_rtx_VEC_MERGE (mode, vm1, vm2, mask1);
8474 : 248 : ASSERT_EQ (vm1, simplify_merge_mask (nvm, mask1, 0));
8475 : 248 : ASSERT_EQ (vm2, simplify_merge_mask (nvm, mask1, 1));
8476 : :
8477 : : /* Intermediate unary op. */
8478 : 248 : rtx unop = gen_rtx_NOT (mode, vm1);
8479 : 248 : ASSERT_RTX_EQ (gen_rtx_NOT (mode, op0),
8480 : : simplify_merge_mask (unop, mask1, 0));
8481 : 248 : ASSERT_RTX_EQ (gen_rtx_NOT (mode, op1),
8482 : : simplify_merge_mask (unop, mask1, 1));
8483 : :
8484 : : /* Intermediate binary op. */
8485 : 248 : rtx binop = gen_rtx_PLUS (mode, vm1, vm2);
8486 : 248 : ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op0, op2),
8487 : : simplify_merge_mask (binop, mask1, 0));
8488 : 248 : ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op1, op3),
8489 : : simplify_merge_mask (binop, mask1, 1));
8490 : :
8491 : : /* Intermediate ternary op. */
8492 : 248 : rtx tenop = gen_rtx_FMA (mode, vm1, vm2, vm3);
8493 : 248 : ASSERT_RTX_EQ (gen_rtx_FMA (mode, op0, op2, op4),
8494 : : simplify_merge_mask (tenop, mask1, 0));
8495 : 248 : ASSERT_RTX_EQ (gen_rtx_FMA (mode, op1, op3, op5),
8496 : : simplify_merge_mask (tenop, mask1, 1));
8497 : :
8498 : : /* Side effects. */
8499 : 248 : rtx badop0 = gen_rtx_PRE_INC (mode, op0);
8500 : 248 : rtx badvm = gen_rtx_VEC_MERGE (mode, badop0, op1, mask1);
8501 : 248 : ASSERT_EQ (badop0, simplify_merge_mask (badvm, mask1, 0));
8502 : 248 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (badvm, mask1, 1));
8503 : :
8504 : : /* Called indirectly. */
8505 : 248 : ASSERT_RTX_EQ (gen_rtx_VEC_MERGE (mode, op0, op3, mask1),
8506 : : simplify_rtx (nvm));
8507 : 248 : }
8508 : :
8509 : : /* Test subregs of integer vector constant X, trying elements in
8510 : : the range [ELT_BIAS, ELT_BIAS + constant_lower_bound (NELTS)),
8511 : : where NELTS is the number of elements in X. Subregs involving
8512 : : elements [ELT_BIAS, ELT_BIAS + FIRST_VALID) are expected to fail. */
8513 : :
8514 : : static void
8515 : 288 : test_vector_subregs_modes (rtx x, poly_uint64 elt_bias = 0,
8516 : : unsigned int first_valid = 0)
8517 : : {
8518 : 288 : machine_mode inner_mode = GET_MODE (x);
8519 : 288 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
8520 : :
8521 : 37728 : for (unsigned int modei = 0; modei < NUM_MACHINE_MODES; ++modei)
8522 : : {
8523 : 37440 : machine_mode outer_mode = (machine_mode) modei;
8524 : 37440 : if (!VECTOR_MODE_P (outer_mode))
8525 : 19584 : continue;
8526 : :
8527 : 17856 : unsigned int outer_nunits;
8528 : 35712 : if (GET_MODE_INNER (outer_mode) == int_mode
8529 : 2064 : && GET_MODE_NUNITS (outer_mode).is_constant (&outer_nunits)
8530 : 21984 : && multiple_p (GET_MODE_NUNITS (inner_mode), outer_nunits))
8531 : : {
8532 : : /* Test subregs in which the outer mode is a smaller,
8533 : : constant-sized vector of the same element type. */
8534 : 1176 : unsigned int limit
8535 : 1176 : = constant_lower_bound (GET_MODE_NUNITS (inner_mode));
8536 : 9636 : for (unsigned int elt = 0; elt < limit; elt += outer_nunits)
8537 : : {
8538 : 8460 : rtx expected = NULL_RTX;
8539 : 8460 : if (elt >= first_valid)
8540 : : {
8541 : 8460 : rtx_vector_builder builder (outer_mode, outer_nunits, 1);
8542 : 46668 : for (unsigned int i = 0; i < outer_nunits; ++i)
8543 : 38208 : builder.quick_push (CONST_VECTOR_ELT (x, elt + i));
8544 : 8460 : expected = builder.build ();
8545 : 8460 : }
8546 : 8460 : poly_uint64 byte = (elt_bias + elt) * GET_MODE_SIZE (int_mode);
8547 : 8460 : ASSERT_RTX_EQ (expected,
8548 : : simplify_subreg (outer_mode, x,
8549 : : inner_mode, byte));
8550 : : }
8551 : : }
8552 : 33360 : else if (known_eq (GET_MODE_SIZE (outer_mode),
8553 : : GET_MODE_SIZE (inner_mode))
8554 : 2100 : && known_eq (elt_bias, 0U)
8555 : 2100 : && (GET_MODE_CLASS (outer_mode) != MODE_VECTOR_BOOL
8556 : 0 : || known_eq (GET_MODE_BITSIZE (outer_mode),
8557 : : GET_MODE_NUNITS (outer_mode)))
8558 : 2100 : && (!FLOAT_MODE_P (outer_mode)
8559 : 3492 : || (FLOAT_MODE_FORMAT (outer_mode)->ieee_bits
8560 : 1164 : == GET_MODE_UNIT_PRECISION (outer_mode)))
8561 : 18780 : && (GET_MODE_SIZE (inner_mode).is_constant ()
8562 : 0 : || !CONST_VECTOR_STEPPED_P (x)))
8563 : : {
8564 : : /* Try converting to OUTER_MODE and back. */
8565 : 1848 : rtx outer_x = simplify_subreg (outer_mode, x, inner_mode, 0);
8566 : 1848 : ASSERT_TRUE (outer_x != NULL_RTX);
8567 : 1848 : ASSERT_RTX_EQ (x, simplify_subreg (inner_mode, outer_x,
8568 : : outer_mode, 0));
8569 : : }
8570 : : }
8571 : :
8572 : 288 : if (BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
8573 : : {
8574 : : /* Test each byte in the element range. */
8575 : 288 : unsigned int limit
8576 : 288 : = constant_lower_bound (GET_MODE_SIZE (inner_mode));
8577 : 17688 : for (unsigned int i = 0; i < limit; ++i)
8578 : : {
8579 : 17400 : unsigned int elt = i / GET_MODE_SIZE (int_mode);
8580 : 17400 : rtx expected = NULL_RTX;
8581 : 17400 : if (elt >= first_valid)
8582 : : {
8583 : 17400 : unsigned int byte_shift = i % GET_MODE_SIZE (int_mode);
8584 : 17400 : if (BYTES_BIG_ENDIAN)
8585 : : byte_shift = GET_MODE_SIZE (int_mode) - byte_shift - 1;
8586 : 17400 : rtx_mode_t vec_elt (CONST_VECTOR_ELT (x, elt), int_mode);
8587 : 17400 : wide_int shifted_elt
8588 : 17400 : = wi::lrshift (vec_elt, byte_shift * BITS_PER_UNIT);
8589 : 17400 : expected = immed_wide_int_const (shifted_elt, QImode);
8590 : 17400 : }
8591 : 17400 : poly_uint64 byte = elt_bias * GET_MODE_SIZE (int_mode) + i;
8592 : 17400 : ASSERT_RTX_EQ (expected,
8593 : : simplify_subreg (QImode, x, inner_mode, byte));
8594 : : }
8595 : : }
8596 : 288 : }
8597 : :
8598 : : /* Test constant subregs of integer vector mode INNER_MODE, using 1
8599 : : element per pattern. */
8600 : :
8601 : : static void
8602 : 96 : test_vector_subregs_repeating (machine_mode inner_mode)
8603 : : {
8604 : 192 : poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
8605 : 96 : unsigned int min_nunits = constant_lower_bound (nunits);
8606 : 96 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
8607 : 96 : unsigned int count = gcd (min_nunits, 8);
8608 : :
8609 : 96 : rtx_vector_builder builder (inner_mode, count, 1);
8610 : 720 : for (unsigned int i = 0; i < count; ++i)
8611 : 624 : builder.quick_push (gen_int_mode (8 - i, int_mode));
8612 : 96 : rtx x = builder.build ();
8613 : :
8614 : 96 : test_vector_subregs_modes (x);
8615 : 96 : if (!nunits.is_constant ())
8616 : : test_vector_subregs_modes (x, nunits - min_nunits);
8617 : 96 : }
8618 : :
8619 : : /* Test constant subregs of integer vector mode INNER_MODE, using 2
8620 : : elements per pattern. */
8621 : :
8622 : : static void
8623 : 96 : test_vector_subregs_fore_back (machine_mode inner_mode)
8624 : : {
8625 : 192 : poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
8626 : 96 : unsigned int min_nunits = constant_lower_bound (nunits);
8627 : 96 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
8628 : 96 : unsigned int count = gcd (min_nunits, 4);
8629 : :
8630 : 96 : rtx_vector_builder builder (inner_mode, count, 2);
8631 : 464 : for (unsigned int i = 0; i < count; ++i)
8632 : 368 : builder.quick_push (gen_int_mode (i, int_mode));
8633 : 464 : for (unsigned int i = 0; i < count; ++i)
8634 : 368 : builder.quick_push (gen_int_mode (-1 - (int) i, int_mode));
8635 : 96 : rtx x = builder.build ();
8636 : :
8637 : 96 : test_vector_subregs_modes (x);
8638 : 96 : if (!nunits.is_constant ())
8639 : : test_vector_subregs_modes (x, nunits - min_nunits, count);
8640 : 96 : }
8641 : :
8642 : : /* Test constant subregs of integer vector mode INNER_MODE, using 3
8643 : : elements per pattern. */
8644 : :
8645 : : static void
8646 : 96 : test_vector_subregs_stepped (machine_mode inner_mode)
8647 : : {
8648 : : /* Build { 0, 1, 2, 3, ... }. */
8649 : 96 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
8650 : 96 : rtx_vector_builder builder (inner_mode, 1, 3);
8651 : 384 : for (unsigned int i = 0; i < 3; ++i)
8652 : 288 : builder.quick_push (gen_int_mode (i, int_mode));
8653 : 96 : rtx x = builder.build ();
8654 : :
8655 : 96 : test_vector_subregs_modes (x);
8656 : 96 : }
8657 : :
8658 : : /* Test constant subregs of integer vector mode INNER_MODE. */
8659 : :
8660 : : static void
8661 : 96 : test_vector_subregs (machine_mode inner_mode)
8662 : : {
8663 : 96 : test_vector_subregs_repeating (inner_mode);
8664 : 96 : test_vector_subregs_fore_back (inner_mode);
8665 : 96 : test_vector_subregs_stepped (inner_mode);
8666 : 96 : }
8667 : :
8668 : : /* Verify some simplifications involving vectors. */
8669 : :
8670 : : static void
8671 : 4 : test_vector_ops ()
8672 : : {
8673 : 524 : for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
8674 : : {
8675 : 520 : machine_mode mode = (machine_mode) i;
8676 : 520 : if (VECTOR_MODE_P (mode))
8677 : : {
8678 : 496 : rtx scalar_reg = make_test_reg (GET_MODE_INNER (mode));
8679 : 248 : test_vector_ops_duplicate (mode, scalar_reg);
8680 : 248 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
8681 : 376 : && maybe_gt (GET_MODE_NUNITS (mode), 2))
8682 : : {
8683 : 96 : test_vector_ops_series (mode, scalar_reg);
8684 : 96 : test_vector_subregs (mode);
8685 : : }
8686 : 248 : test_vec_merge (mode);
8687 : : }
8688 : : }
8689 : 4 : }
8690 : :
8691 : : template<unsigned int N>
8692 : : struct simplify_const_poly_int_tests
8693 : : {
8694 : : static void run ();
8695 : : };
8696 : :
8697 : : template<>
8698 : : struct simplify_const_poly_int_tests<1>
8699 : : {
8700 : : static void run () {}
8701 : : };
8702 : :
8703 : : /* Test various CONST_POLY_INT properties. */
8704 : :
8705 : : template<unsigned int N>
8706 : : void
8707 : : simplify_const_poly_int_tests<N>::run ()
8708 : : {
8709 : : using poly_int64 = poly_int<N, HOST_WIDE_INT>;
8710 : : rtx x1 = gen_int_mode (poly_int64 (1, 1), QImode);
8711 : : rtx x2 = gen_int_mode (poly_int64 (-80, 127), QImode);
8712 : : rtx x3 = gen_int_mode (poly_int64 (-79, -128), QImode);
8713 : : rtx x4 = gen_int_mode (poly_int64 (5, 4), QImode);
8714 : : rtx x5 = gen_int_mode (poly_int64 (30, 24), QImode);
8715 : : rtx x6 = gen_int_mode (poly_int64 (20, 16), QImode);
8716 : : rtx x7 = gen_int_mode (poly_int64 (7, 4), QImode);
8717 : : rtx x8 = gen_int_mode (poly_int64 (30, 24), HImode);
8718 : : rtx x9 = gen_int_mode (poly_int64 (-30, -24), HImode);
8719 : : rtx x10 = gen_int_mode (poly_int64 (-31, -24), HImode);
8720 : : rtx two = GEN_INT (2);
8721 : : rtx six = GEN_INT (6);
8722 : : poly_uint64 offset = subreg_lowpart_offset (QImode, HImode);
8723 : :
8724 : : /* These tests only try limited operation combinations. Fuller arithmetic
8725 : : testing is done directly on poly_ints. */
8726 : : ASSERT_EQ (simplify_unary_operation (NEG, HImode, x8, HImode), x9);
8727 : : ASSERT_EQ (simplify_unary_operation (NOT, HImode, x8, HImode), x10);
8728 : : ASSERT_EQ (simplify_unary_operation (TRUNCATE, QImode, x8, HImode), x5);
8729 : : ASSERT_EQ (simplify_binary_operation (PLUS, QImode, x1, x2), x3);
8730 : : ASSERT_EQ (simplify_binary_operation (MINUS, QImode, x3, x1), x2);
8731 : : ASSERT_EQ (simplify_binary_operation (MULT, QImode, x4, six), x5);
8732 : : ASSERT_EQ (simplify_binary_operation (MULT, QImode, six, x4), x5);
8733 : : ASSERT_EQ (simplify_binary_operation (ASHIFT, QImode, x4, two), x6);
8734 : : ASSERT_EQ (simplify_binary_operation (IOR, QImode, x4, two), x7);
8735 : : ASSERT_EQ (simplify_subreg (HImode, x5, QImode, 0), x8);
8736 : : ASSERT_EQ (simplify_subreg (QImode, x8, HImode, offset), x5);
8737 : : }
8738 : :
8739 : : /* Run all of the selftests within this file. */
8740 : :
8741 : : void
8742 : 4 : simplify_rtx_cc_tests ()
8743 : : {
8744 : 4 : test_scalar_ops ();
8745 : 4 : test_vector_ops ();
8746 : 4 : simplify_const_poly_int_tests<NUM_POLY_INT_COEFFS>::run ();
8747 : 4 : }
8748 : :
8749 : : } // namespace selftest
8750 : :
8751 : : #endif /* CHECKING_P */
|