Branch data Line data Source code
1 : : /* RTL simplification functions for GNU compiler.
2 : : Copyright (C) 1987-2025 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 : 9083125 : neg_poly_int_rtx (machine_mode mode, const_rtx i)
56 : : {
57 : 9083125 : 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 : 6371272 : mode_signbit_p (machine_mode mode, const_rtx x)
65 : : {
66 : 6371272 : unsigned HOST_WIDE_INT val;
67 : 6371272 : unsigned int width;
68 : 6371272 : scalar_int_mode int_mode;
69 : :
70 : 6371272 : if (!is_int_mode (mode, &int_mode))
71 : : return false;
72 : :
73 : 6371264 : width = GET_MODE_PRECISION (int_mode);
74 : 6371264 : if (width == 0)
75 : : return false;
76 : :
77 : 6371264 : if (width <= HOST_BITS_PER_WIDE_INT
78 : 6369725 : && CONST_INT_P (x))
79 : 6229320 : val = INTVAL (x);
80 : : #if TARGET_SUPPORTS_WIDE_INT
81 : 141944 : else if (CONST_WIDE_INT_P (x))
82 : : {
83 : 474 : unsigned int i;
84 : 474 : unsigned int elts = CONST_WIDE_INT_NUNITS (x);
85 : 474 : if (elts != (width + HOST_BITS_PER_WIDE_INT - 1) / HOST_BITS_PER_WIDE_INT)
86 : : return false;
87 : 888 : for (i = 0; i < elts - 1; i++)
88 : 474 : if (CONST_WIDE_INT_ELT (x, i) != 0)
89 : : return false;
90 : 414 : val = CONST_WIDE_INT_ELT (x, elts - 1);
91 : 414 : width %= HOST_BITS_PER_WIDE_INT;
92 : 414 : if (width == 0)
93 : : width = HOST_BITS_PER_WIDE_INT;
94 : : }
95 : : #else
96 : : else if (width <= HOST_BITS_PER_DOUBLE_INT
97 : : && CONST_DOUBLE_AS_INT_P (x)
98 : : && CONST_DOUBLE_LOW (x) == 0)
99 : : {
100 : : val = CONST_DOUBLE_HIGH (x);
101 : : width -= HOST_BITS_PER_WIDE_INT;
102 : : }
103 : : #endif
104 : : else
105 : : /* X is not an integer constant. */
106 : : return false;
107 : :
108 : 6229320 : if (width < HOST_BITS_PER_WIDE_INT)
109 : 5624379 : val &= (HOST_WIDE_INT_1U << width) - 1;
110 : 6229734 : 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 : 3742712 : val_signbit_p (machine_mode mode, unsigned HOST_WIDE_INT val)
119 : : {
120 : 3742712 : unsigned int width;
121 : 3742712 : scalar_int_mode int_mode;
122 : :
123 : 3742712 : if (!is_int_mode (mode, &int_mode))
124 : : return false;
125 : :
126 : 3742676 : width = GET_MODE_PRECISION (int_mode);
127 : 3742676 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
128 : : return false;
129 : :
130 : 3738022 : val &= GET_MODE_MASK (int_mode);
131 : 3738022 : 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 : 2732086 : val_signbit_known_set_p (machine_mode mode, unsigned HOST_WIDE_INT val)
138 : : {
139 : 2732086 : unsigned int width;
140 : :
141 : 2732086 : scalar_int_mode int_mode;
142 : 2732086 : if (!is_int_mode (mode, &int_mode))
143 : : return false;
144 : :
145 : 2698800 : width = GET_MODE_PRECISION (int_mode);
146 : 2698800 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
147 : : return false;
148 : :
149 : 2698800 : val &= HOST_WIDE_INT_1U << (width - 1);
150 : 2698800 : 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 : 7653160 : val_signbit_known_clear_p (machine_mode mode, unsigned HOST_WIDE_INT val)
157 : : {
158 : 7653160 : unsigned int width;
159 : :
160 : 7653160 : scalar_int_mode int_mode;
161 : 7653160 : if (!is_int_mode (mode, &int_mode))
162 : : return false;
163 : :
164 : 7328747 : width = GET_MODE_PRECISION (int_mode);
165 : 7328747 : if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
166 : : return false;
167 : :
168 : 7217133 : val &= HOST_WIDE_INT_1U << (width - 1);
169 : 7217133 : 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 : 116752343 : simplify_context::simplify_gen_binary (rtx_code code, machine_mode mode,
177 : : rtx op0, rtx op1)
178 : : {
179 : 116752343 : rtx tem;
180 : :
181 : : /* If this simplifies, do it. */
182 : 116752343 : tem = simplify_binary_operation (code, mode, op0, op1);
183 : 116752343 : if (tem)
184 : : return tem;
185 : :
186 : : /* Put complex operands first and constants second if commutative. */
187 : 73460731 : if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
188 : 73460731 : && swap_commutative_operands_p (op0, op1))
189 : : std::swap (op0, op1);
190 : :
191 : 73460731 : 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 : 2778135555 : avoid_constant_pool_reference (rtx x)
198 : : {
199 : 2778135555 : rtx c, tmp, addr;
200 : 2778135555 : machine_mode cmode;
201 : 2778135555 : poly_int64 offset = 0;
202 : :
203 : 2778135555 : switch (GET_CODE (x))
204 : : {
205 : 258043276 : case MEM:
206 : 258043276 : break;
207 : :
208 : 910444 : case FLOAT_EXTEND:
209 : : /* Handle float extensions of constant pool references. */
210 : 910444 : tmp = XEXP (x, 0);
211 : 910444 : c = avoid_constant_pool_reference (tmp);
212 : 910444 : if (c != tmp && CONST_DOUBLE_AS_FLOAT_P (c))
213 : 123063 : return const_double_from_real_value (*CONST_DOUBLE_REAL_VALUE (c),
214 : 123063 : GET_MODE (x));
215 : : return x;
216 : :
217 : : default:
218 : : return x;
219 : : }
220 : :
221 : 258043276 : if (GET_MODE (x) == BLKmode)
222 : : return x;
223 : :
224 : 255876491 : addr = XEXP (x, 0);
225 : :
226 : : /* Call target hook to avoid the effects of -fpic etc.... */
227 : 255876491 : addr = targetm.delegitimize_address (addr);
228 : :
229 : : /* Split the address into a base and integer offset. */
230 : 255876491 : addr = strip_offset (addr, &offset);
231 : :
232 : 255876491 : 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 : 255876491 : if (GET_CODE (addr) == SYMBOL_REF
238 : 255876491 : && CONSTANT_POOL_ADDRESS_P (addr))
239 : : {
240 : 5459278 : c = get_pool_constant (addr);
241 : 5459278 : 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 : 5459278 : if (known_eq (offset, 0) && cmode == GET_MODE (x))
247 : : return c;
248 : 20066 : else if (known_in_range_p (offset, 0, GET_MODE_SIZE (cmode)))
249 : : {
250 : 10033 : rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset);
251 : 10033 : 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 : 3515546283 : 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 : 3515546283 : if (MEM_P (x)
269 : 61990463 : && MEM_EXPR (x)
270 : 3553537014 : && MEM_OFFSET_KNOWN_P (x))
271 : : {
272 : 35074011 : tree decl = MEM_EXPR (x);
273 : 35074011 : machine_mode mode = GET_MODE (x);
274 : 35074011 : poly_int64 offset = 0;
275 : :
276 : 35074011 : switch (TREE_CODE (decl))
277 : : {
278 : : default:
279 : : decl = NULL;
280 : : break;
281 : :
282 : : case VAR_DECL:
283 : : break;
284 : :
285 : 10058210 : case ARRAY_REF:
286 : 10058210 : case ARRAY_RANGE_REF:
287 : 10058210 : case COMPONENT_REF:
288 : 10058210 : case BIT_FIELD_REF:
289 : 10058210 : case REALPART_EXPR:
290 : 10058210 : case IMAGPART_EXPR:
291 : 10058210 : case VIEW_CONVERT_EXPR:
292 : 10058210 : {
293 : 10058210 : poly_int64 bitsize, bitpos, bytepos, toffset_val = 0;
294 : 10058210 : tree toffset;
295 : 10058210 : int unsignedp, reversep, volatilep = 0;
296 : :
297 : 10058210 : decl
298 : 10058210 : = get_inner_reference (decl, &bitsize, &bitpos, &toffset, &mode,
299 : : &unsignedp, &reversep, &volatilep);
300 : 20116420 : if (maybe_ne (bitsize, GET_MODE_BITSIZE (mode))
301 : 10341351 : || !multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
302 : 19660772 : || (toffset && !poly_int_tree_p (toffset, &toffset_val)))
303 : : decl = NULL;
304 : : else
305 : 9319421 : offset += bytepos + toffset_val;
306 : 10058210 : break;
307 : : }
308 : : }
309 : :
310 : 738789 : if (decl
311 : 20576750 : && mode == GET_MODE (x)
312 : 20294546 : && VAR_P (decl)
313 : 13190445 : && (TREE_STATIC (decl)
314 : 11978423 : || DECL_THREAD_LOCAL_P (decl))
315 : 1247431 : && DECL_RTL_SET_P (decl)
316 : 10566346 : && MEM_P (DECL_RTL (decl)))
317 : : {
318 : 1246925 : rtx newx;
319 : :
320 : 1246925 : offset += MEM_OFFSET (x);
321 : :
322 : 1246925 : newx = DECL_RTL (decl);
323 : :
324 : 1246925 : if (MEM_P (newx))
325 : : {
326 : 1246925 : rtx n = XEXP (newx, 0), o = XEXP (x, 0);
327 : 1246925 : 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 : 1246925 : n = strip_offset (n, &n_offset);
336 : 1246925 : o = strip_offset (o, &o_offset);
337 : 2466638 : if (!(known_eq (o_offset, n_offset + offset)
338 : 1219713 : && rtx_equal_p (o, n)))
339 : 208531 : 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 : 3515546283 : 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 : 5311316 : simplify_context::simplify_gen_unary (rtx_code code, machine_mode mode, rtx op,
355 : : machine_mode op_mode)
356 : : {
357 : 5311316 : rtx tem;
358 : :
359 : : /* If this simplifies, use it. */
360 : 5311316 : if ((tem = simplify_unary_operation (code, mode, op, op_mode)) != 0)
361 : : return tem;
362 : :
363 : 2028712 : return gen_rtx_fmt_e (code, mode, op);
364 : : }
365 : :
366 : : /* Likewise for ternary operations. */
367 : :
368 : : rtx
369 : 2198864 : 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 : 2198864 : rtx tem;
374 : :
375 : : /* If this simplifies, use it. */
376 : 2198864 : if ((tem = simplify_ternary_operation (code, mode, op0_mode,
377 : : op0, op1, op2)) != 0)
378 : : return tem;
379 : :
380 : 1951202 : 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 : 21289764 : simplify_context::simplify_gen_relational (rtx_code code, machine_mode mode,
388 : : machine_mode cmp_mode,
389 : : rtx op0, rtx op1)
390 : : {
391 : 21289764 : rtx tem;
392 : :
393 : 21289764 : if ((tem = simplify_relational_operation (code, mode, cmp_mode,
394 : : op0, op1)) != 0)
395 : : return tem;
396 : :
397 : 19039862 : 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 : 488874307 : simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
407 : : rtx (*fn) (rtx, const_rtx, void *), void *data)
408 : : {
409 : 488874307 : enum rtx_code code = GET_CODE (x);
410 : 488874307 : machine_mode mode = GET_MODE (x);
411 : 488874307 : machine_mode op_mode;
412 : 488874307 : const char *fmt;
413 : 488874307 : rtx op0, op1, op2, newx, op;
414 : 488874307 : rtvec vec, newvec;
415 : 488874307 : int i, j;
416 : :
417 : 488874307 : if (UNLIKELY (fn != NULL))
418 : : {
419 : 426163399 : newx = fn (x, old_rtx, data);
420 : 426163399 : if (newx)
421 : : return newx;
422 : : }
423 : 62710908 : else if (rtx_equal_p (x, old_rtx))
424 : 5259140 : return copy_rtx ((rtx) data);
425 : :
426 : 383389248 : switch (GET_RTX_CLASS (code))
427 : : {
428 : 2145076 : case RTX_UNARY:
429 : 2145076 : op0 = XEXP (x, 0);
430 : 2145076 : op_mode = GET_MODE (op0);
431 : 2145076 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
432 : 2145076 : if (op0 == XEXP (x, 0))
433 : : return x;
434 : 679980 : return simplify_gen_unary (code, mode, op0, op_mode);
435 : :
436 : 76299864 : case RTX_BIN_ARITH:
437 : 76299864 : case RTX_COMM_ARITH:
438 : 76299864 : op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
439 : 76299864 : op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
440 : 76299864 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
441 : : return x;
442 : 23411730 : return simplify_gen_binary (code, mode, op0, op1);
443 : :
444 : 9805279 : case RTX_COMPARE:
445 : 9805279 : case RTX_COMM_COMPARE:
446 : 9805279 : op0 = XEXP (x, 0);
447 : 9805279 : op1 = XEXP (x, 1);
448 : 9805279 : op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
449 : 9805279 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
450 : 9805279 : op1 = simplify_replace_fn_rtx (op1, old_rtx, fn, data);
451 : 9805279 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
452 : : return x;
453 : 2317292 : return simplify_gen_relational (code, mode, op_mode, op0, op1);
454 : :
455 : 5769892 : case RTX_TERNARY:
456 : 5769892 : case RTX_BITFIELD_OPS:
457 : 5769892 : op0 = XEXP (x, 0);
458 : 5769892 : op_mode = GET_MODE (op0);
459 : 5769892 : op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
460 : 5769892 : op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
461 : 5769892 : op2 = simplify_replace_fn_rtx (XEXP (x, 2), old_rtx, fn, data);
462 : 5769892 : if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2))
463 : : return x;
464 : 1645216 : if (op_mode == VOIDmode)
465 : 1625086 : op_mode = GET_MODE (op0);
466 : 1645216 : return simplify_gen_ternary (code, mode, op_mode, op0, op1, op2);
467 : :
468 : 83231947 : case RTX_EXTRA:
469 : 83231947 : if (code == SUBREG)
470 : : {
471 : 708203 : op0 = simplify_replace_fn_rtx (SUBREG_REG (x), old_rtx, fn, data);
472 : 708203 : if (op0 == SUBREG_REG (x))
473 : : return x;
474 : 140558 : op0 = simplify_gen_subreg (GET_MODE (x), op0,
475 : 70279 : GET_MODE (SUBREG_REG (x)),
476 : 70279 : SUBREG_BYTE (x));
477 : 70279 : return op0 ? op0 : x;
478 : : }
479 : : break;
480 : :
481 : 61541677 : case RTX_OBJ:
482 : 61541677 : if (code == MEM)
483 : : {
484 : 11049015 : op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
485 : 11049015 : if (op0 == XEXP (x, 0))
486 : : return x;
487 : 165327 : return replace_equiv_address_nv (x, op0);
488 : : }
489 : 50492662 : 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 : 277611919 : newx = x;
515 : 277611919 : fmt = GET_RTX_FORMAT (code);
516 : 598894119 : for (i = 0; fmt[i]; i++)
517 : 321282200 : switch (fmt[i])
518 : : {
519 : 3065549 : case 'E':
520 : 3065549 : vec = XVEC (x, i);
521 : 3065549 : newvec = XVEC (newx, i);
522 : 12760491 : for (j = 0; j < GET_NUM_ELEM (vec); j++)
523 : : {
524 : 9694942 : op = simplify_replace_fn_rtx (RTVEC_ELT (vec, j),
525 : : old_rtx, fn, data);
526 : 9694942 : if (op != RTVEC_ELT (vec, j))
527 : : {
528 : 346876 : if (newvec == vec)
529 : : {
530 : 337951 : newvec = shallow_copy_rtvec (vec);
531 : 337951 : if (x == newx)
532 : 337951 : newx = shallow_copy_rtx (x);
533 : 337951 : XVEC (newx, i) = newvec;
534 : : }
535 : 346876 : RTVEC_ELT (newvec, j) = op;
536 : : }
537 : : }
538 : : break;
539 : :
540 : 75017227 : case 'e':
541 : 75017227 : if (XEXP (x, i))
542 : : {
543 : 75017227 : op = simplify_replace_fn_rtx (XEXP (x, i), old_rtx, fn, data);
544 : 75017227 : if (op != XEXP (x, i))
545 : : {
546 : 4381018 : if (x == newx)
547 : 4377728 : newx = shallow_copy_rtx (x);
548 : 4381018 : 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 : 12884603 : simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx)
561 : : {
562 : 12884603 : 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 : 18457504 : simplify_context::simplify_truncation (machine_mode mode, rtx op,
614 : : machine_mode op_mode)
615 : : {
616 : 18457504 : unsigned int precision = GET_MODE_UNIT_PRECISION (mode);
617 : 18457504 : unsigned int op_precision = GET_MODE_UNIT_PRECISION (op_mode);
618 : 18457504 : scalar_int_mode int_mode, int_op_mode, subreg_mode;
619 : :
620 : 18457504 : gcc_assert (precision <= op_precision);
621 : :
622 : : /* Optimize truncations of zero and sign extended values. */
623 : 18457504 : if (GET_CODE (op) == ZERO_EXTEND
624 : 18457504 : || 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 : 287774 : machine_mode origmode = GET_MODE (XEXP (op, 0));
633 : 287774 : if (mode == origmode)
634 : : return XEXP (op, 0);
635 : 16864 : else if (precision <= GET_MODE_UNIT_PRECISION (origmode))
636 : 4758 : return simplify_gen_unary (TRUNCATE, mode,
637 : 4758 : XEXP (op, 0), origmode);
638 : : else
639 : 3674 : return simplify_gen_unary (GET_CODE (op), mode,
640 : 3674 : 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 : 18169730 : if (1
647 : : && (!WORD_REGISTER_OPERATIONS || precision >= BITS_PER_WORD)
648 : : && (GET_CODE (op) == PLUS
649 : : || GET_CODE (op) == MINUS
650 : 18169730 : || GET_CODE (op) == MULT))
651 : : {
652 : 780552 : rtx op0 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0), op_mode);
653 : 780552 : if (op0)
654 : : {
655 : 780552 : rtx op1 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 1), op_mode);
656 : 780552 : if (op1)
657 : 780552 : 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 : 17389178 : if ((GET_CODE (op) == LSHIFTRT
665 : 17389178 : || 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 : 1705568 : && 2 * precision <= op_precision
671 : 1705568 : && CONST_INT_P (XEXP (op, 1))
672 : 1605743 : && GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
673 : 22 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
674 : 19 : && UINTVAL (XEXP (op, 1)) < precision)
675 : 15 : return simplify_gen_binary (ASHIFTRT, mode,
676 : 15 : 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 : 17389163 : if ((GET_CODE (op) == LSHIFTRT
682 : : || GET_CODE (op) == ASHIFTRT)
683 : 1705553 : && CONST_INT_P (XEXP (op, 1))
684 : 1605728 : && GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
685 : 674 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
686 : 674 : && UINTVAL (XEXP (op, 1)) < precision)
687 : 664 : return simplify_gen_binary (LSHIFTRT, mode,
688 : 664 : 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 : 17388499 : if (GET_CODE (op) == ASHIFT
694 : 468564 : && CONST_INT_P (XEXP (op, 1))
695 : 409835 : && (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
696 : 409835 : || GET_CODE (XEXP (op, 0)) == SIGN_EXTEND)
697 : 547 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
698 : 534 : && UINTVAL (XEXP (op, 1)) < precision)
699 : 526 : return simplify_gen_binary (ASHIFT, mode,
700 : 526 : 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 : 17387973 : if (GET_CODE (op) == AND
706 : 620233 : && (GET_CODE (XEXP (op, 0)) == LSHIFTRT
707 : 620233 : || GET_CODE (XEXP (op, 0)) == ASHIFTRT)
708 : 30960 : && CONST_INT_P (XEXP (XEXP (op, 0), 1))
709 : 30850 : && CONST_INT_P (XEXP (op, 1)))
710 : : {
711 : 30850 : rtx op0 = (XEXP (XEXP (op, 0), 0));
712 : 30850 : rtx shift_op = XEXP (XEXP (op, 0), 1);
713 : 30850 : rtx mask_op = XEXP (op, 1);
714 : 30850 : unsigned HOST_WIDE_INT shift = UINTVAL (shift_op);
715 : 30850 : unsigned HOST_WIDE_INT mask = UINTVAL (mask_op);
716 : :
717 : 30850 : if (shift < precision
718 : : /* If doing this transform works for an X with all bits set,
719 : : it works for any X. */
720 : 17874 : && ((GET_MODE_MASK (mode) >> shift) & mask)
721 : 17874 : == ((GET_MODE_MASK (op_mode) >> shift) & mask)
722 : 3201 : && (op0 = simplify_gen_unary (TRUNCATE, mode, op0, op_mode))
723 : 34051 : && (op0 = simplify_gen_binary (LSHIFTRT, mode, op0, shift_op)))
724 : : {
725 : 3201 : mask_op = GEN_INT (trunc_int_for_mode (mask, mode));
726 : 3201 : 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 : 17384772 : if ((GET_CODE (op) == ZERO_EXTRACT || GET_CODE (op) == SIGN_EXTRACT)
734 : 414643 : && REG_P (XEXP (op, 0))
735 : 275633 : && GET_MODE (XEXP (op, 0)) == GET_MODE (op)
736 : 274833 : && CONST_INT_P (XEXP (op, 1))
737 : 274833 : && CONST_INT_P (XEXP (op, 2)))
738 : : {
739 : 238244 : rtx op0 = XEXP (op, 0);
740 : 238244 : unsigned HOST_WIDE_INT len = UINTVAL (XEXP (op, 1));
741 : 238244 : unsigned HOST_WIDE_INT pos = UINTVAL (XEXP (op, 2));
742 : 238244 : 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 : 238244 : else if (!BITS_BIG_ENDIAN && precision >= len + pos)
753 : : {
754 : 8106 : op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
755 : 8106 : if (op0)
756 : 8106 : return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
757 : 8106 : XEXP (op, 1), XEXP (op, 2));
758 : : }
759 : : }
760 : :
761 : : /* Recognize a word extraction from a multi-word subreg. */
762 : 17376666 : if ((GET_CODE (op) == LSHIFTRT
763 : 17376666 : || GET_CODE (op) == ASHIFTRT)
764 : 1704889 : && SCALAR_INT_MODE_P (mode)
765 : 1701947 : && SCALAR_INT_MODE_P (op_mode)
766 : 1834197 : && precision >= BITS_PER_WORD
767 : 64766 : && 2 * precision <= op_precision
768 : 64766 : && CONST_INT_P (XEXP (op, 1))
769 : 56676 : && (INTVAL (XEXP (op, 1)) & (precision - 1)) == 0
770 : 1897 : && UINTVAL (XEXP (op, 1)) < op_precision)
771 : : {
772 : 1897 : poly_int64 byte = subreg_lowpart_offset (mode, op_mode);
773 : 1897 : int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
774 : 1897 : return simplify_gen_subreg (mode, XEXP (op, 0), op_mode,
775 : : (WORDS_BIG_ENDIAN
776 : 1897 : ? byte - shifted_bytes
777 : 1897 : : 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 : 17374769 : if ((GET_CODE (op) == LSHIFTRT
784 : : || GET_CODE (op) == ASHIFTRT)
785 : 1700050 : && is_a <scalar_int_mode> (mode, &int_mode)
786 : 19073586 : && is_a <scalar_int_mode> (op_mode, &int_op_mode)
787 : 1700050 : && MEM_P (XEXP (op, 0))
788 : 11116 : && CONST_INT_P (XEXP (op, 1))
789 : 20668 : && INTVAL (XEXP (op, 1)) % GET_MODE_BITSIZE (int_mode) == 0
790 : 1272 : && INTVAL (XEXP (op, 1)) > 0
791 : 2544 : && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (int_op_mode)
792 : 1272 : && ! mode_dependent_address_p (XEXP (XEXP (op, 0), 0),
793 : 1272 : MEM_ADDR_SPACE (XEXP (op, 0)))
794 : 1272 : && ! MEM_VOLATILE_P (XEXP (op, 0))
795 : 17374769 : && (GET_MODE_SIZE (int_mode) >= UNITS_PER_WORD
796 : : || WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN))
797 : : {
798 : 1233 : poly_int64 byte = subreg_lowpart_offset (int_mode, int_op_mode);
799 : 1233 : int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
800 : 1233 : 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 : 17373536 : if ((GET_CODE (op) == ABS
809 : 17373536 : || GET_CODE (op) == NEG)
810 : 27109 : && (GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
811 : 27109 : || GET_CODE (XEXP (op, 0)) == ZERO_EXTEND)
812 : 18 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
813 : 2 : return simplify_gen_unary (GET_CODE (op), mode,
814 : 2 : XEXP (XEXP (op, 0), 0), mode);
815 : :
816 : : /* Simplifications of (truncate:A (subreg:B X 0)). */
817 : 17373534 : if (GET_CODE (op) == SUBREG
818 : 17373632 : && is_a <scalar_int_mode> (mode, &int_mode)
819 : 34741 : && SCALAR_INT_MODE_P (op_mode)
820 : 34741 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &subreg_mode)
821 : 17408213 : && subreg_lowpart_p (op))
822 : : {
823 : : /* (truncate:A (subreg:B (truncate:C X) 0)) is (truncate:A X). */
824 : 34676 : if (GET_CODE (SUBREG_REG (op)) == TRUNCATE)
825 : : {
826 : 0 : rtx inner = XEXP (SUBREG_REG (op), 0);
827 : 0 : if (GET_MODE_PRECISION (int_mode)
828 : 0 : <= GET_MODE_PRECISION (subreg_mode))
829 : 0 : return simplify_gen_unary (TRUNCATE, int_mode, inner,
830 : 0 : GET_MODE (inner));
831 : : else
832 : : /* If subreg above is paradoxical and C is narrower
833 : : than A, return (subreg:A (truncate:C X) 0). */
834 : 0 : return simplify_gen_subreg (int_mode, SUBREG_REG (op),
835 : : subreg_mode, 0);
836 : : }
837 : :
838 : : /* Simplifications of (truncate:A (subreg:B X:C 0)) with
839 : : paradoxical subregs (B is wider than C). */
840 : 34676 : if (is_a <scalar_int_mode> (op_mode, &int_op_mode))
841 : : {
842 : 34676 : unsigned int int_op_prec = GET_MODE_PRECISION (int_op_mode);
843 : 34676 : unsigned int subreg_prec = GET_MODE_PRECISION (subreg_mode);
844 : 34676 : if (int_op_prec > subreg_prec)
845 : : {
846 : 1367 : 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 : 33309 : else if (int_op_prec < subreg_prec
855 : 33309 : && GET_MODE_PRECISION (int_mode) < int_op_prec)
856 : 33309 : return simplify_gen_unary (TRUNCATE, int_mode,
857 : 33309 : SUBREG_REG (op), subreg_mode);
858 : : }
859 : : }
860 : :
861 : : /* (truncate:A (truncate:B X)) is (truncate:A X). */
862 : 17338891 : if (GET_CODE (op) == TRUNCATE)
863 : 0 : return simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0),
864 : 0 : GET_MODE (XEXP (op, 0)));
865 : :
866 : : /* (truncate:A (ior X C)) is (const_int -1) if C is equal to that already,
867 : : in mode A. */
868 : 17338891 : if (GET_CODE (op) == IOR
869 : 34211 : && SCALAR_INT_MODE_P (mode)
870 : 34211 : && SCALAR_INT_MODE_P (op_mode)
871 : 34211 : && CONST_INT_P (XEXP (op, 1))
872 : 17347025 : && trunc_int_for_mode (INTVAL (XEXP (op, 1)), mode) == -1)
873 : 42 : return constm1_rtx;
874 : :
875 : : return NULL_RTX;
876 : : }
877 : :
878 : : /* Try to simplify a unary operation CODE whose output mode is to be
879 : : MODE with input operand OP whose mode was originally OP_MODE.
880 : : Return zero if no simplification can be made. */
881 : : rtx
882 : 27904256 : simplify_context::simplify_unary_operation (rtx_code code, machine_mode mode,
883 : : rtx op, machine_mode op_mode)
884 : : {
885 : 27904256 : rtx trueop, tem;
886 : :
887 : 27904256 : trueop = avoid_constant_pool_reference (op);
888 : :
889 : 27904256 : tem = simplify_const_unary_operation (code, mode, trueop, op_mode);
890 : 27904256 : if (tem)
891 : : return tem;
892 : :
893 : 22875956 : 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 : 2692 : exact_int_to_float_conversion_p (const_rtx op)
901 : : {
902 : 2692 : 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 : 2692 : if (op0_mode == VOIDmode)
906 : : return false;
907 : 5382 : int out_bits = significand_size (GET_MODE_INNER (GET_MODE (op)));
908 : 2691 : int in_prec = GET_MODE_UNIT_PRECISION (op0_mode);
909 : 2691 : int in_bits = in_prec;
910 : 2691 : if (HWI_COMPUTABLE_MODE_P (op0_mode))
911 : : {
912 : 2601 : unsigned HOST_WIDE_INT nonzero = nonzero_bits (XEXP (op, 0), op0_mode);
913 : 2601 : if (GET_CODE (op) == FLOAT)
914 : 2477 : in_bits -= num_sign_bit_copies (XEXP (op, 0), op0_mode);
915 : 124 : else if (GET_CODE (op) == UNSIGNED_FLOAT)
916 : 124 : in_bits = wi::min_precision (wi::uhwi (nonzero, in_prec), UNSIGNED);
917 : : else
918 : 0 : gcc_unreachable ();
919 : 2601 : in_bits -= wi::ctz (wi::uhwi (nonzero, in_prec));
920 : : }
921 : 2691 : 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 : 22875956 : simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
928 : : rtx op)
929 : : {
930 : 22875956 : enum rtx_code reversed;
931 : 22875956 : rtx temp, elt, base, step;
932 : 22875956 : scalar_int_mode inner, int_mode, op_mode, op0_mode;
933 : :
934 : 22875956 : switch (code)
935 : : {
936 : 1823461 : case NOT:
937 : : /* (not (not X)) == X. */
938 : 1823461 : if (GET_CODE (op) == NOT)
939 : 3850 : 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 : 1819611 : if (COMPARISON_P (op)
944 : 10985 : && (mode == BImode || STORE_FLAG_VALUE == -1)
945 : 1819611 : && ((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 : 1819611 : if (GET_CODE (op) == PLUS
951 : 290615 : && XEXP (op, 1) == constm1_rtx)
952 : 7245 : 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 : 1812366 : if (GET_CODE (op) == NEG && CONSTM1_RTX (mode))
958 : 71667 : return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
959 : 71667 : CONSTM1_RTX (mode));
960 : :
961 : : /* (not (xor X C)) for C constant is (xor X D) with D = ~C. */
962 : 1740699 : if (GET_CODE (op) == XOR
963 : 15085 : && CONST_INT_P (XEXP (op, 1))
964 : 1744537 : && (temp = simplify_unary_operation (NOT, mode,
965 : : XEXP (op, 1), mode)) != 0)
966 : 3838 : 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 : 1736861 : if (GET_CODE (op) == PLUS
970 : 283370 : && CONST_INT_P (XEXP (op, 1))
971 : 166065 : && mode_signbit_p (mode, XEXP (op, 1))
972 : 1742251 : && (temp = simplify_unary_operation (NOT, mode,
973 : : XEXP (op, 1), mode)) != 0)
974 : 5390 : 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 : 1731471 : if (GET_CODE (op) == ASHIFT
983 : 47683 : && XEXP (op, 0) == const1_rtx)
984 : : {
985 : 1073 : temp = simplify_gen_unary (NOT, mode, const1_rtx, mode);
986 : 1073 : 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 : 1730398 : 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 : 1730398 : if (partial_subreg_p (op)
1002 : 71225 : && subreg_lowpart_p (op)
1003 : 70911 : && GET_CODE (SUBREG_REG (op)) == ASHIFT
1004 : 97278 : && XEXP (SUBREG_REG (op), 0) == const1_rtx)
1005 : : {
1006 : 163 : machine_mode inner_mode = GET_MODE (SUBREG_REG (op));
1007 : 163 : rtx x;
1008 : :
1009 : 163 : x = gen_rtx_ROTATE (inner_mode,
1010 : : simplify_gen_unary (NOT, inner_mode, const1_rtx,
1011 : : inner_mode),
1012 : : XEXP (SUBREG_REG (op), 1));
1013 : 163 : temp = rtl_hooks.gen_lowpart_no_emit (mode, x);
1014 : 163 : if (temp)
1015 : : return temp;
1016 : : }
1017 : :
1018 : : /* Apply De Morgan's laws to reduce number of patterns for machines
1019 : : with negating logical insns (and-not, nand, etc.). If result has
1020 : : only one NOT, put it first, since that is how the patterns are
1021 : : coded. */
1022 : 1730235 : if (GET_CODE (op) == IOR || GET_CODE (op) == AND)
1023 : : {
1024 : 11709 : rtx in1 = XEXP (op, 0), in2 = XEXP (op, 1);
1025 : 11709 : machine_mode op_mode;
1026 : :
1027 : 11709 : op_mode = GET_MODE (in1);
1028 : 11709 : in1 = simplify_gen_unary (NOT, op_mode, in1, op_mode);
1029 : :
1030 : 11709 : op_mode = GET_MODE (in2);
1031 : 11709 : if (op_mode == VOIDmode)
1032 : 5798 : op_mode = mode;
1033 : 11709 : in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode);
1034 : :
1035 : 11709 : if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT)
1036 : : std::swap (in1, in2);
1037 : :
1038 : 23418 : 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 : 1718526 : 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 : 1648360 : case NEG:
1051 : : /* (neg (neg X)) == X. */
1052 : 1648360 : if (GET_CODE (op) == NEG)
1053 : 6596 : 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 : 1641764 : if (GET_CODE (op) == IF_THEN_ELSE)
1059 : : {
1060 : 2414 : rtx cond = XEXP (op, 0);
1061 : 2414 : rtx true_rtx = XEXP (op, 1);
1062 : 2414 : rtx false_rtx = XEXP (op, 2);
1063 : :
1064 : 2414 : if ((GET_CODE (true_rtx) == NEG
1065 : 0 : && rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
1066 : 2414 : || (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 : 1641764 : if (GET_CODE (op) == PLUS
1083 : 134759 : && XEXP (op, 1) == const1_rtx)
1084 : 53204 : return simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1085 : :
1086 : : /* Similarly, (neg (not X)) is (plus X 1). */
1087 : 1588560 : if (GET_CODE (op) == NOT)
1088 : 542 : return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
1089 : 542 : 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 : 1588018 : if (GET_CODE (op) == MINUS
1097 : 24197 : && !HONOR_SIGNED_ZEROS (mode)
1098 : 1610807 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1099 : 22789 : return simplify_gen_binary (MINUS, mode, XEXP (op, 1), XEXP (op, 0));
1100 : :
1101 : 1565229 : if (GET_CODE (op) == PLUS
1102 : 81555 : && !HONOR_SIGNED_ZEROS (mode)
1103 : 1646424 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1104 : : {
1105 : : /* (neg (plus A C)) is simplified to (minus -C A). */
1106 : 81195 : if (CONST_SCALAR_INT_P (XEXP (op, 1))
1107 : 5019 : || CONST_DOUBLE_AS_FLOAT_P (XEXP (op, 1)))
1108 : : {
1109 : 76176 : temp = simplify_unary_operation (NEG, mode, XEXP (op, 1), mode);
1110 : 76176 : if (temp)
1111 : 76176 : 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 : 5019 : temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
1116 : 5019 : 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 : 1484034 : if (GET_CODE (op) == MULT
1122 : 1484034 : && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1123 : : {
1124 : 20211 : temp = simplify_gen_unary (NEG, mode, XEXP (op, 1), mode);
1125 : 20211 : 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 : 1463823 : if (GET_CODE (op) == ASHIFT)
1132 : : {
1133 : 52573 : temp = simplify_unary_operation (NEG, mode, XEXP (op, 0), mode);
1134 : 52573 : if (temp)
1135 : 12890 : 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 : 1450933 : if (GET_CODE (op) == ASHIFTRT
1141 : 27396 : && CONST_INT_P (XEXP (op, 1))
1142 : 1505629 : && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1143 : 420 : return simplify_gen_binary (LSHIFTRT, mode,
1144 : 420 : 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 : 1450513 : if (GET_CODE (op) == LSHIFTRT
1149 : 7478 : && CONST_INT_P (XEXP (op, 1))
1150 : 1465313 : && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1151 : 2424 : return simplify_gen_binary (ASHIFTRT, mode,
1152 : 2424 : 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 : 1448089 : if (GET_CODE (op) == XOR
1156 : 23943 : && XEXP (op, 1) == const1_rtx
1157 : 1448227 : && nonzero_bits (XEXP (op, 0), mode) == 1)
1158 : 40 : 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 : 1448049 : if (GET_CODE (op) == LT
1163 : 2547 : && XEXP (op, 1) == const0_rtx
1164 : 1449643 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op, 0)), &inner))
1165 : : {
1166 : 336 : int_mode = as_a <scalar_int_mode> (mode);
1167 : 336 : int isize = GET_MODE_PRECISION (inner);
1168 : 336 : if (STORE_FLAG_VALUE == 1)
1169 : : {
1170 : 336 : temp = simplify_gen_binary (ASHIFTRT, inner, XEXP (op, 0),
1171 : : gen_int_shift_amount (inner,
1172 : 336 : isize - 1));
1173 : 336 : if (int_mode == inner)
1174 : : return temp;
1175 : 169 : if (GET_MODE_PRECISION (int_mode) > isize)
1176 : 104 : return simplify_gen_unary (SIGN_EXTEND, int_mode, temp, inner);
1177 : 65 : return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1178 : : }
1179 : : else if (STORE_FLAG_VALUE == -1)
1180 : : {
1181 : : temp = simplify_gen_binary (LSHIFTRT, inner, XEXP (op, 0),
1182 : : gen_int_shift_amount (inner,
1183 : : isize - 1));
1184 : : if (int_mode == inner)
1185 : : return temp;
1186 : : if (GET_MODE_PRECISION (int_mode) > isize)
1187 : : return simplify_gen_unary (ZERO_EXTEND, int_mode, temp, inner);
1188 : : return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1189 : : }
1190 : : }
1191 : :
1192 : 1447713 : if (vec_series_p (op, &base, &step))
1193 : : {
1194 : : /* Only create a new series if we can simplify both parts. In other
1195 : : cases this isn't really a simplification, and it's not necessarily
1196 : : a win to replace a vector operation with a scalar operation. */
1197 : 276 : scalar_mode inner_mode = GET_MODE_INNER (mode);
1198 : 276 : base = simplify_unary_operation (NEG, inner_mode, base, inner_mode);
1199 : 276 : if (base)
1200 : : {
1201 : 276 : step = simplify_unary_operation (NEG, inner_mode,
1202 : : step, inner_mode);
1203 : 276 : if (step)
1204 : 276 : return gen_vec_series (mode, base, step);
1205 : : }
1206 : : }
1207 : : break;
1208 : :
1209 : 1295862 : case TRUNCATE:
1210 : : /* Don't optimize (lshiftrt (mult ...)) as it would interfere
1211 : : with the umulXi3_highpart patterns. */
1212 : 1295862 : if (GET_CODE (op) == LSHIFTRT
1213 : 18350 : && GET_CODE (XEXP (op, 0)) == MULT)
1214 : : break;
1215 : :
1216 : 1288632 : 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 : 1288620 : if (GET_MODE (op) != VOIDmode)
1231 : : {
1232 : 1288620 : temp = simplify_truncation (mode, op, GET_MODE (op));
1233 : 1288620 : 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 : 1156821 : if (known_eq (GET_MODE_NUNITS (mode), 1)
1240 : 1156821 : && (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op))
1241 : 0 : || truncated_to_mode (mode, op)))
1242 : : {
1243 : 1145742 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1244 : 1145742 : 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 : 11307 : if (HWI_COMPUTABLE_MODE_P (mode)
1253 : 228 : && COMPARISON_P (op)
1254 : 0 : && (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0
1255 : 11307 : && 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 : 11307 : if (GET_CODE (op) == MEM
1265 : 339 : && !VECTOR_MODE_P (mode)
1266 : 226 : && !MEM_VOLATILE_P (op)
1267 : 11533 : && !mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op)))
1268 : : {
1269 : 226 : temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1270 : 226 : if (temp)
1271 : : return temp;
1272 : : }
1273 : :
1274 : : /* Check for useless truncation. */
1275 : 11307 : if (GET_MODE (op) == mode)
1276 : : return op;
1277 : : break;
1278 : :
1279 : 173811 : case FLOAT_TRUNCATE:
1280 : : /* Check for useless truncation. */
1281 : 173811 : if (GET_MODE (op) == mode)
1282 : : return op;
1283 : :
1284 : 173811 : if (DECIMAL_FLOAT_MODE_P (mode))
1285 : : break;
1286 : :
1287 : : /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF. */
1288 : 173657 : if (GET_CODE (op) == FLOAT_EXTEND
1289 : 2 : && 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 : 173657 : if ((GET_CODE (op) == FLOAT_TRUNCATE
1302 : 145 : && flag_unsafe_math_optimizations)
1303 : 173653 : || 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 : 173651 : if ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1312 : 173651 : && (flag_unsafe_math_optimizations
1313 : 1419 : || exact_int_to_float_conversion_p (op)))
1314 : 1418 : return simplify_gen_unary (GET_CODE (op), mode,
1315 : : XEXP (op, 0),
1316 : 1418 : 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 : 172233 : if ((GET_CODE (op) == ABS
1321 : 172233 : || GET_CODE (op) == NEG)
1322 : 209 : && GET_CODE (XEXP (op, 0)) == FLOAT_EXTEND
1323 : 28 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
1324 : 28 : return simplify_gen_unary (GET_CODE (op), mode,
1325 : 28 : XEXP (XEXP (op, 0), 0), mode);
1326 : :
1327 : : /* (float_truncate:SF (subreg:DF (float_truncate:SF X) 0))
1328 : : is (float_truncate:SF x). */
1329 : 172205 : if (GET_CODE (op) == SUBREG
1330 : 308 : && subreg_lowpart_p (op)
1331 : 172510 : && GET_CODE (SUBREG_REG (op)) == FLOAT_TRUNCATE)
1332 : : return SUBREG_REG (op);
1333 : : break;
1334 : :
1335 : 593561 : case FLOAT_EXTEND:
1336 : : /* Check for useless extension. */
1337 : 593561 : if (GET_MODE (op) == mode)
1338 : : return op;
1339 : :
1340 : 593561 : 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 : 593458 : if (GET_CODE (op) == FLOAT_EXTEND
1349 : 593458 : || ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1350 : 1273 : && exact_int_to_float_conversion_p (op)))
1351 : 562 : return simplify_gen_unary (GET_CODE (op), mode,
1352 : : XEXP (op, 0),
1353 : 562 : GET_MODE (XEXP (op, 0)));
1354 : :
1355 : : break;
1356 : :
1357 : 288789 : case ABS:
1358 : : /* (abs (neg <foo>)) -> (abs <foo>) */
1359 : 288789 : if (GET_CODE (op) == NEG)
1360 : 30 : return simplify_gen_unary (ABS, mode, XEXP (op, 0),
1361 : 30 : 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 : 288759 : if (GET_MODE (op) == VOIDmode)
1366 : : break;
1367 : :
1368 : : /* If operand is something known to be positive, ignore the ABS. */
1369 : 288759 : 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 : 288530 : 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 : 288530 : && 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 : 288530 : if (is_a <scalar_int_mode> (mode, &int_mode)
1400 : 40087 : && (num_sign_bit_copies (op, int_mode)
1401 : 40087 : == GET_MODE_PRECISION (int_mode)))
1402 : 49 : 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 : 3419 : case POPCOUNT:
1419 : 3419 : 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 : 36 : case ZERO_EXTEND:
1428 : : /* (popcount (zero_extend <X>)) = (zero_extend (popcount <X>)). */
1429 : 72 : temp = simplify_gen_unary (POPCOUNT, GET_MODE (XEXP (op, 0)),
1430 : 36 : XEXP (op, 0), GET_MODE (XEXP (op, 0)));
1431 : 36 : return simplify_gen_unary (ZERO_EXTEND, mode, temp,
1432 : 36 : 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 : 29356 : case BSWAP:
1481 : : /* (bswap (bswap x)) -> x. */
1482 : 29356 : if (GET_CODE (op) == BSWAP)
1483 : 128 : 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 : 932098 : case FLOAT:
1493 : : /* (float (sign_extend <X>)) = (float <X>). */
1494 : 932098 : if (GET_CODE (op) == SIGN_EXTEND)
1495 : 10918 : return simplify_gen_unary (FLOAT, mode, XEXP (op, 0),
1496 : 10918 : GET_MODE (XEXP (op, 0)));
1497 : : break;
1498 : :
1499 : 3217921 : case SIGN_EXTEND:
1500 : : /* Check for useless extension. */
1501 : 3217921 : 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 : 3217881 : if (GET_CODE (op) == TRUNCATE
1509 : 62 : && GET_MODE (XEXP (op, 0)) == mode
1510 : 62 : && GET_CODE (XEXP (op, 0)) == MINUS
1511 : 0 : && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
1512 : 0 : && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
1513 : : return XEXP (op, 0);
1514 : :
1515 : : /* Extending a widening multiplication should be canonicalized to
1516 : : a wider widening multiplication. */
1517 : 3217881 : if (GET_CODE (op) == MULT)
1518 : : {
1519 : 68241 : rtx lhs = XEXP (op, 0);
1520 : 68241 : rtx rhs = XEXP (op, 1);
1521 : 68241 : enum rtx_code lcode = GET_CODE (lhs);
1522 : 68241 : 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 : 68241 : if ((lcode == SIGN_EXTEND
1527 : 68092 : || (lcode == ASHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1528 : 877 : && (rcode == SIGN_EXTEND
1529 : 833 : || (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 : 3217773 : if (GET_CODE (op) == SUBREG
1563 : 164642 : && SUBREG_PROMOTED_VAR_P (op)
1564 : 3222715 : && 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 : 3217773 : if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND)
1591 : : {
1592 : 20100 : gcc_assert (GET_MODE_UNIT_PRECISION (mode)
1593 : : > GET_MODE_UNIT_PRECISION (GET_MODE (op)));
1594 : 6700 : return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0),
1595 : 6700 : 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 : 3211073 : if ((GET_CODE (op) == ASHIFTRT || GET_CODE (op) == LSHIFTRT)
1604 : 86481 : && GET_CODE (XEXP (op, 0)) == ASHIFT
1605 : 3213569 : && is_a <scalar_int_mode> (mode, &int_mode)
1606 : 5211 : && CONST_INT_P (XEXP (op, 1))
1607 : 5211 : && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1608 : 3216158 : && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1609 : 5085 : GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1610 : : {
1611 : 5085 : scalar_int_mode tmode;
1612 : 5085 : gcc_assert (GET_MODE_PRECISION (int_mode)
1613 : : > GET_MODE_PRECISION (op_mode));
1614 : 5085 : if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1615 : 7455 : - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1616 : : {
1617 : 2715 : rtx inner =
1618 : 2715 : rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1619 : 2715 : if (inner)
1620 : 2715 : return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
1621 : : ? SIGN_EXTEND : ZERO_EXTEND,
1622 : 2715 : 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 : 3208358 : if (GET_CODE (op) == LSHIFTRT
1629 : 201 : && CONST_INT_P (XEXP (op, 1))
1630 : 201 : && XEXP (op, 1) != const0_rtx)
1631 : 201 : 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 : 3208157 : if (GET_CODE (op) == TRUNCATE
1640 : 62 : && GET_CODE (XEXP (op, 0)) == LSHIFTRT
1641 : 0 : && CONST_INT_P (XEXP (XEXP (op, 0), 1)))
1642 : : {
1643 : 0 : scalar_int_mode m_mode, n_mode, o_mode;
1644 : 0 : rtx old_shift = XEXP (op, 0);
1645 : 0 : if (is_a <scalar_int_mode> (mode, &m_mode)
1646 : 0 : && is_a <scalar_int_mode> (GET_MODE (op), &n_mode)
1647 : 0 : && is_a <scalar_int_mode> (GET_MODE (old_shift), &o_mode)
1648 : 0 : && GET_MODE_PRECISION (o_mode) - GET_MODE_PRECISION (n_mode)
1649 : 0 : == INTVAL (XEXP (old_shift, 1)))
1650 : : {
1651 : 0 : rtx new_shift = simplify_gen_binary (ASHIFTRT,
1652 : : GET_MODE (old_shift),
1653 : : XEXP (old_shift, 0),
1654 : : XEXP (old_shift, 1));
1655 : 0 : if (GET_MODE_PRECISION (m_mode) > GET_MODE_PRECISION (o_mode))
1656 : 0 : return simplify_gen_unary (SIGN_EXTEND, mode, new_shift,
1657 : 0 : GET_MODE (new_shift));
1658 : 0 : if (mode != GET_MODE (new_shift))
1659 : 0 : return simplify_gen_unary (TRUNCATE, mode, new_shift,
1660 : 0 : GET_MODE (new_shift));
1661 : : return new_shift;
1662 : : }
1663 : : }
1664 : :
1665 : : /* We can canonicalize SIGN_EXTEND (op) as ZERO_EXTEND (op) when
1666 : : we know the sign bit of OP must be clear. */
1667 : 3208157 : if (val_signbit_known_clear_p (GET_MODE (op),
1668 : 3208157 : nonzero_bits (op, GET_MODE (op))))
1669 : 44167 : return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1670 : :
1671 : : /* (sign_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1672 : 3163990 : if (GET_CODE (op) == SUBREG
1673 : 164089 : && subreg_lowpart_p (op)
1674 : 163958 : && GET_MODE (SUBREG_REG (op)) == mode
1675 : 3300294 : && is_a <scalar_int_mode> (mode, &int_mode)
1676 : 143082 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1677 : 143082 : && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
1678 : 141275 : && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
1679 : 3305265 : && (nonzero_bits (SUBREG_REG (op), mode)
1680 : 141275 : & ~(GET_MODE_MASK (op_mode) >> 1)) == 0)
1681 : 6778 : return SUBREG_REG (op);
1682 : :
1683 : : #if defined(POINTERS_EXTEND_UNSIGNED)
1684 : : /* As we do not know which address space the pointer is referring to,
1685 : : we can do this only if the target does not support different pointer
1686 : : or address modes depending on the address space. */
1687 : 3157212 : 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 : 11947413 : case ZERO_EXTEND:
1708 : : /* Check for useless extension. */
1709 : 11947413 : if (GET_MODE (op) == mode)
1710 : : return op;
1711 : :
1712 : : /* (zero_extend:SI (and:QI X (const))) -> (and:SI (lowpart:SI X) const)
1713 : : where const does not sign bit set. */
1714 : 11947373 : if (GET_CODE (op) == AND
1715 : 132018 : && CONST_INT_P (XEXP (op, 1))
1716 : 105926 : && INTVAL (XEXP (op, 1)) > 0)
1717 : : {
1718 : 98960 : rtx tem = rtl_hooks.gen_lowpart_no_emit (mode, XEXP (op, 0));
1719 : 98960 : if (tem)
1720 : 82010 : return simplify_gen_binary (AND, mode, tem, XEXP (op, 1));
1721 : : }
1722 : :
1723 : : /* Check for a zero extension of a subreg of a promoted
1724 : : variable, where the promotion is zero-extended, and the
1725 : : target mode is the same as the variable's promotion. */
1726 : 11865363 : if (GET_CODE (op) == SUBREG
1727 : 1493466 : && SUBREG_PROMOTED_VAR_P (op)
1728 : 11865812 : && SUBREG_PROMOTED_UNSIGNED_P (op))
1729 : : {
1730 : 449 : rtx subreg = SUBREG_REG (op);
1731 : 449 : machine_mode subreg_mode = GET_MODE (subreg);
1732 : 449 : if (!paradoxical_subreg_p (mode, subreg_mode))
1733 : : {
1734 : 293 : temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
1735 : 293 : if (temp)
1736 : : {
1737 : : /* Preserve SUBREG_PROMOTED_VAR_P. */
1738 : 293 : if (partial_subreg_p (temp))
1739 : : {
1740 : 129 : SUBREG_PROMOTED_VAR_P (temp) = 1;
1741 : 129 : SUBREG_PROMOTED_SET (temp, SRP_UNSIGNED);
1742 : : }
1743 : 293 : return temp;
1744 : : }
1745 : : }
1746 : : else
1747 : : /* Zero-extending a zero-extended subreg. */
1748 : 156 : return simplify_gen_unary (ZERO_EXTEND, mode,
1749 : 156 : subreg, subreg_mode);
1750 : : }
1751 : :
1752 : : /* Extending a widening multiplication should be canonicalized to
1753 : : a wider widening multiplication. */
1754 : 11864914 : if (GET_CODE (op) == MULT)
1755 : : {
1756 : 178507 : rtx lhs = XEXP (op, 0);
1757 : 178507 : rtx rhs = XEXP (op, 1);
1758 : 178507 : enum rtx_code lcode = GET_CODE (lhs);
1759 : 178507 : enum rtx_code rcode = GET_CODE (rhs);
1760 : :
1761 : : /* Widening multiplies usually extend both operands, but sometimes
1762 : : they use a shift to extract a portion of a register. */
1763 : 178507 : if ((lcode == ZERO_EXTEND
1764 : 177771 : || (lcode == LSHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1765 : 784 : && (rcode == ZERO_EXTEND
1766 : 672 : || (rcode == LSHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1767 : : {
1768 : 112 : machine_mode lmode = GET_MODE (lhs);
1769 : 112 : machine_mode rmode = GET_MODE (rhs);
1770 : 112 : int bits;
1771 : :
1772 : 112 : if (lcode == LSHIFTRT)
1773 : : /* Number of bits not shifted off the end. */
1774 : 0 : bits = (GET_MODE_UNIT_PRECISION (lmode)
1775 : 0 : - INTVAL (XEXP (lhs, 1)));
1776 : : else /* lcode == ZERO_EXTEND */
1777 : : /* Size of inner mode. */
1778 : 224 : bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1779 : :
1780 : 112 : if (rcode == LSHIFTRT)
1781 : 0 : bits += (GET_MODE_UNIT_PRECISION (rmode)
1782 : 0 : - INTVAL (XEXP (rhs, 1)));
1783 : : else /* rcode == ZERO_EXTEND */
1784 : 224 : bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1785 : :
1786 : : /* We can only widen multiplies if the result is mathematiclly
1787 : : equivalent. I.e. if overflow was impossible. */
1788 : 224 : if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1789 : 112 : return simplify_gen_binary
1790 : 112 : (MULT, mode,
1791 : : simplify_gen_unary (ZERO_EXTEND, mode, lhs, lmode),
1792 : 112 : simplify_gen_unary (ZERO_EXTEND, mode, rhs, rmode));
1793 : : }
1794 : : }
1795 : :
1796 : : /* (zero_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1797 : 11864802 : if (GET_CODE (op) == ZERO_EXTEND)
1798 : 23908 : return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0),
1799 : 23908 : GET_MODE (XEXP (op, 0)));
1800 : :
1801 : : /* (zero_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1802 : : is (zero_extend:M (subreg:O <X>)) if there is mode with
1803 : : GET_MODE_PRECISION (N) - I bits. */
1804 : 11840894 : if (GET_CODE (op) == LSHIFTRT
1805 : 82048 : && GET_CODE (XEXP (op, 0)) == ASHIFT
1806 : 11840917 : && is_a <scalar_int_mode> (mode, &int_mode)
1807 : 23 : && CONST_INT_P (XEXP (op, 1))
1808 : 18 : && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1809 : 11840894 : && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1810 : 0 : GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1811 : : {
1812 : 0 : scalar_int_mode tmode;
1813 : 0 : if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1814 : 0 : - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1815 : : {
1816 : 0 : rtx inner =
1817 : 0 : rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1818 : 0 : if (inner)
1819 : 0 : return simplify_gen_unary (ZERO_EXTEND, int_mode,
1820 : 0 : inner, tmode);
1821 : : }
1822 : : }
1823 : :
1824 : : /* (zero_extend:M (subreg:N <X:O>)) is <X:O> (for M == O) or
1825 : : (zero_extend:M <X:O>), if X doesn't have any non-zero bits outside
1826 : : of mode N. E.g.
1827 : : (zero_extend:SI (subreg:QI (and:SI (reg:SI) (const_int 63)) 0)) is
1828 : : (and:SI (reg:SI) (const_int 63)). */
1829 : 11840894 : if (partial_subreg_p (op)
1830 : 13289072 : && is_a <scalar_int_mode> (mode, &int_mode)
1831 : 1474500 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &op0_mode)
1832 : 1473932 : && GET_MODE_PRECISION (op0_mode) <= HOST_BITS_PER_WIDE_INT
1833 : 1021371 : && GET_MODE_PRECISION (int_mode) >= GET_MODE_PRECISION (op0_mode)
1834 : 998344 : && subreg_lowpart_p (op)
1835 : 2178775 : && (nonzero_bits (SUBREG_REG (op), op0_mode)
1836 : 685758 : & ~GET_MODE_MASK (GET_MODE (op))) == 0)
1837 : : {
1838 : 26322 : if (GET_MODE_PRECISION (int_mode) == GET_MODE_PRECISION (op0_mode))
1839 : 16169 : return SUBREG_REG (op);
1840 : 10153 : return simplify_gen_unary (ZERO_EXTEND, int_mode, SUBREG_REG (op),
1841 : 10153 : op0_mode);
1842 : : }
1843 : :
1844 : : /* (zero_extend:DI (subreg:SI (ctz:DI ...))) is (ctz:DI ...). */
1845 : 11814572 : if (GET_CODE (op) == SUBREG
1846 : 1466695 : && subreg_lowpart_p (op)
1847 : 771271 : && GET_MODE (SUBREG_REG (op)) == mode
1848 : 12504416 : && is_a <scalar_int_mode> (mode, &int_mode)
1849 : 689844 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1850 : 689844 : && GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_WIDE_INT
1851 : 621004 : && GET_MODE_PRECISION (op_mode) < GET_MODE_PRECISION (int_mode)
1852 : 12435576 : && (nonzero_bits (SUBREG_REG (op), mode)
1853 : 621004 : & ~GET_MODE_MASK (op_mode)) == 0)
1854 : 0 : return SUBREG_REG (op);
1855 : :
1856 : : /* Trying to optimize:
1857 : : (zero_extend:M (subreg:N (not:M (X:M)))) ->
1858 : : (xor:M (zero_extend:M (subreg:N (X:M)), mask))
1859 : : where the mask is GET_MODE_MASK (N).
1860 : : For the cases when X:M doesn't have any non-zero bits
1861 : : outside of mode N, (zero_extend:M (subreg:N (X:M))
1862 : : will be simplified to just (X:M)
1863 : : and whole optimization will be -> (xor:M (X:M, mask)). */
1864 : 11814572 : if (partial_subreg_p (op)
1865 : 1448178 : && GET_CODE (XEXP (op, 0)) == NOT
1866 : 1854 : && GET_MODE (XEXP (op, 0)) == mode
1867 : 1851 : && subreg_lowpart_p (op)
1868 : 11814855 : && HWI_COMPUTABLE_MODE_P (mode)
1869 : 284 : && is_a <scalar_int_mode> (GET_MODE (op), &op_mode)
1870 : 1466979 : && (nonzero_bits (XEXP (XEXP (op, 0), 0), mode)
1871 : 284 : & ~GET_MODE_MASK (op_mode)) == 0)
1872 : : {
1873 : 1 : unsigned HOST_WIDE_INT mask = GET_MODE_MASK (op_mode);
1874 : 2 : return simplify_gen_binary (XOR, mode,
1875 : 1 : XEXP (XEXP (op, 0), 0),
1876 : 1 : gen_int_mode (mask, mode));
1877 : : }
1878 : :
1879 : : #if defined(POINTERS_EXTEND_UNSIGNED)
1880 : : /* As we do not know which address space the pointer is referring to,
1881 : : we can do this only if the target does not support different pointer
1882 : : or address modes depending on the address space. */
1883 : 11814571 : if (target_default_pointer_address_modes_p ()
1884 : : && POINTERS_EXTEND_UNSIGNED > 0
1885 : 13118156 : && mode == Pmode && GET_MODE (op) == ptr_mode
1886 : 677 : && (CONSTANT_P (op)
1887 : 656 : || (GET_CODE (op) == SUBREG
1888 : 0 : && REG_P (SUBREG_REG (op))
1889 : 0 : && REG_POINTER (SUBREG_REG (op))
1890 : 0 : && GET_MODE (SUBREG_REG (op)) == Pmode))
1891 : 11814592 : && !targetm.have_ptr_extend ())
1892 : : {
1893 : 21 : temp
1894 : 21 : = convert_memory_address_addr_space_1 (Pmode, op,
1895 : : ADDR_SPACE_GENERIC, false,
1896 : : true);
1897 : 21 : if (temp)
1898 : : return temp;
1899 : : }
1900 : : #endif
1901 : : break;
1902 : :
1903 : : default:
1904 : : break;
1905 : : }
1906 : :
1907 : 19619330 : if (VECTOR_MODE_P (mode)
1908 : 1466467 : && vec_duplicate_p (op, &elt)
1909 : 21091473 : && code != VEC_DUPLICATE)
1910 : : {
1911 : 5672 : if (code == SIGN_EXTEND || code == ZERO_EXTEND)
1912 : : /* Enforce a canonical order of VEC_DUPLICATE wrt other unary
1913 : : operations by promoting VEC_DUPLICATE to the root of the expression
1914 : : (as far as possible). */
1915 : 4605 : temp = simplify_gen_unary (code, GET_MODE_INNER (mode),
1916 : 9210 : elt, GET_MODE_INNER (GET_MODE (op)));
1917 : : else
1918 : : /* Try applying the operator to ELT and see if that simplifies.
1919 : : We can duplicate the result if so.
1920 : :
1921 : : The reason we traditionally haven't used simplify_gen_unary
1922 : : for these codes is that it didn't necessarily seem to be a
1923 : : win to convert things like:
1924 : :
1925 : : (neg:V (vec_duplicate:V (reg:S R)))
1926 : :
1927 : : to:
1928 : :
1929 : : (vec_duplicate:V (neg:S (reg:S R)))
1930 : :
1931 : : The first might be done entirely in vector registers while the
1932 : : second might need a move between register files.
1933 : :
1934 : : However, there also cases where promoting the vec_duplicate is
1935 : : more efficient, and there is definite value in having a canonical
1936 : : form when matching instruction patterns. We should consider
1937 : : extending the simplify_gen_unary code above to more cases. */
1938 : 1067 : temp = simplify_unary_operation (code, GET_MODE_INNER (mode),
1939 : 2134 : elt, GET_MODE_INNER (GET_MODE (op)));
1940 : 5672 : if (temp)
1941 : 5183 : return gen_vec_duplicate (mode, temp);
1942 : : }
1943 : :
1944 : : return 0;
1945 : : }
1946 : :
1947 : : /* Try to compute the value of a unary operation CODE whose output mode is to
1948 : : be MODE with input operand OP whose mode was originally OP_MODE.
1949 : : Return zero if the value cannot be computed. */
1950 : : rtx
1951 : 27905143 : simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
1952 : : rtx op, machine_mode op_mode)
1953 : : {
1954 : 27905143 : scalar_int_mode result_mode;
1955 : :
1956 : 27905143 : if (code == VEC_DUPLICATE)
1957 : : {
1958 : 1608111 : gcc_assert (VECTOR_MODE_P (mode));
1959 : 1608111 : if (GET_MODE (op) != VOIDmode)
1960 : : {
1961 : 532336 : if (!VECTOR_MODE_P (GET_MODE (op)))
1962 : 1051426 : gcc_assert (GET_MODE_INNER (mode) == GET_MODE (op));
1963 : : else
1964 : 19869 : gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER
1965 : : (GET_MODE (op)));
1966 : : }
1967 : 1608111 : if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op))
1968 : 1113609 : return gen_const_vec_duplicate (mode, op);
1969 : 494502 : if (GET_CODE (op) == CONST_VECTOR
1970 : 494502 : && (CONST_VECTOR_DUPLICATE_P (op)
1971 : : || CONST_VECTOR_NUNITS (op).is_constant ()))
1972 : : {
1973 : 755 : unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op)
1974 : 755 : ? CONST_VECTOR_NPATTERNS (op)
1975 : 1509 : : CONST_VECTOR_NUNITS (op).to_constant ());
1976 : 2265 : gcc_assert (multiple_p (GET_MODE_NUNITS (mode), npatterns));
1977 : 755 : rtx_vector_builder builder (mode, npatterns, 1);
1978 : 3130 : for (unsigned i = 0; i < npatterns; i++)
1979 : 2375 : builder.quick_push (CONST_VECTOR_ELT (op, i));
1980 : 755 : return builder.build ();
1981 : 755 : }
1982 : : }
1983 : :
1984 : 25604614 : if (VECTOR_MODE_P (mode)
1985 : 1504603 : && GET_CODE (op) == CONST_VECTOR
1986 : 26888264 : && known_eq (GET_MODE_NUNITS (mode), CONST_VECTOR_NUNITS (op)))
1987 : : {
1988 : 32495 : gcc_assert (GET_MODE (op) == op_mode);
1989 : :
1990 : 32495 : rtx_vector_builder builder;
1991 : 32495 : if (!builder.new_unary_operation (mode, op, false))
1992 : : return 0;
1993 : :
1994 : 32495 : unsigned int count = builder.encoded_nelts ();
1995 : 143523 : for (unsigned int i = 0; i < count; i++)
1996 : : {
1997 : 223094 : rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
1998 : : CONST_VECTOR_ELT (op, i),
1999 : 223094 : GET_MODE_INNER (op_mode));
2000 : 111547 : if (!x || !valid_for_const_vector_p (mode, x))
2001 : 519 : return 0;
2002 : 111028 : builder.quick_push (x);
2003 : : }
2004 : 31976 : return builder.build ();
2005 : 32495 : }
2006 : :
2007 : : /* The order of these tests is critical so that, for example, we don't
2008 : : check the wrong mode (input vs. output) for a conversion operation,
2009 : : such as FIX. At some point, this should be simplified. */
2010 : :
2011 : 26758284 : if (code == FLOAT && CONST_SCALAR_INT_P (op))
2012 : : {
2013 : 7120 : REAL_VALUE_TYPE d;
2014 : :
2015 : 7120 : if (op_mode == VOIDmode)
2016 : : {
2017 : : /* CONST_INT have VOIDmode as the mode. We assume that all
2018 : : the bits of the constant are significant, though, this is
2019 : : a dangerous assumption as many times CONST_INTs are
2020 : : created and used with garbage in the bits outside of the
2021 : : precision of the implied mode of the const_int. */
2022 : 63 : op_mode = MAX_MODE_INT;
2023 : : }
2024 : :
2025 : 7120 : real_from_integer (&d, mode, rtx_mode_t (op, op_mode), SIGNED);
2026 : :
2027 : : /* Avoid the folding if flag_signaling_nans is on and
2028 : : operand is a signaling NaN. */
2029 : 7120 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2030 : : return 0;
2031 : :
2032 : 7120 : d = real_value_truncate (mode, d);
2033 : :
2034 : : /* Avoid the folding if flag_rounding_math is on and the
2035 : : conversion is not exact. */
2036 : 7120 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2037 : : {
2038 : 1003 : bool fail = false;
2039 : 1003 : wide_int w = real_to_integer (&d, &fail,
2040 : : GET_MODE_PRECISION
2041 : 1003 : (as_a <scalar_int_mode> (op_mode)));
2042 : 2006 : if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
2043 : 897 : return 0;
2044 : 1003 : }
2045 : :
2046 : 6223 : return const_double_from_real_value (d, mode);
2047 : : }
2048 : 26751164 : else if (code == UNSIGNED_FLOAT && CONST_SCALAR_INT_P (op))
2049 : : {
2050 : 2139 : REAL_VALUE_TYPE d;
2051 : :
2052 : 2139 : if (op_mode == VOIDmode)
2053 : : {
2054 : : /* CONST_INT have VOIDmode as the mode. We assume that all
2055 : : the bits of the constant are significant, though, this is
2056 : : a dangerous assumption as many times CONST_INTs are
2057 : : created and used with garbage in the bits outside of the
2058 : : precision of the implied mode of the const_int. */
2059 : 8 : op_mode = MAX_MODE_INT;
2060 : : }
2061 : :
2062 : 2139 : real_from_integer (&d, mode, rtx_mode_t (op, op_mode), UNSIGNED);
2063 : :
2064 : : /* Avoid the folding if flag_signaling_nans is on and
2065 : : operand is a signaling NaN. */
2066 : 2139 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2067 : : return 0;
2068 : :
2069 : 2139 : d = real_value_truncate (mode, d);
2070 : :
2071 : : /* Avoid the folding if flag_rounding_math is on and the
2072 : : conversion is not exact. */
2073 : 2139 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2074 : : {
2075 : 16 : bool fail = false;
2076 : 16 : wide_int w = real_to_integer (&d, &fail,
2077 : : GET_MODE_PRECISION
2078 : 16 : (as_a <scalar_int_mode> (op_mode)));
2079 : 28 : if (fail || wi::ne_p (w, wide_int (rtx_mode_t (op, op_mode))))
2080 : 16 : return 0;
2081 : 16 : }
2082 : :
2083 : 2123 : return const_double_from_real_value (d, mode);
2084 : : }
2085 : :
2086 : 26749025 : if (CONST_SCALAR_INT_P (op) && is_a <scalar_int_mode> (mode, &result_mode))
2087 : : {
2088 : 3452540 : unsigned int width = GET_MODE_PRECISION (result_mode);
2089 : 3452540 : if (width > MAX_BITSIZE_MODE_ANY_INT)
2090 : : return 0;
2091 : :
2092 : 3452540 : wide_int result;
2093 : 3452540 : scalar_int_mode imode = (op_mode == VOIDmode
2094 : 3452540 : ? result_mode
2095 : 3452324 : : as_a <scalar_int_mode> (op_mode));
2096 : 3452540 : rtx_mode_t op0 = rtx_mode_t (op, imode);
2097 : 3452540 : int int_value;
2098 : :
2099 : : #if TARGET_SUPPORTS_WIDE_INT == 0
2100 : : /* This assert keeps the simplification from producing a result
2101 : : that cannot be represented in a CONST_DOUBLE but a lot of
2102 : : upstream callers expect that this function never fails to
2103 : : simplify something and so you if you added this to the test
2104 : : above the code would die later anyway. If this assert
2105 : : happens, you just need to make the port support wide int. */
2106 : : gcc_assert (width <= HOST_BITS_PER_DOUBLE_INT);
2107 : : #endif
2108 : :
2109 : 3452540 : switch (code)
2110 : : {
2111 : 182212 : case NOT:
2112 : 182212 : result = wi::bit_not (op0);
2113 : 182212 : break;
2114 : :
2115 : 1907348 : case NEG:
2116 : 1907348 : result = wi::neg (op0);
2117 : 1907348 : break;
2118 : :
2119 : 7294 : case ABS:
2120 : 7294 : result = wi::abs (op0);
2121 : 7294 : break;
2122 : :
2123 : 0 : case FFS:
2124 : 0 : result = wi::shwi (wi::ffs (op0), result_mode);
2125 : 0 : break;
2126 : :
2127 : 211 : case CLZ:
2128 : 211 : if (wi::ne_p (op0, 0))
2129 : 20 : int_value = wi::clz (op0);
2130 : 382 : else if (! CLZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2131 : : return NULL_RTX;
2132 : 20 : result = wi::shwi (int_value, result_mode);
2133 : 20 : break;
2134 : :
2135 : 0 : case CLRSB:
2136 : 0 : result = wi::shwi (wi::clrsb (op0), result_mode);
2137 : 0 : break;
2138 : :
2139 : 0 : case CTZ:
2140 : 0 : if (wi::ne_p (op0, 0))
2141 : 0 : int_value = wi::ctz (op0);
2142 : 0 : else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
2143 : : return NULL_RTX;
2144 : 0 : result = wi::shwi (int_value, result_mode);
2145 : 0 : break;
2146 : :
2147 : 160 : case POPCOUNT:
2148 : 160 : result = wi::shwi (wi::popcount (op0), result_mode);
2149 : 160 : break;
2150 : :
2151 : 0 : case PARITY:
2152 : 0 : result = wi::shwi (wi::parity (op0), result_mode);
2153 : 0 : break;
2154 : :
2155 : 2013 : case BSWAP:
2156 : 2013 : result = wi::bswap (op0);
2157 : 2013 : break;
2158 : :
2159 : 0 : case BITREVERSE:
2160 : 0 : result = wi::bitreverse (op0);
2161 : 0 : break;
2162 : :
2163 : 1188341 : case TRUNCATE:
2164 : 1188341 : case ZERO_EXTEND:
2165 : 1188341 : result = wide_int::from (op0, width, UNSIGNED);
2166 : 1188341 : break;
2167 : :
2168 : 14254 : case US_TRUNCATE:
2169 : 14254 : case SS_TRUNCATE:
2170 : 14254 : {
2171 : 14254 : signop sgn = code == US_TRUNCATE ? UNSIGNED : SIGNED;
2172 : 14254 : wide_int nmax
2173 : 14254 : = wide_int::from (wi::max_value (width, sgn),
2174 : 28508 : GET_MODE_PRECISION (imode), sgn);
2175 : 14254 : wide_int nmin
2176 : 14254 : = wide_int::from (wi::min_value (width, sgn),
2177 : 28508 : GET_MODE_PRECISION (imode), sgn);
2178 : 14254 : result = wi::min (wi::max (op0, nmin, sgn), nmax, sgn);
2179 : 14254 : result = wide_int::from (result, width, sgn);
2180 : 14254 : break;
2181 : 14254 : }
2182 : 150707 : case SIGN_EXTEND:
2183 : 150707 : result = wide_int::from (op0, width, SIGNED);
2184 : 150707 : break;
2185 : :
2186 : 0 : case SS_NEG:
2187 : 0 : if (wi::only_sign_bit_p (op0))
2188 : 0 : result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
2189 : : else
2190 : 0 : result = wi::neg (op0);
2191 : : break;
2192 : :
2193 : 0 : case SS_ABS:
2194 : 0 : if (wi::only_sign_bit_p (op0))
2195 : 0 : result = wi::max_value (GET_MODE_PRECISION (imode), SIGNED);
2196 : : else
2197 : 0 : result = wi::abs (op0);
2198 : : break;
2199 : :
2200 : : case SQRT:
2201 : : default:
2202 : : return 0;
2203 : : }
2204 : :
2205 : 3452349 : return immed_wide_int_const (result, result_mode);
2206 : 3452540 : }
2207 : :
2208 : 23296485 : else if (CONST_DOUBLE_AS_FLOAT_P (op)
2209 : 424884 : && SCALAR_FLOAT_MODE_P (mode)
2210 : 422886 : && SCALAR_FLOAT_MODE_P (GET_MODE (op)))
2211 : : {
2212 : 422886 : REAL_VALUE_TYPE d = *CONST_DOUBLE_REAL_VALUE (op);
2213 : 422886 : switch (code)
2214 : : {
2215 : : case SQRT:
2216 : : return 0;
2217 : 350 : case ABS:
2218 : 350 : d = real_value_abs (&d);
2219 : 350 : break;
2220 : 15656 : case NEG:
2221 : 15656 : d = real_value_negate (&d);
2222 : 15656 : break;
2223 : 2276 : case FLOAT_TRUNCATE:
2224 : : /* Don't perform the operation if flag_signaling_nans is on
2225 : : and the operand is a signaling NaN. */
2226 : 2276 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2227 : : return NULL_RTX;
2228 : : /* Or if flag_rounding_math is on and the truncation is not
2229 : : exact. */
2230 : 2276 : if (HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2231 : 2276 : && !exact_real_truncate (mode, &d))
2232 : 231 : return NULL_RTX;
2233 : 2045 : d = real_value_truncate (mode, d);
2234 : 2045 : break;
2235 : 398134 : case FLOAT_EXTEND:
2236 : : /* Don't perform the operation if flag_signaling_nans is on
2237 : : and the operand is a signaling NaN. */
2238 : 398134 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2239 : : return NULL_RTX;
2240 : : /* All this does is change the mode, unless changing
2241 : : mode class. */
2242 : 398132 : if (GET_MODE_CLASS (mode) != GET_MODE_CLASS (GET_MODE (op)))
2243 : 0 : real_convert (&d, mode, &d);
2244 : : break;
2245 : 0 : case FIX:
2246 : : /* Don't perform the operation if flag_signaling_nans is on
2247 : : and the operand is a signaling NaN. */
2248 : 0 : if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
2249 : : return NULL_RTX;
2250 : 0 : real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
2251 : 0 : break;
2252 : 5868 : case NOT:
2253 : 5868 : {
2254 : 5868 : long tmp[4];
2255 : 5868 : int i;
2256 : :
2257 : 5868 : real_to_target (tmp, &d, GET_MODE (op));
2258 : 29340 : for (i = 0; i < 4; i++)
2259 : 23472 : tmp[i] = ~tmp[i];
2260 : 5868 : real_from_target (&d, tmp, mode);
2261 : 5868 : break;
2262 : : }
2263 : 0 : default:
2264 : 0 : gcc_unreachable ();
2265 : : }
2266 : 422051 : return const_double_from_real_value (d, mode);
2267 : : }
2268 : 1998 : else if (CONST_DOUBLE_AS_FLOAT_P (op)
2269 : 1998 : && SCALAR_FLOAT_MODE_P (GET_MODE (op))
2270 : 22875597 : && is_int_mode (mode, &result_mode))
2271 : : {
2272 : 1998 : unsigned int width = GET_MODE_PRECISION (result_mode);
2273 : 1998 : if (width > MAX_BITSIZE_MODE_ANY_INT)
2274 : : return 0;
2275 : :
2276 : : /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
2277 : : operators are intentionally left unspecified (to ease implementation
2278 : : by target backends), for consistency, this routine implements the
2279 : : same semantics for constant folding as used by the middle-end. */
2280 : :
2281 : : /* This was formerly used only for non-IEEE float.
2282 : : eggert@twinsun.com says it is safe for IEEE also. */
2283 : 1998 : REAL_VALUE_TYPE t;
2284 : 1998 : const REAL_VALUE_TYPE *x = CONST_DOUBLE_REAL_VALUE (op);
2285 : 1998 : wide_int wmax, wmin;
2286 : : /* This is part of the abi to real_to_integer, but we check
2287 : : things before making this call. */
2288 : 1998 : bool fail;
2289 : :
2290 : 1998 : switch (code)
2291 : : {
2292 : 1990 : case FIX:
2293 : : /* According to IEEE standard, for conversions from floating point to
2294 : : integer. When a NaN or infinite operand cannot be represented in
2295 : : the destination format and this cannot otherwise be indicated, the
2296 : : invalid operation exception shall be signaled. When a numeric
2297 : : operand would convert to an integer outside the range of the
2298 : : destination format, the invalid operation exception shall be
2299 : : signaled if this situation cannot otherwise be indicated. */
2300 : 1990 : if (REAL_VALUE_ISNAN (*x))
2301 : 941 : return flag_trapping_math ? NULL_RTX : const0_rtx;
2302 : :
2303 : 1049 : if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
2304 : : return NULL_RTX;
2305 : :
2306 : : /* Test against the signed upper bound. */
2307 : 103 : wmax = wi::max_value (width, SIGNED);
2308 : 103 : real_from_integer (&t, VOIDmode, wmax, SIGNED);
2309 : 103 : if (real_less (&t, x))
2310 : 3 : return (flag_trapping_math
2311 : 3 : ? NULL_RTX : immed_wide_int_const (wmax, mode));
2312 : :
2313 : : /* Test against the signed lower bound. */
2314 : 100 : wmin = wi::min_value (width, SIGNED);
2315 : 100 : real_from_integer (&t, VOIDmode, wmin, SIGNED);
2316 : 100 : if (real_less (x, &t))
2317 : 8 : return immed_wide_int_const (wmin, mode);
2318 : :
2319 : 92 : return immed_wide_int_const (real_to_integer (x, &fail, width),
2320 : : mode);
2321 : :
2322 : 8 : case UNSIGNED_FIX:
2323 : 8 : if (REAL_VALUE_ISNAN (*x) || REAL_VALUE_NEGATIVE (*x))
2324 : 6 : return flag_trapping_math ? NULL_RTX : const0_rtx;
2325 : :
2326 : 2 : if (REAL_VALUE_ISINF (*x) && flag_trapping_math)
2327 : : return NULL_RTX;
2328 : :
2329 : : /* Test against the unsigned upper bound. */
2330 : 0 : wmax = wi::max_value (width, UNSIGNED);
2331 : 0 : real_from_integer (&t, VOIDmode, wmax, UNSIGNED);
2332 : 0 : if (real_less (&t, x))
2333 : 0 : return (flag_trapping_math
2334 : 0 : ? NULL_RTX : immed_wide_int_const (wmax, mode));
2335 : :
2336 : 0 : return immed_wide_int_const (real_to_integer (x, &fail, width),
2337 : : mode);
2338 : :
2339 : 0 : default:
2340 : 0 : gcc_unreachable ();
2341 : : }
2342 : 1998 : }
2343 : :
2344 : : /* Handle polynomial integers. */
2345 : : else if (CONST_POLY_INT_P (op))
2346 : : {
2347 : : poly_wide_int result;
2348 : : switch (code)
2349 : : {
2350 : : case NEG:
2351 : : result = -const_poly_int_value (op);
2352 : : break;
2353 : :
2354 : : case NOT:
2355 : : result = ~const_poly_int_value (op);
2356 : : break;
2357 : :
2358 : : default:
2359 : : return NULL_RTX;
2360 : : }
2361 : : return immed_wide_int_const (result, mode);
2362 : : }
2363 : :
2364 : : return NULL_RTX;
2365 : : }
2366 : :
2367 : : /* Subroutine of simplify_binary_operation to simplify a binary operation
2368 : : CODE that can commute with byte swapping, with result mode MODE and
2369 : : operating on OP0 and OP1. CODE is currently one of AND, IOR or XOR.
2370 : : Return zero if no simplification or canonicalization is possible. */
2371 : :
2372 : : rtx
2373 : 40319474 : simplify_context::simplify_byte_swapping_operation (rtx_code code,
2374 : : machine_mode mode,
2375 : : rtx op0, rtx op1)
2376 : : {
2377 : 40319474 : rtx tem;
2378 : :
2379 : : /* (op (bswap x) C1)) -> (bswap (op x C2)) with C2 swapped. */
2380 : 40319474 : if (GET_CODE (op0) == BSWAP && CONST_SCALAR_INT_P (op1))
2381 : : {
2382 : 503 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0),
2383 : : simplify_gen_unary (BSWAP, mode, op1, mode));
2384 : 503 : return simplify_gen_unary (BSWAP, mode, tem, mode);
2385 : : }
2386 : :
2387 : : /* (op (bswap x) (bswap y)) -> (bswap (op x y)). */
2388 : 40318971 : if (GET_CODE (op0) == BSWAP && GET_CODE (op1) == BSWAP)
2389 : : {
2390 : 0 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0), XEXP (op1, 0));
2391 : 0 : return simplify_gen_unary (BSWAP, mode, tem, mode);
2392 : : }
2393 : :
2394 : : return NULL_RTX;
2395 : : }
2396 : :
2397 : : /* Subroutine of simplify_binary_operation to simplify a commutative,
2398 : : associative binary operation CODE with result mode MODE, operating
2399 : : on OP0 and OP1. CODE is currently one of PLUS, MULT, AND, IOR, XOR,
2400 : : SMIN, SMAX, UMIN or UMAX. Return zero if no simplification or
2401 : : canonicalization is possible. */
2402 : :
2403 : : rtx
2404 : 49984736 : simplify_context::simplify_associative_operation (rtx_code code,
2405 : : machine_mode mode,
2406 : : rtx op0, rtx op1)
2407 : : {
2408 : 49984736 : rtx tem;
2409 : :
2410 : : /* Normally expressions simplified by simplify-rtx.cc are combined
2411 : : at most from a few machine instructions and therefore the
2412 : : expressions should be fairly small. During var-tracking
2413 : : we can see arbitrarily large expressions though and reassociating
2414 : : those can be quadratic, so punt after encountering max_assoc_count
2415 : : simplify_associative_operation calls during outermost simplify_*
2416 : : call. */
2417 : 49984736 : if (++assoc_count >= max_assoc_count)
2418 : : return NULL_RTX;
2419 : :
2420 : : /* Linearize the operator to the left. */
2421 : 49977435 : if (GET_CODE (op1) == code)
2422 : : {
2423 : : /* "(a op b) op (c op d)" becomes "((a op b) op c) op d)". */
2424 : 25142 : if (GET_CODE (op0) == code)
2425 : : {
2426 : 5273 : tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
2427 : 5273 : return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
2428 : : }
2429 : :
2430 : : /* "a op (b op c)" becomes "(b op c) op a". */
2431 : 19869 : if (! swap_commutative_operands_p (op1, op0))
2432 : 19869 : return simplify_gen_binary (code, mode, op1, op0);
2433 : :
2434 : : std::swap (op0, op1);
2435 : : }
2436 : :
2437 : 49952293 : if (GET_CODE (op0) == code)
2438 : : {
2439 : : /* Canonicalize "(x op c) op y" as "(x op y) op c". */
2440 : 1625522 : if (swap_commutative_operands_p (XEXP (op0, 1), op1))
2441 : : {
2442 : 350137 : tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
2443 : 350137 : return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2444 : : }
2445 : :
2446 : : /* Attempt to simplify "(a op b) op c" as "a op (b op c)". */
2447 : 1275385 : tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
2448 : 1275385 : if (tem != 0)
2449 : 95728 : return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
2450 : :
2451 : : /* Attempt to simplify "(a op b) op c" as "(a op c) op b". */
2452 : 1179657 : tem = simplify_binary_operation (code, mode, XEXP (op0, 0), op1);
2453 : 1179657 : if (tem != 0)
2454 : 58283 : return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2455 : : }
2456 : :
2457 : : return 0;
2458 : : }
2459 : :
2460 : : /* If COMPARISON can be treated as an unsigned comparison, return a mask
2461 : : that represents it (8 if it includes <, 4 if it includes > and 2
2462 : : if it includes ==). Return 0 otherwise. */
2463 : : static int
2464 : 18624 : unsigned_comparison_to_mask (rtx_code comparison)
2465 : : {
2466 : 0 : switch (comparison)
2467 : : {
2468 : : case LTU:
2469 : : return 8;
2470 : : case GTU:
2471 : : return 4;
2472 : : case EQ:
2473 : : return 2;
2474 : :
2475 : : case LEU:
2476 : : return 10;
2477 : : case GEU:
2478 : : return 6;
2479 : :
2480 : : case NE:
2481 : : return 12;
2482 : :
2483 : : default:
2484 : : return 0;
2485 : : }
2486 : : }
2487 : :
2488 : : /* Reverse the mapping in unsigned_comparison_to_mask, going from masks
2489 : : to comparisons. */
2490 : : static rtx_code
2491 : 6475 : mask_to_unsigned_comparison (int mask)
2492 : : {
2493 : 6475 : switch (mask)
2494 : : {
2495 : : case 8:
2496 : : return LTU;
2497 : 160 : case 4:
2498 : 160 : return GTU;
2499 : 2467 : case 2:
2500 : 2467 : return EQ;
2501 : :
2502 : 160 : case 10:
2503 : 160 : return LEU;
2504 : 160 : case 6:
2505 : 160 : return GEU;
2506 : :
2507 : 3368 : case 12:
2508 : 3368 : return NE;
2509 : :
2510 : 0 : default:
2511 : 0 : gcc_unreachable ();
2512 : : }
2513 : : }
2514 : :
2515 : : /* Return a mask describing the COMPARISON. */
2516 : : static int
2517 : 2666 : comparison_to_mask (enum rtx_code comparison)
2518 : : {
2519 : 2666 : switch (comparison)
2520 : : {
2521 : : case LT:
2522 : : return 8;
2523 : 472 : case GT:
2524 : 472 : return 4;
2525 : 419 : case EQ:
2526 : 419 : return 2;
2527 : 19 : case UNORDERED:
2528 : 19 : return 1;
2529 : :
2530 : 0 : case LTGT:
2531 : 0 : return 12;
2532 : 441 : case LE:
2533 : 441 : return 10;
2534 : 441 : case GE:
2535 : 441 : return 6;
2536 : 0 : case UNLT:
2537 : 0 : return 9;
2538 : 0 : case UNGT:
2539 : 0 : return 5;
2540 : 0 : case UNEQ:
2541 : 0 : return 3;
2542 : :
2543 : 0 : case ORDERED:
2544 : 0 : return 14;
2545 : 400 : case NE:
2546 : 400 : return 13;
2547 : 0 : case UNLE:
2548 : 0 : return 11;
2549 : 0 : case UNGE:
2550 : 0 : return 7;
2551 : :
2552 : 0 : default:
2553 : 0 : gcc_unreachable ();
2554 : : }
2555 : : }
2556 : :
2557 : : /* Return a comparison corresponding to the MASK. */
2558 : : static enum rtx_code
2559 : 1014 : mask_to_comparison (int mask)
2560 : : {
2561 : 1014 : switch (mask)
2562 : : {
2563 : : case 8:
2564 : : return LT;
2565 : : case 4:
2566 : : return GT;
2567 : : case 2:
2568 : : return EQ;
2569 : : case 1:
2570 : : return UNORDERED;
2571 : :
2572 : : case 12:
2573 : : return LTGT;
2574 : : case 10:
2575 : : return LE;
2576 : : case 6:
2577 : : return GE;
2578 : : case 9:
2579 : : return UNLT;
2580 : : case 5:
2581 : : return UNGT;
2582 : : case 3:
2583 : : return UNEQ;
2584 : :
2585 : : case 14:
2586 : : return ORDERED;
2587 : : case 13:
2588 : : return NE;
2589 : : case 11:
2590 : : return UNLE;
2591 : : case 7:
2592 : : return UNGE;
2593 : :
2594 : 0 : default:
2595 : 0 : gcc_unreachable ();
2596 : : }
2597 : : }
2598 : :
2599 : : /* Canonicalize RES, a scalar const0_rtx/const_true_rtx to the right
2600 : : false/true value of comparison with MODE where comparison operands
2601 : : have CMP_MODE. */
2602 : :
2603 : : static rtx
2604 : 857602 : relational_result (machine_mode mode, machine_mode cmp_mode, rtx res)
2605 : : {
2606 : 857602 : if (SCALAR_FLOAT_MODE_P (mode))
2607 : : {
2608 : 202 : if (res == const0_rtx)
2609 : 198 : return CONST0_RTX (mode);
2610 : : #ifdef FLOAT_STORE_FLAG_VALUE
2611 : : REAL_VALUE_TYPE val = FLOAT_STORE_FLAG_VALUE (mode);
2612 : : return const_double_from_real_value (val, mode);
2613 : : #else
2614 : : return NULL_RTX;
2615 : : #endif
2616 : : }
2617 : 857400 : if (VECTOR_MODE_P (mode))
2618 : : {
2619 : 350 : if (res == const0_rtx)
2620 : 51 : return CONST0_RTX (mode);
2621 : : #ifdef VECTOR_STORE_FLAG_VALUE
2622 : 299 : rtx val = VECTOR_STORE_FLAG_VALUE (mode);
2623 : 299 : if (val == NULL_RTX)
2624 : : return NULL_RTX;
2625 : 299 : if (val == const1_rtx)
2626 : 0 : return CONST1_RTX (mode);
2627 : :
2628 : 299 : return gen_const_vec_duplicate (mode, val);
2629 : : #else
2630 : : return NULL_RTX;
2631 : : #endif
2632 : : }
2633 : : /* For vector comparison with scalar int result, it is unknown
2634 : : if the target means here a comparison into an integral bitmask,
2635 : : or comparison where all comparisons true mean const_true_rtx
2636 : : whole result, or where any comparisons true mean const_true_rtx
2637 : : whole result. For const0_rtx all the cases are the same. */
2638 : 857050 : if (VECTOR_MODE_P (cmp_mode)
2639 : 0 : && SCALAR_INT_MODE_P (mode)
2640 : 0 : && res == const_true_rtx)
2641 : 0 : return NULL_RTX;
2642 : :
2643 : : return res;
2644 : : }
2645 : :
2646 : : /* Simplify a logical operation CODE with result mode MODE, operating on OP0
2647 : : and OP1, in the case where both are relational operations. Assume that
2648 : : OP0 is inverted if INVERT0_P is true.
2649 : :
2650 : : Return 0 if no such simplification is possible. */
2651 : : rtx
2652 : 15393526 : simplify_context::simplify_logical_relational_operation (rtx_code code,
2653 : : machine_mode mode,
2654 : : rtx op0, rtx op1,
2655 : : bool invert0_p)
2656 : : {
2657 : 15393526 : if (!(COMPARISON_P (op0) && COMPARISON_P (op1)))
2658 : : return 0;
2659 : :
2660 : 21529 : if (!(rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2661 : 9807 : && rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))))
2662 : 2410 : return 0;
2663 : :
2664 : 9312 : if (side_effects_p (op0))
2665 : : return 0;
2666 : :
2667 : 9312 : enum rtx_code code0 = GET_CODE (op0);
2668 : 9312 : enum rtx_code code1 = GET_CODE (op1);
2669 : 9312 : machine_mode cmp_mode = GET_MODE (XEXP (op0, 0));
2670 : 9312 : if (cmp_mode == VOIDmode)
2671 : 0 : cmp_mode = GET_MODE (XEXP (op0, 1));
2672 : :
2673 : : /* Assume at first that the comparisons are on integers, and that the
2674 : : operands are therefore ordered. */
2675 : 9312 : int all = 14;
2676 : 9312 : int mask0 = unsigned_comparison_to_mask (code0);
2677 : 9312 : int mask1 = unsigned_comparison_to_mask (code1);
2678 : 18624 : bool unsigned_p = (IN_RANGE (mask0 & 12, 4, 8)
2679 : 9312 : || IN_RANGE (mask1 & 12, 4, 8));
2680 : 1333 : if (unsigned_p)
2681 : : {
2682 : : /* We only reach here when comparing integers. Reject mixtures of signed
2683 : : and unsigned comparisons. */
2684 : 7979 : if (mask0 == 0 || mask1 == 0)
2685 : : return 0;
2686 : : }
2687 : : else
2688 : : {
2689 : : /* See whether the operands might be unordered. Assume that all
2690 : : results are possible for CC modes, and punt later if we don't get an
2691 : : always-true or always-false answer. */
2692 : 1333 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC || HONOR_NANS (cmp_mode))
2693 : : all = 15;
2694 : 1333 : mask0 = comparison_to_mask (code0) & all;
2695 : 1333 : mask1 = comparison_to_mask (code1) & all;
2696 : : }
2697 : :
2698 : 8032 : if (invert0_p)
2699 : 4535 : mask0 = mask0 ^ all;
2700 : :
2701 : 8032 : int mask;
2702 : 8032 : if (code == AND)
2703 : 960 : mask = mask0 & mask1;
2704 : 7072 : else if (code == IOR)
2705 : 948 : mask = mask0 | mask1;
2706 : 6124 : else if (code == XOR)
2707 : 6124 : mask = mask0 ^ mask1;
2708 : : else
2709 : : return 0;
2710 : :
2711 : 8032 : if (mask == all)
2712 : 232 : return relational_result (mode, GET_MODE (op0), const_true_rtx);
2713 : :
2714 : 7800 : if (mask == 0)
2715 : 232 : return relational_result (mode, GET_MODE (op0), const0_rtx);
2716 : :
2717 : 7568 : if (unsigned_p)
2718 : 6475 : code = mask_to_unsigned_comparison (mask);
2719 : : else
2720 : : {
2721 : 1093 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
2722 : : return 0;
2723 : :
2724 : 1014 : code = mask_to_comparison (mask);
2725 : : /* LTGT and NE are arithmetically equivalent for ordered operands,
2726 : : with NE being the canonical choice. */
2727 : 1014 : if (code == LTGT && all == 14)
2728 : 184 : code = NE;
2729 : : }
2730 : :
2731 : 7489 : op0 = XEXP (op1, 0);
2732 : 7489 : op1 = XEXP (op1, 1);
2733 : :
2734 : 7489 : return simplify_gen_relational (code, mode, VOIDmode, op0, op1);
2735 : : }
2736 : :
2737 : : /* Simplify a binary operation CODE with result mode MODE, operating on OP0
2738 : : and OP1. Return 0 if no simplification is possible.
2739 : :
2740 : : Don't use this for relational operations such as EQ or LT.
2741 : : Use simplify_relational_operation instead. */
2742 : : rtx
2743 : 478361736 : simplify_context::simplify_binary_operation (rtx_code code, machine_mode mode,
2744 : : rtx op0, rtx op1)
2745 : : {
2746 : 478361736 : rtx trueop0, trueop1;
2747 : 478361736 : rtx tem;
2748 : :
2749 : : /* Relational operations don't work here. We must know the mode
2750 : : of the operands in order to do the comparison correctly.
2751 : : Assuming a full word can give incorrect results.
2752 : : Consider comparing 128 with -128 in QImode. */
2753 : 478361736 : gcc_assert (GET_RTX_CLASS (code) != RTX_COMPARE);
2754 : 478361736 : gcc_assert (GET_RTX_CLASS (code) != RTX_COMM_COMPARE);
2755 : :
2756 : : /* Make sure the constant is second. */
2757 : 478361736 : if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
2758 : 478361736 : && swap_commutative_operands_p (op0, op1))
2759 : : std::swap (op0, op1);
2760 : :
2761 : 478361736 : trueop0 = avoid_constant_pool_reference (op0);
2762 : 478361736 : trueop1 = avoid_constant_pool_reference (op1);
2763 : :
2764 : 478361736 : tem = simplify_const_binary_operation (code, mode, trueop0, trueop1);
2765 : 478361736 : if (tem)
2766 : : return tem;
2767 : 447932783 : tem = simplify_binary_operation_1 (code, mode, op0, op1, trueop0, trueop1);
2768 : :
2769 : 447932783 : if (tem)
2770 : : return tem;
2771 : :
2772 : : /* If the above steps did not result in a simplification and op0 or op1
2773 : : were constant pool references, use the referenced constants directly. */
2774 : 385027142 : if (trueop0 != op0 || trueop1 != op1)
2775 : 579952 : return simplify_gen_binary (code, mode, trueop0, trueop1);
2776 : :
2777 : : return NULL_RTX;
2778 : : }
2779 : :
2780 : : /* Subroutine of simplify_binary_operation_1 that looks for cases in
2781 : : which OP0 and OP1 are both vector series or vector duplicates
2782 : : (which are really just series with a step of 0). If so, try to
2783 : : form a new series by applying CODE to the bases and to the steps.
2784 : : Return null if no simplification is possible.
2785 : :
2786 : : MODE is the mode of the operation and is known to be a vector
2787 : : integer mode. */
2788 : :
2789 : : rtx
2790 : 2310117 : simplify_context::simplify_binary_operation_series (rtx_code code,
2791 : : machine_mode mode,
2792 : : rtx op0, rtx op1)
2793 : : {
2794 : 2310117 : rtx base0, step0;
2795 : 2310117 : if (vec_duplicate_p (op0, &base0))
2796 : 66676 : step0 = const0_rtx;
2797 : 2243441 : else if (!vec_series_p (op0, &base0, &step0))
2798 : : return NULL_RTX;
2799 : :
2800 : 67168 : rtx base1, step1;
2801 : 67168 : if (vec_duplicate_p (op1, &base1))
2802 : 403 : step1 = const0_rtx;
2803 : 66765 : else if (!vec_series_p (op1, &base1, &step1))
2804 : : return NULL_RTX;
2805 : :
2806 : : /* Only create a new series if we can simplify both parts. In other
2807 : : cases this isn't really a simplification, and it's not necessarily
2808 : : a win to replace a vector operation with a scalar operation. */
2809 : 3397 : scalar_mode inner_mode = GET_MODE_INNER (mode);
2810 : 3397 : rtx new_base = simplify_binary_operation (code, inner_mode, base0, base1);
2811 : 3397 : if (!new_base)
2812 : : return NULL_RTX;
2813 : :
2814 : 3099 : rtx new_step = simplify_binary_operation (code, inner_mode, step0, step1);
2815 : 3099 : if (!new_step)
2816 : : return NULL_RTX;
2817 : :
2818 : 3099 : return gen_vec_series (mode, new_base, new_step);
2819 : : }
2820 : :
2821 : : /* Subroutine of simplify_binary_operation_1. Un-distribute a binary
2822 : : operation CODE with result mode MODE, operating on OP0 and OP1.
2823 : : e.g. simplify (xor (and A C) (and (B C)) to (and (xor (A B) C).
2824 : : Returns NULL_RTX if no simplification is possible. */
2825 : :
2826 : : rtx
2827 : 1519212 : simplify_context::simplify_distributive_operation (rtx_code code,
2828 : : machine_mode mode,
2829 : : rtx op0, rtx op1)
2830 : : {
2831 : 1519212 : enum rtx_code op = GET_CODE (op0);
2832 : 1519212 : gcc_assert (GET_CODE (op1) == op);
2833 : :
2834 : 1519212 : if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))
2835 : 1519212 : && ! side_effects_p (XEXP (op0, 1)))
2836 : 318549 : return simplify_gen_binary (op, mode,
2837 : : simplify_gen_binary (code, mode,
2838 : : XEXP (op0, 0),
2839 : : XEXP (op1, 0)),
2840 : 318549 : XEXP (op0, 1));
2841 : :
2842 : 1200663 : if (GET_RTX_CLASS (op) == RTX_COMM_ARITH)
2843 : : {
2844 : 1173222 : if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2845 : 1173222 : && ! side_effects_p (XEXP (op0, 0)))
2846 : 532743 : return simplify_gen_binary (op, mode,
2847 : : simplify_gen_binary (code, mode,
2848 : : XEXP (op0, 1),
2849 : : XEXP (op1, 1)),
2850 : 532743 : XEXP (op0, 0));
2851 : 640479 : if (rtx_equal_p (XEXP (op0, 0), XEXP (op1, 1))
2852 : 640479 : && ! side_effects_p (XEXP (op0, 0)))
2853 : 52 : return simplify_gen_binary (op, mode,
2854 : : simplify_gen_binary (code, mode,
2855 : : XEXP (op0, 1),
2856 : : XEXP (op1, 0)),
2857 : 52 : XEXP (op0, 0));
2858 : 640427 : if (rtx_equal_p (XEXP (op0, 1), XEXP (op1, 0))
2859 : 640427 : && ! side_effects_p (XEXP (op0, 1)))
2860 : 339234 : return simplify_gen_binary (op, mode,
2861 : : simplify_gen_binary (code, mode,
2862 : : XEXP (op0, 0),
2863 : : XEXP (op1, 1)),
2864 : 339234 : XEXP (op0, 1));
2865 : : }
2866 : :
2867 : : return NULL_RTX;
2868 : : }
2869 : :
2870 : : /* Return TRUE if a rotate in mode MODE with a constant count in OP1
2871 : : should be reversed.
2872 : :
2873 : : If the rotate should not be reversed, return FALSE.
2874 : :
2875 : : LEFT indicates if this is a rotate left or a rotate right. */
2876 : :
2877 : : bool
2878 : 142824 : reverse_rotate_by_imm_p (machine_mode mode, unsigned int left, rtx op1)
2879 : : {
2880 : 142824 : if (!CONST_INT_P (op1))
2881 : : return false;
2882 : :
2883 : : /* Some targets may only be able to rotate by a constant
2884 : : in one direction. So we need to query the optab interface
2885 : : to see what is possible. */
2886 : 111135 : optab binoptab = left ? rotl_optab : rotr_optab;
2887 : 46452 : optab re_binoptab = left ? rotr_optab : rotl_optab;
2888 : 111135 : enum insn_code icode = optab_handler (binoptab, mode);
2889 : 111135 : enum insn_code re_icode = optab_handler (re_binoptab, mode);
2890 : :
2891 : : /* If the target can not support the reversed optab, then there
2892 : : is nothing to do. */
2893 : 111135 : if (re_icode == CODE_FOR_nothing)
2894 : : return false;
2895 : :
2896 : : /* If the target does not support the requested rotate-by-immediate,
2897 : : then we want to try reversing the rotate. We also want to try
2898 : : reversing to minimize the count. */
2899 : 108635 : if ((icode == CODE_FOR_nothing)
2900 : 108635 : || (!insn_operand_matches (icode, 2, op1))
2901 : 543175 : || (IN_RANGE (INTVAL (op1),
2902 : : GET_MODE_UNIT_PRECISION (mode) / 2 + left,
2903 : : GET_MODE_UNIT_PRECISION (mode) - 1)))
2904 : 14156 : return (insn_operand_matches (re_icode, 2, op1));
2905 : : return false;
2906 : : }
2907 : :
2908 : : /* Analyse argument X to see if it represents an (ASHIFT X Y) operation
2909 : : and return the expression to be shifted in SHIFT_OPND and the shift amount
2910 : : in SHIFT_AMNT. This is primarily used to group handling of ASHIFT (X, CST)
2911 : : and (PLUS (X, X)) in one place. If the expression is not equivalent to an
2912 : : ASHIFT then return FALSE and set SHIFT_OPND and SHIFT_AMNT to NULL. */
2913 : :
2914 : : static bool
2915 : 529257830 : extract_ashift_operands_p (rtx x, rtx *shift_opnd, rtx *shift_amnt)
2916 : : {
2917 : 529257830 : if (GET_CODE (x) == ASHIFT)
2918 : : {
2919 : 13770938 : *shift_opnd = XEXP (x, 0);
2920 : 13770938 : *shift_amnt = XEXP (x, 1);
2921 : 13770938 : return true;
2922 : : }
2923 : 515486892 : if (GET_CODE (x) == PLUS && rtx_equal_p (XEXP (x, 0), XEXP (x, 1)))
2924 : : {
2925 : 12621 : *shift_opnd = XEXP (x, 0);
2926 : 12621 : *shift_amnt = CONST1_RTX (GET_MODE (x));
2927 : 12621 : return true;
2928 : : }
2929 : 515474271 : *shift_opnd = NULL_RTX;
2930 : 515474271 : *shift_amnt = NULL_RTX;
2931 : 515474271 : return false;
2932 : : }
2933 : :
2934 : : /* OP0 and OP1 are combined under an operation of mode MODE that can
2935 : : potentially result in a ROTATE expression. Analyze the OP0 and OP1
2936 : : and return the resulting ROTATE expression if so. Return NULL otherwise.
2937 : : This is used in detecting the patterns (X << C1) [+,|,^] (X >> C2) where
2938 : : C1 + C2 == GET_MODE_UNIT_PRECISION (mode).
2939 : : (X << C1) and (C >> C2) would be OP0 and OP1. */
2940 : :
2941 : : static rtx
2942 : 266812276 : simplify_rotate_op (rtx op0, rtx op1, machine_mode mode)
2943 : : {
2944 : : /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
2945 : : mode size to (rotate A CX). */
2946 : :
2947 : 266812276 : rtx opleft = op0;
2948 : 266812276 : rtx opright = op1;
2949 : 266812276 : rtx ashift_opnd, ashift_amnt;
2950 : : /* In some cases the ASHIFT is not a direct ASHIFT. Look deeper and extract
2951 : : the relevant operands here. */
2952 : 266812276 : bool ashift_op_p
2953 : 266812276 : = extract_ashift_operands_p (op1, &ashift_opnd, &ashift_amnt);
2954 : :
2955 : 266812276 : if (ashift_op_p
2956 : 265072208 : || GET_CODE (op1) == SUBREG)
2957 : : {
2958 : : opleft = op1;
2959 : : opright = op0;
2960 : : }
2961 : : else
2962 : : {
2963 : 262445554 : opright = op1;
2964 : 262445554 : opleft = op0;
2965 : 262445554 : ashift_op_p
2966 : 262445554 : = extract_ashift_operands_p (opleft, &ashift_opnd, &ashift_amnt);
2967 : : }
2968 : :
2969 : 13783559 : if (ashift_op_p && GET_CODE (opright) == LSHIFTRT
2970 : 265115016 : && rtx_equal_p (ashift_opnd, XEXP (opright, 0)))
2971 : : {
2972 : 9781 : rtx leftcst = unwrap_const_vec_duplicate (ashift_amnt);
2973 : 9781 : rtx rightcst = unwrap_const_vec_duplicate (XEXP (opright, 1));
2974 : :
2975 : 5963 : if (CONST_INT_P (leftcst) && CONST_INT_P (rightcst)
2976 : 15744 : && (INTVAL (leftcst) + INTVAL (rightcst)
2977 : 5963 : == GET_MODE_UNIT_PRECISION (mode)))
2978 : 5358 : return gen_rtx_ROTATE (mode, XEXP (opright, 0), ashift_amnt);
2979 : : }
2980 : :
2981 : : /* Same, but for ashift that has been "simplified" to a wider mode
2982 : : by simplify_shift_const. */
2983 : 266806918 : scalar_int_mode int_mode, inner_mode;
2984 : :
2985 : 266806918 : if (GET_CODE (opleft) == SUBREG
2986 : 270578217 : && is_a <scalar_int_mode> (mode, &int_mode)
2987 : 3765941 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (opleft)),
2988 : : &inner_mode)
2989 : 3735663 : && GET_CODE (SUBREG_REG (opleft)) == ASHIFT
2990 : 107913 : && GET_CODE (opright) == LSHIFTRT
2991 : 1098 : && GET_CODE (XEXP (opright, 0)) == SUBREG
2992 : 251 : && known_eq (SUBREG_BYTE (opleft), SUBREG_BYTE (XEXP (opright, 0)))
2993 : 498 : && GET_MODE_SIZE (int_mode) < GET_MODE_SIZE (inner_mode)
2994 : 235 : && rtx_equal_p (XEXP (SUBREG_REG (opleft), 0),
2995 : 235 : SUBREG_REG (XEXP (opright, 0)))
2996 : 19 : && CONST_INT_P (XEXP (SUBREG_REG (opleft), 1))
2997 : 19 : && CONST_INT_P (XEXP (opright, 1))
2998 : 266806918 : && (INTVAL (XEXP (SUBREG_REG (opleft), 1))
2999 : 19 : + INTVAL (XEXP (opright, 1))
3000 : 19 : == GET_MODE_PRECISION (int_mode)))
3001 : 15 : return gen_rtx_ROTATE (int_mode, XEXP (opright, 0),
3002 : : XEXP (SUBREG_REG (opleft), 1));
3003 : : return NULL_RTX;
3004 : : }
3005 : :
3006 : : /* Returns true if OP0 and OP1 match the pattern (OP (plus (A - 1)) (neg A)),
3007 : : and the pattern can be simplified (there are no side effects). */
3008 : :
3009 : : static bool
3010 : 42571145 : match_plus_neg_pattern (rtx op0, rtx op1, machine_mode mode)
3011 : : {
3012 : : /* Remove SUBREG from OP0 and OP1, if needed. */
3013 : 42571145 : if (GET_CODE (op0) == SUBREG
3014 : 7268516 : && GET_CODE (op1) == SUBREG
3015 : 285142 : && subreg_lowpart_p (op0)
3016 : 42854893 : && subreg_lowpart_p (op1))
3017 : : {
3018 : 283739 : op0 = XEXP (op0, 0);
3019 : 283739 : op1 = XEXP (op1, 0);
3020 : : }
3021 : :
3022 : : /* Check for the pattern (OP (plus (A - 1)) (neg A)). */
3023 : 42571145 : if (((GET_CODE (op1) == NEG
3024 : 3592 : && GET_CODE (op0) == PLUS
3025 : 2192 : && XEXP (op0, 1) == CONSTM1_RTX (mode))
3026 : 42570483 : || (GET_CODE (op0) == NEG
3027 : 77470 : && GET_CODE (op1) == PLUS
3028 : 0 : && XEXP (op1, 1) == CONSTM1_RTX (mode)))
3029 : 662 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3030 : 42571147 : && !side_effects_p (XEXP (op0, 0)))
3031 : : return true;
3032 : : return false;
3033 : : }
3034 : :
3035 : : /* Check if OP matches the pattern of (subreg (not X)) and the subreg is
3036 : : non-paradoxical. */
3037 : :
3038 : : static bool
3039 : 80641309 : non_paradoxical_subreg_not_p (rtx op)
3040 : : {
3041 : 80641309 : return GET_CODE (op) == SUBREG
3042 : 8769760 : && !paradoxical_subreg_p (op)
3043 : 83569434 : && GET_CODE (SUBREG_REG (op)) == NOT;
3044 : : }
3045 : :
3046 : : /* Convert (binop (subreg (not X)) Y) into (binop (not (subreg X)) Y), or
3047 : : (binop X (subreg (not Y))) into (binop X (not (subreg Y))) to expose
3048 : : opportunities to combine another binary logical operation with NOT. */
3049 : :
3050 : : static rtx
3051 : 40321887 : simplify_with_subreg_not (rtx_code binop, machine_mode mode, rtx op0, rtx op1)
3052 : : {
3053 : 40321887 : rtx opn = NULL_RTX;
3054 : 40321887 : if (non_paradoxical_subreg_not_p (op0))
3055 : : opn = op0;
3056 : 40319422 : else if (non_paradoxical_subreg_not_p (op1))
3057 : : opn = op1;
3058 : :
3059 : 2468 : if (opn == NULL_RTX)
3060 : : return NULL_RTX;
3061 : :
3062 : 4936 : rtx new_subreg = simplify_gen_subreg (mode,
3063 : : XEXP (SUBREG_REG (opn), 0),
3064 : 2468 : GET_MODE (SUBREG_REG (opn)),
3065 : 2468 : SUBREG_BYTE (opn));
3066 : :
3067 : 2468 : if (!new_subreg)
3068 : : return NULL_RTX;
3069 : :
3070 : 2413 : rtx new_not = simplify_gen_unary (NOT, mode, new_subreg, mode);
3071 : 2413 : if (opn == op0)
3072 : 2410 : return simplify_gen_binary (binop, mode, new_not, op1);
3073 : : else
3074 : 3 : return simplify_gen_binary (binop, mode, op0, new_not);
3075 : : }
3076 : :
3077 : : /* Subroutine of simplify_binary_operation. Simplify a binary operation
3078 : : CODE with result mode MODE, operating on OP0 and OP1. If OP0 and/or
3079 : : OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the
3080 : : actual constants. */
3081 : :
3082 : : rtx
3083 : 447932783 : simplify_context::simplify_binary_operation_1 (rtx_code code,
3084 : : machine_mode mode,
3085 : : rtx op0, rtx op1,
3086 : : rtx trueop0, rtx trueop1)
3087 : : {
3088 : 447932783 : rtx tem, reversed, elt0, elt1;
3089 : 447932783 : HOST_WIDE_INT val;
3090 : 447932783 : scalar_int_mode int_mode, inner_mode;
3091 : 447932783 : poly_int64 offset;
3092 : :
3093 : : /* Even if we can't compute a constant result,
3094 : : there are some cases worth simplifying. */
3095 : :
3096 : 447932783 : switch (code)
3097 : : {
3098 : 253869671 : case PLUS:
3099 : : /* Maybe simplify x + 0 to x. The two expressions are equivalent
3100 : : when x is NaN, infinite, or finite and nonzero. They aren't
3101 : : when x is -0 and the rounding mode is not towards -infinity,
3102 : : since (-0) + 0 is then 0. */
3103 : 503820102 : if (!HONOR_SIGNED_ZEROS (mode) && !HONOR_SNANS (mode)
3104 : 503820090 : && trueop1 == CONST0_RTX (mode))
3105 : : return op0;
3106 : :
3107 : : /* ((-a) + b) -> (b - a) and similarly for (a + (-b)). These
3108 : : transformations are safe even for IEEE. */
3109 : 252558666 : if (GET_CODE (op0) == NEG)
3110 : 26111 : return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
3111 : 252532555 : else if (GET_CODE (op1) == NEG)
3112 : 6949 : return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
3113 : :
3114 : : /* (~a) + 1 -> -a */
3115 : 252525606 : if (INTEGRAL_MODE_P (mode)
3116 : 247702174 : && GET_CODE (op0) == NOT
3117 : 627885 : && trueop1 == const1_rtx)
3118 : 3520 : return simplify_gen_unary (NEG, mode, XEXP (op0, 0), mode);
3119 : :
3120 : : /* Handle both-operands-constant cases. We can only add
3121 : : CONST_INTs to constants since the sum of relocatable symbols
3122 : : can't be handled by most assemblers. Don't add CONST_INT
3123 : : to CONST_INT since overflow won't be computed properly if wider
3124 : : than HOST_BITS_PER_WIDE_INT. */
3125 : :
3126 : 252522086 : if ((GET_CODE (op0) == CONST
3127 : 252522086 : || GET_CODE (op0) == SYMBOL_REF
3128 : 250063549 : || GET_CODE (op0) == LABEL_REF)
3129 : 252522086 : && poly_int_rtx_p (op1, &offset))
3130 : 2457561 : return plus_constant (mode, op0, offset);
3131 : 250064525 : else if ((GET_CODE (op1) == CONST
3132 : 250064525 : || GET_CODE (op1) == SYMBOL_REF
3133 : 246399343 : || GET_CODE (op1) == LABEL_REF)
3134 : 250064525 : && poly_int_rtx_p (op0, &offset))
3135 : 0 : return plus_constant (mode, op1, offset);
3136 : :
3137 : : /* See if this is something like X * C - X or vice versa or
3138 : : if the multiplication is written as a shift. If so, we can
3139 : : distribute and make a new multiply, shift, or maybe just
3140 : : have X (if C is 2 in the example above). But don't make
3141 : : something more expensive than we had before. */
3142 : :
3143 : 250064525 : if (is_a <scalar_int_mode> (mode, &int_mode))
3144 : : {
3145 : 243167967 : rtx lhs = op0, rhs = op1;
3146 : :
3147 : 243167967 : wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
3148 : 243167967 : wide_int coeff1 = wi::one (GET_MODE_PRECISION (int_mode));
3149 : :
3150 : 243167967 : if (GET_CODE (lhs) == NEG)
3151 : : {
3152 : 0 : coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3153 : 0 : lhs = XEXP (lhs, 0);
3154 : : }
3155 : 243167967 : else if (GET_CODE (lhs) == MULT
3156 : 6709956 : && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
3157 : : {
3158 : 5591576 : coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
3159 : 5591576 : lhs = XEXP (lhs, 0);
3160 : : }
3161 : 237576391 : else if (GET_CODE (lhs) == ASHIFT
3162 : 10641953 : && CONST_INT_P (XEXP (lhs, 1))
3163 : 10570487 : && INTVAL (XEXP (lhs, 1)) >= 0
3164 : 248146866 : && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
3165 : : {
3166 : 10570475 : coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
3167 : 21140950 : GET_MODE_PRECISION (int_mode));
3168 : 10570475 : lhs = XEXP (lhs, 0);
3169 : : }
3170 : :
3171 : 243167967 : if (GET_CODE (rhs) == NEG)
3172 : : {
3173 : 0 : coeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3174 : 0 : rhs = XEXP (rhs, 0);
3175 : : }
3176 : 243167967 : else if (GET_CODE (rhs) == MULT
3177 : 276758 : && CONST_INT_P (XEXP (rhs, 1)))
3178 : : {
3179 : 173208 : coeff1 = rtx_mode_t (XEXP (rhs, 1), int_mode);
3180 : 173208 : rhs = XEXP (rhs, 0);
3181 : : }
3182 : 242994759 : else if (GET_CODE (rhs) == ASHIFT
3183 : 507942 : && CONST_INT_P (XEXP (rhs, 1))
3184 : 498175 : && INTVAL (XEXP (rhs, 1)) >= 0
3185 : 243492934 : && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
3186 : : {
3187 : 498175 : coeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
3188 : 996350 : GET_MODE_PRECISION (int_mode));
3189 : 498175 : rhs = XEXP (rhs, 0);
3190 : : }
3191 : :
3192 : 243167967 : if (rtx_equal_p (lhs, rhs))
3193 : : {
3194 : 726621 : rtx orig = gen_rtx_PLUS (int_mode, op0, op1);
3195 : 726621 : rtx coeff;
3196 : 726621 : bool speed = optimize_function_for_speed_p (cfun);
3197 : :
3198 : 726621 : coeff = immed_wide_int_const (coeff0 + coeff1, int_mode);
3199 : :
3200 : 726621 : tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
3201 : 726621 : return (set_src_cost (tem, int_mode, speed)
3202 : 726621 : <= set_src_cost (orig, int_mode, speed) ? tem : 0);
3203 : : }
3204 : :
3205 : : /* Optimize (X - 1) * Y + Y to X * Y. */
3206 : 242441346 : lhs = op0;
3207 : 242441346 : rhs = op1;
3208 : 242441346 : if (GET_CODE (op0) == MULT)
3209 : : {
3210 : 6688095 : if (((GET_CODE (XEXP (op0, 0)) == PLUS
3211 : 273461 : && XEXP (XEXP (op0, 0), 1) == constm1_rtx)
3212 : 6647790 : || (GET_CODE (XEXP (op0, 0)) == MINUS
3213 : 37156 : && XEXP (XEXP (op0, 0), 1) == const1_rtx))
3214 : 6728400 : && rtx_equal_p (XEXP (op0, 1), op1))
3215 : 118 : lhs = XEXP (XEXP (op0, 0), 0);
3216 : 6687977 : else if (((GET_CODE (XEXP (op0, 1)) == PLUS
3217 : 1631 : && XEXP (XEXP (op0, 1), 1) == constm1_rtx)
3218 : 6687942 : || (GET_CODE (XEXP (op0, 1)) == MINUS
3219 : 263 : && XEXP (XEXP (op0, 1), 1) == const1_rtx))
3220 : 6688012 : && rtx_equal_p (XEXP (op0, 0), op1))
3221 : 0 : lhs = XEXP (XEXP (op0, 1), 0);
3222 : : }
3223 : 235753251 : else if (GET_CODE (op1) == MULT)
3224 : : {
3225 : 128392 : if (((GET_CODE (XEXP (op1, 0)) == PLUS
3226 : 84 : && XEXP (XEXP (op1, 0), 1) == constm1_rtx)
3227 : 128390 : || (GET_CODE (XEXP (op1, 0)) == MINUS
3228 : 27 : && XEXP (XEXP (op1, 0), 1) == const1_rtx))
3229 : 128394 : && rtx_equal_p (XEXP (op1, 1), op0))
3230 : 0 : rhs = XEXP (XEXP (op1, 0), 0);
3231 : 128392 : else if (((GET_CODE (XEXP (op1, 1)) == PLUS
3232 : 45 : && XEXP (XEXP (op1, 1), 1) == constm1_rtx)
3233 : 128392 : || (GET_CODE (XEXP (op1, 1)) == MINUS
3234 : 0 : && XEXP (XEXP (op1, 1), 1) == const1_rtx))
3235 : 128392 : && rtx_equal_p (XEXP (op1, 0), op0))
3236 : 0 : rhs = XEXP (XEXP (op1, 1), 0);
3237 : : }
3238 : 242441346 : if (lhs != op0 || rhs != op1)
3239 : 118 : return simplify_gen_binary (MULT, int_mode, lhs, rhs);
3240 : 243167967 : }
3241 : :
3242 : : /* (plus (xor X C1) C2) is (xor X (C1^C2)) if C2 is signbit. */
3243 : 249337786 : if (CONST_SCALAR_INT_P (op1)
3244 : 193322324 : && GET_CODE (op0) == XOR
3245 : 22839 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
3246 : 249352143 : && mode_signbit_p (mode, op1))
3247 : 121 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3248 : : simplify_gen_binary (XOR, mode, op1,
3249 : 121 : XEXP (op0, 1)));
3250 : :
3251 : : /* (plus (xor X C1) C2) is (xor X (C1^C2)) if X is either 0 or 1 and
3252 : : 2 * ((X ^ C1) & C2) == 0; based on A + B == A ^ B + 2 * (A & B). */
3253 : 249337665 : if (CONST_SCALAR_INT_P (op1)
3254 : 193322203 : && GET_CODE (op0) == XOR
3255 : 22718 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
3256 : 14236 : && nonzero_bits (XEXP (op0, 0), mode) == 1
3257 : 191 : && 2 * (INTVAL (XEXP (op0, 1)) & INTVAL (op1)) == 0
3258 : 249337668 : && 2 * ((1 ^ INTVAL (XEXP (op0, 1))) & INTVAL (op1)) == 0)
3259 : 3 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3260 : : simplify_gen_binary (XOR, mode, op1,
3261 : 3 : XEXP (op0, 1)));
3262 : :
3263 : : /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)). */
3264 : 249337662 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3265 : 249335184 : && GET_CODE (op0) == MULT
3266 : 256390288 : && GET_CODE (XEXP (op0, 0)) == NEG)
3267 : : {
3268 : 5457 : rtx in1, in2;
3269 : :
3270 : 5457 : in1 = XEXP (XEXP (op0, 0), 0);
3271 : 5457 : in2 = XEXP (op0, 1);
3272 : 5457 : return simplify_gen_binary (MINUS, mode, op1,
3273 : : simplify_gen_binary (MULT, mode,
3274 : 5457 : in1, in2));
3275 : : }
3276 : :
3277 : : /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
3278 : : C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
3279 : : is 1. */
3280 : 249332205 : if (COMPARISON_P (op0)
3281 : 1510489 : && ((STORE_FLAG_VALUE == -1 && trueop1 == const1_rtx)
3282 : 1510489 : || (STORE_FLAG_VALUE == 1 && trueop1 == constm1_rtx))
3283 : 249384380 : && (reversed = reversed_comparison (op0, mode)))
3284 : 51871 : return
3285 : 51871 : simplify_gen_unary (NEG, mode, reversed, mode);
3286 : :
3287 : : /* Convert (plus (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3288 : : mode size to (rotate A CX). */
3289 : 249280334 : if ((tem = simplify_rotate_op (op0, op1, mode)))
3290 : : return tem;
3291 : :
3292 : : /* If one of the operands is a PLUS or a MINUS, see if we can
3293 : : simplify this by the associative law.
3294 : : Don't use the associative law for floating point.
3295 : : The inaccuracy makes it nonassociative,
3296 : : and subtle programs can break if operations are associated. */
3297 : :
3298 : 249278864 : if (INTEGRAL_MODE_P (mode)
3299 : 244455481 : && (plus_minus_operand_p (op0)
3300 : 210774133 : || plus_minus_operand_p (op1))
3301 : 34673517 : && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
3302 : : return tem;
3303 : :
3304 : : /* Reassociate floating point addition only when the user
3305 : : specifies associative math operations. */
3306 : 215308829 : if (FLOAT_MODE_P (mode)
3307 : 4823383 : && flag_associative_math)
3308 : : {
3309 : 904121 : tem = simplify_associative_operation (code, mode, op0, op1);
3310 : 904121 : if (tem)
3311 : : return tem;
3312 : : }
3313 : :
3314 : : /* Handle vector series. */
3315 : 215295248 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3316 : : {
3317 : 1911745 : tem = simplify_binary_operation_series (code, mode, op0, op1);
3318 : 1911745 : if (tem)
3319 : : return tem;
3320 : : }
3321 : : break;
3322 : :
3323 : : case COMPARE:
3324 : : break;
3325 : :
3326 : 42155008 : case MINUS:
3327 : : /* We can't assume x-x is 0 even with non-IEEE floating point,
3328 : : but since it is zero except in very strange circumstances, we
3329 : : will treat it as zero with -ffinite-math-only. */
3330 : 42155008 : if (rtx_equal_p (trueop0, trueop1)
3331 : 222003 : && ! side_effects_p (op0)
3332 : 42375789 : && (!FLOAT_MODE_P (mode) || !HONOR_NANS (mode)))
3333 : 218397 : return CONST0_RTX (mode);
3334 : :
3335 : : /* Change subtraction from zero into negation. (0 - x) is the
3336 : : same as -x when x is NaN, infinite, or finite and nonzero.
3337 : : But if the mode has signed zeros, and does not round towards
3338 : : -infinity, then 0 - 0 is 0, not -0. */
3339 : 41936611 : if (!HONOR_SIGNED_ZEROS (mode) && trueop0 == CONST0_RTX (mode))
3340 : 292510 : return simplify_gen_unary (NEG, mode, op1, mode);
3341 : :
3342 : : /* (-1 - a) is ~a, unless the expression contains symbolic
3343 : : constants, in which case not retaining additions and
3344 : : subtractions could cause invalid assembly to be produced. */
3345 : 41644101 : if (trueop0 == CONSTM1_RTX (mode)
3346 : 41644101 : && !contains_symbolic_reference_p (op1))
3347 : 367876 : return simplify_gen_unary (NOT, mode, op1, mode);
3348 : :
3349 : : /* Subtracting 0 has no effect unless the mode has signalling NaNs,
3350 : : or has signed zeros and supports rounding towards -infinity.
3351 : : In such a case, 0 - 0 is -0. */
3352 : 41973436 : if (!(HONOR_SIGNED_ZEROS (mode)
3353 : 697211 : && HONOR_SIGN_DEPENDENT_ROUNDING (mode))
3354 : 41275047 : && !HONOR_SNANS (mode)
3355 : 82551236 : && trueop1 == CONST0_RTX (mode))
3356 : : return op0;
3357 : :
3358 : : /* See if this is something like X * C - X or vice versa or
3359 : : if the multiplication is written as a shift. If so, we can
3360 : : distribute and make a new multiply, shift, or maybe just
3361 : : have X (if C is 2 in the example above). But don't make
3362 : : something more expensive than we had before. */
3363 : :
3364 : 40313467 : if (is_a <scalar_int_mode> (mode, &int_mode))
3365 : : {
3366 : 39077578 : rtx lhs = op0, rhs = op1;
3367 : :
3368 : 39077578 : wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
3369 : 39077578 : wide_int negcoeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3370 : :
3371 : 39077578 : if (GET_CODE (lhs) == NEG)
3372 : : {
3373 : 118709 : coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
3374 : 118709 : lhs = XEXP (lhs, 0);
3375 : : }
3376 : 38958869 : else if (GET_CODE (lhs) == MULT
3377 : 188911 : && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
3378 : : {
3379 : 78815 : coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
3380 : 78815 : lhs = XEXP (lhs, 0);
3381 : : }
3382 : 38880054 : else if (GET_CODE (lhs) == ASHIFT
3383 : 321332 : && CONST_INT_P (XEXP (lhs, 1))
3384 : 318281 : && INTVAL (XEXP (lhs, 1)) >= 0
3385 : 39198314 : && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
3386 : : {
3387 : 318260 : coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
3388 : 636520 : GET_MODE_PRECISION (int_mode));
3389 : 318260 : lhs = XEXP (lhs, 0);
3390 : : }
3391 : :
3392 : 39077578 : if (GET_CODE (rhs) == NEG)
3393 : : {
3394 : 7295 : negcoeff1 = wi::one (GET_MODE_PRECISION (int_mode));
3395 : 7295 : rhs = XEXP (rhs, 0);
3396 : : }
3397 : 39070283 : else if (GET_CODE (rhs) == MULT
3398 : 166036 : && CONST_INT_P (XEXP (rhs, 1)))
3399 : : {
3400 : 131710 : negcoeff1 = wi::neg (rtx_mode_t (XEXP (rhs, 1), int_mode));
3401 : 131710 : rhs = XEXP (rhs, 0);
3402 : : }
3403 : 38938573 : else if (GET_CODE (rhs) == ASHIFT
3404 : 388888 : && CONST_INT_P (XEXP (rhs, 1))
3405 : 388466 : && INTVAL (XEXP (rhs, 1)) >= 0
3406 : 39327039 : && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
3407 : : {
3408 : 388466 : negcoeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
3409 : 776932 : GET_MODE_PRECISION (int_mode));
3410 : 388466 : negcoeff1 = -negcoeff1;
3411 : 388466 : rhs = XEXP (rhs, 0);
3412 : : }
3413 : :
3414 : 39077578 : if (rtx_equal_p (lhs, rhs))
3415 : : {
3416 : 102414 : rtx orig = gen_rtx_MINUS (int_mode, op0, op1);
3417 : 102414 : rtx coeff;
3418 : 102414 : bool speed = optimize_function_for_speed_p (cfun);
3419 : :
3420 : 102414 : coeff = immed_wide_int_const (coeff0 + negcoeff1, int_mode);
3421 : :
3422 : 102414 : tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
3423 : 102414 : return (set_src_cost (tem, int_mode, speed)
3424 : 102414 : <= set_src_cost (orig, int_mode, speed) ? tem : 0);
3425 : : }
3426 : :
3427 : : /* Optimize (X + 1) * Y - Y to X * Y. */
3428 : 38975164 : lhs = op0;
3429 : 38975164 : if (GET_CODE (op0) == MULT)
3430 : : {
3431 : 188806 : if (((GET_CODE (XEXP (op0, 0)) == PLUS
3432 : 4496 : && XEXP (XEXP (op0, 0), 1) == const1_rtx)
3433 : 187435 : || (GET_CODE (XEXP (op0, 0)) == MINUS
3434 : 2225 : && XEXP (XEXP (op0, 0), 1) == constm1_rtx))
3435 : 190177 : && rtx_equal_p (XEXP (op0, 1), op1))
3436 : 2 : lhs = XEXP (XEXP (op0, 0), 0);
3437 : 188804 : else if (((GET_CODE (XEXP (op0, 1)) == PLUS
3438 : 16 : && XEXP (XEXP (op0, 1), 1) == const1_rtx)
3439 : 188800 : || (GET_CODE (XEXP (op0, 1)) == MINUS
3440 : 45 : && XEXP (XEXP (op0, 1), 1) == constm1_rtx))
3441 : 188808 : && rtx_equal_p (XEXP (op0, 0), op1))
3442 : 0 : lhs = XEXP (XEXP (op0, 1), 0);
3443 : : }
3444 : 38975164 : if (lhs != op0)
3445 : 2 : return simplify_gen_binary (MULT, int_mode, lhs, op1);
3446 : 39077578 : }
3447 : :
3448 : : /* (a - (-b)) -> (a + b). True even for IEEE. */
3449 : 40211051 : if (GET_CODE (op1) == NEG)
3450 : 7257 : return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
3451 : :
3452 : : /* (-x - c) may be simplified as (-c - x). */
3453 : 40203794 : if (GET_CODE (op0) == NEG
3454 : 122875 : && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1)))
3455 : : {
3456 : 610 : tem = simplify_unary_operation (NEG, mode, op1, mode);
3457 : 610 : if (tem)
3458 : 610 : return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
3459 : : }
3460 : :
3461 : 40203184 : if ((GET_CODE (op0) == CONST
3462 : 40203184 : || GET_CODE (op0) == SYMBOL_REF
3463 : 34678504 : || GET_CODE (op0) == LABEL_REF)
3464 : 40203184 : && poly_int_rtx_p (op1, &offset))
3465 : 50891 : return plus_constant (mode, op0, trunc_int_for_mode (-offset, mode));
3466 : :
3467 : : /* Don't let a relocatable value get a negative coeff. */
3468 : 40152293 : if (is_a <scalar_int_mode> (mode)
3469 : 38916435 : && poly_int_rtx_p (op1)
3470 : 47371957 : && GET_MODE (op0) != VOIDmode)
3471 : 7219664 : return simplify_gen_binary (PLUS, mode,
3472 : : op0,
3473 : 7219664 : neg_poly_int_rtx (mode, op1));
3474 : :
3475 : : /* (x - (x & y)) -> (x & ~y) */
3476 : 32932629 : if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND)
3477 : : {
3478 : 310623 : if (rtx_equal_p (op0, XEXP (op1, 0)))
3479 : : {
3480 : 496 : tem = simplify_gen_unary (NOT, mode, XEXP (op1, 1),
3481 : 248 : GET_MODE (XEXP (op1, 1)));
3482 : 248 : return simplify_gen_binary (AND, mode, op0, tem);
3483 : : }
3484 : 310375 : if (rtx_equal_p (op0, XEXP (op1, 1)))
3485 : : {
3486 : 2004 : tem = simplify_gen_unary (NOT, mode, XEXP (op1, 0),
3487 : 1002 : GET_MODE (XEXP (op1, 0)));
3488 : 1002 : return simplify_gen_binary (AND, mode, op0, tem);
3489 : : }
3490 : : }
3491 : :
3492 : : /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
3493 : : by reversing the comparison code if valid. */
3494 : 32931379 : if (STORE_FLAG_VALUE == 1
3495 : 32931379 : && trueop0 == const1_rtx
3496 : 1045048 : && COMPARISON_P (op1)
3497 : 33012111 : && (reversed = reversed_comparison (op1, mode)))
3498 : : return reversed;
3499 : :
3500 : : /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A). */
3501 : 32850670 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3502 : 32849291 : && GET_CODE (op1) == MULT
3503 : 33116107 : && GET_CODE (XEXP (op1, 0)) == NEG)
3504 : : {
3505 : 165 : rtx in1, in2;
3506 : :
3507 : 165 : in1 = XEXP (XEXP (op1, 0), 0);
3508 : 165 : in2 = XEXP (op1, 1);
3509 : 165 : return simplify_gen_binary (PLUS, mode,
3510 : : simplify_gen_binary (MULT, mode,
3511 : : in1, in2),
3512 : 165 : op0);
3513 : : }
3514 : :
3515 : : /* Canonicalize (minus (neg A) (mult B C)) to
3516 : : (minus (mult (neg B) C) A). */
3517 : 32850505 : if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
3518 : 32849126 : && GET_CODE (op1) == MULT
3519 : 33115777 : && GET_CODE (op0) == NEG)
3520 : : {
3521 : 655 : rtx in1, in2;
3522 : :
3523 : 655 : in1 = simplify_gen_unary (NEG, mode, XEXP (op1, 0), mode);
3524 : 655 : in2 = XEXP (op1, 1);
3525 : 655 : return simplify_gen_binary (MINUS, mode,
3526 : : simplify_gen_binary (MULT, mode,
3527 : : in1, in2),
3528 : 655 : XEXP (op0, 0));
3529 : : }
3530 : :
3531 : : /* If one of the operands is a PLUS or a MINUS, see if we can
3532 : : simplify this by the associative law. This will, for example,
3533 : : canonicalize (minus A (plus B C)) to (minus (minus A B) C).
3534 : : Don't use the associative law for floating point.
3535 : : The inaccuracy makes it nonassociative,
3536 : : and subtle programs can break if operations are associated. */
3537 : :
3538 : 32849850 : if (INTEGRAL_MODE_P (mode)
3539 : 32033000 : && (plus_minus_operand_p (op0)
3540 : 29665810 : || plus_minus_operand_p (op1))
3541 : 3592216 : && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
3542 : : return tem;
3543 : :
3544 : : /* Handle vector series. */
3545 : 29388250 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3546 : : {
3547 : 398372 : tem = simplify_binary_operation_series (code, mode, op0, op1);
3548 : 398372 : if (tem)
3549 : : return tem;
3550 : : }
3551 : : break;
3552 : :
3553 : 12151979 : case MULT:
3554 : 12151979 : if (trueop1 == constm1_rtx)
3555 : 31982 : return simplify_gen_unary (NEG, mode, op0, mode);
3556 : :
3557 : 12119997 : if (GET_CODE (op0) == NEG)
3558 : : {
3559 : 32593 : rtx temp = simplify_unary_operation (NEG, mode, op1, mode);
3560 : : /* If op1 is a MULT as well and simplify_unary_operation
3561 : : just moved the NEG to the second operand, simplify_gen_binary
3562 : : below could through simplify_associative_operation move
3563 : : the NEG around again and recurse endlessly. */
3564 : 32593 : if (temp
3565 : 1446 : && GET_CODE (op1) == MULT
3566 : 0 : && GET_CODE (temp) == MULT
3567 : 0 : && XEXP (op1, 0) == XEXP (temp, 0)
3568 : 0 : && GET_CODE (XEXP (temp, 1)) == NEG
3569 : 0 : && XEXP (op1, 1) == XEXP (XEXP (temp, 1), 0))
3570 : : temp = NULL_RTX;
3571 : : if (temp)
3572 : 1446 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp);
3573 : : }
3574 : 12118551 : if (GET_CODE (op1) == NEG)
3575 : : {
3576 : 952 : rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
3577 : : /* If op0 is a MULT as well and simplify_unary_operation
3578 : : just moved the NEG to the second operand, simplify_gen_binary
3579 : : below could through simplify_associative_operation move
3580 : : the NEG around again and recurse endlessly. */
3581 : 952 : if (temp
3582 : 384 : && GET_CODE (op0) == MULT
3583 : 300 : && GET_CODE (temp) == MULT
3584 : 300 : && XEXP (op0, 0) == XEXP (temp, 0)
3585 : 6 : && GET_CODE (XEXP (temp, 1)) == NEG
3586 : 5 : && XEXP (op0, 1) == XEXP (XEXP (temp, 1), 0))
3587 : : temp = NULL_RTX;
3588 : : if (temp)
3589 : 379 : return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
3590 : : }
3591 : :
3592 : : /* Maybe simplify x * 0 to 0. The reduction is not valid if
3593 : : x is NaN, since x * 0 is then also NaN. Nor is it valid
3594 : : when the mode has signed zeros, since multiplying a negative
3595 : : number by 0 will give -0, not 0. */
3596 : 12118172 : if (!HONOR_NANS (mode)
3597 : 11160057 : && !HONOR_SIGNED_ZEROS (mode)
3598 : 11159661 : && trueop1 == CONST0_RTX (mode)
3599 : 12182798 : && ! side_effects_p (op0))
3600 : : return op1;
3601 : :
3602 : : /* In IEEE floating point, x*1 is not equivalent to x for
3603 : : signalling NaNs. */
3604 : 12054769 : if (!HONOR_SNANS (mode)
3605 : 12054769 : && trueop1 == CONST1_RTX (mode))
3606 : : return op0;
3607 : :
3608 : : /* Convert multiply by constant power of two into shift. */
3609 : 11502789 : if (mem_depth == 0 && CONST_SCALAR_INT_P (trueop1))
3610 : : {
3611 : 6227852 : val = wi::exact_log2 (rtx_mode_t (trueop1, mode));
3612 : 6227852 : if (val >= 0)
3613 : 2926650 : return simplify_gen_binary (ASHIFT, mode, op0,
3614 : 2926650 : gen_int_shift_amount (mode, val));
3615 : : }
3616 : :
3617 : : /* x*2 is x+x and x*(-1) is -x */
3618 : 8576139 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
3619 : 168629 : && SCALAR_FLOAT_MODE_P (GET_MODE (trueop1))
3620 : 168629 : && !DECIMAL_FLOAT_MODE_P (GET_MODE (trueop1))
3621 : 168345 : && GET_MODE (op0) == mode)
3622 : : {
3623 : 168345 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
3624 : :
3625 : 168345 : if (real_equal (d1, &dconst2))
3626 : 614 : return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
3627 : :
3628 : 167731 : if (!HONOR_SNANS (mode)
3629 : 167731 : && real_equal (d1, &dconstm1))
3630 : 24 : return simplify_gen_unary (NEG, mode, op0, mode);
3631 : : }
3632 : :
3633 : : /* Optimize -x * -x as x * x. */
3634 : 8575501 : if (FLOAT_MODE_P (mode)
3635 : 1375138 : && GET_CODE (op0) == NEG
3636 : 7852 : && GET_CODE (op1) == NEG
3637 : 0 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3638 : 0 : && !side_effects_p (XEXP (op0, 0)))
3639 : 0 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3640 : :
3641 : : /* Likewise, optimize abs(x) * abs(x) as x * x. */
3642 : 8575501 : if (SCALAR_FLOAT_MODE_P (mode)
3643 : 1091888 : && GET_CODE (op0) == ABS
3644 : 1340 : && GET_CODE (op1) == ABS
3645 : 0 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
3646 : 8575501 : && !side_effects_p (XEXP (op0, 0)))
3647 : 0 : return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
3648 : :
3649 : : /* Reassociate multiplication, but for floating point MULTs
3650 : : only when the user specifies unsafe math optimizations. */
3651 : 8575501 : if (! FLOAT_MODE_P (mode)
3652 : 1375138 : || flag_unsafe_math_optimizations)
3653 : : {
3654 : 7618546 : tem = simplify_associative_operation (code, mode, op0, op1);
3655 : 7618546 : if (tem)
3656 : : return tem;
3657 : : }
3658 : : break;
3659 : :
3660 : 17385340 : case IOR:
3661 : 17385340 : if (trueop1 == CONST0_RTX (mode))
3662 : : return op0;
3663 : 16464193 : if (INTEGRAL_MODE_P (mode)
3664 : 16189474 : && trueop1 == CONSTM1_RTX (mode)
3665 : 9458 : && !side_effects_p (op0))
3666 : : return op1;
3667 : 16454735 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
3668 : : return op0;
3669 : : /* A | (~A) -> -1 */
3670 : 73684 : if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
3671 : 16435207 : || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
3672 : 10 : && ! side_effects_p (op0)
3673 : 16435227 : && GET_MODE_CLASS (mode) != MODE_CC)
3674 : 10 : return CONSTM1_RTX (mode);
3675 : :
3676 : : /* IOR of two single bit bitfields extracted from the same object.
3677 : : Bitfields are represented as an AND based extraction */
3678 : 16435207 : if (GET_CODE (op0) == AND
3679 : 4686663 : && GET_CODE (op1) == AND
3680 : : /* Verify both AND operands are logical right shifts. */
3681 : 334777 : && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
3682 : 4906 : && GET_CODE (XEXP (op1, 0)) == LSHIFTRT
3683 : : /* Verify both bitfields are extracted from the same object. */
3684 : 54 : && XEXP (XEXP (op0, 0), 0) == XEXP (XEXP (op1, 0), 0)
3685 : : /* Verify both fields are a single bit (could be generalized). */
3686 : 54 : && XEXP (op0, 1) == CONST1_RTX (mode)
3687 : 0 : && XEXP (op1, 1) == CONST1_RTX (mode)
3688 : : /* Verify bit positions (for cases with variable bit position). */
3689 : 0 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
3690 : 0 : && CONST_INT_P (XEXP (XEXP (op1, 0), 1)))
3691 : : {
3692 : 0 : unsigned HOST_WIDE_INT bitpos1 = INTVAL (XEXP (XEXP (op0, 0), 1));
3693 : 0 : unsigned HOST_WIDE_INT bitpos2 = INTVAL (XEXP (XEXP (op1, 0), 1));
3694 : 0 : unsigned HOST_WIDE_INT mask
3695 : 0 : = (HOST_WIDE_INT_1U << bitpos1) | (HOST_WIDE_INT_1U << bitpos2);
3696 : :
3697 : 0 : rtx m = GEN_INT (mask);
3698 : 0 : rtx t = gen_rtx_AND (mode, XEXP (XEXP (op0, 0), 0), m);
3699 : 0 : t = gen_rtx_NE (mode, t, CONST0_RTX (mode));
3700 : 0 : return t;
3701 : : }
3702 : :
3703 : : /* IOR of multiple single bit bitfields extracted from the same object
3704 : : (building on previous case).
3705 : : First bitfield is represented as an AND based extraction, as done
3706 : : above. Second represented as NE based extraction, from
3707 : : output above. */
3708 : 16435207 : if (GET_CODE (op0) == AND
3709 : 4686663 : && GET_CODE (op1) == NE
3710 : : /* Verify AND operand is logical right shift. */
3711 : 4467 : && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
3712 : : /* Verify NE operand is an AND (based on output above). */
3713 : 86 : && GET_CODE (XEXP (op1, 0)) == AND
3714 : : /* Verify both bitfields are extracted from the same object. */
3715 : 0 : && XEXP (XEXP (op0, 0), 0) == XEXP (XEXP (op1, 0), 0)
3716 : : /* Verify masking is with a single bit and that we have a NE 0
3717 : : comparison for the other operand. */
3718 : 0 : && XEXP (op0, 1) == CONST1_RTX (mode)
3719 : 0 : && XEXP (op1, 1) == CONST0_RTX (mode)
3720 : : /* Verify bit position. */
3721 : 0 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
3722 : : {
3723 : 0 : unsigned HOST_WIDE_INT bitpos1 = INTVAL (XEXP (XEXP (op0, 0), 1));
3724 : 0 : unsigned HOST_WIDE_INT mask
3725 : 0 : = (HOST_WIDE_INT_1U << bitpos1) | INTVAL (XEXP (XEXP (op1, 0), 1));
3726 : :
3727 : 0 : rtx m = GEN_INT (mask);
3728 : 0 : rtx t = gen_rtx_AND (mode, XEXP (XEXP (op0, 0), 0), m);
3729 : 0 : t = gen_rtx_NE (mode, t, CONST0_RTX (mode));
3730 : 0 : return t;
3731 : : }
3732 : :
3733 : : /* Convert (ior (plus (A - 1)) (neg A)) to -1. */
3734 : 16435207 : if (match_plus_neg_pattern (op0, op1, mode))
3735 : 0 : return CONSTM1_RTX (mode);
3736 : :
3737 : : /* (ior A C) is C if all bits of A that might be nonzero are on in C. */
3738 : 16435207 : if (CONST_INT_P (op1)
3739 : 4476143 : && HWI_COMPUTABLE_MODE_P (mode)
3740 : 4414683 : && (nonzero_bits (op0, mode) & ~UINTVAL (op1)) == 0
3741 : 16800201 : && !side_effects_p (op0))
3742 : : return op1;
3743 : :
3744 : : /* Canonicalize (X & C1) | C2. */
3745 : 16070213 : if (GET_CODE (op0) == AND
3746 : 4677137 : && CONST_INT_P (trueop1)
3747 : 815398 : && CONST_INT_P (XEXP (op0, 1)))
3748 : : {
3749 : 660385 : HOST_WIDE_INT mask = GET_MODE_MASK (mode);
3750 : 660385 : HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
3751 : 660385 : HOST_WIDE_INT c2 = INTVAL (trueop1);
3752 : :
3753 : : /* If (C1&C2) == C1, then (X&C1)|C2 becomes C2. */
3754 : 660385 : if ((c1 & c2) == c1
3755 : 660385 : && !side_effects_p (XEXP (op0, 0)))
3756 : : return trueop1;
3757 : :
3758 : : /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2. */
3759 : 660365 : if (((c1|c2) & mask) == mask)
3760 : 87748 : return simplify_gen_binary (IOR, mode, XEXP (op0, 0), op1);
3761 : :
3762 : : /* If (C1|C2) has a single bit clear, then adjust C1 so that
3763 : : when split it'll match a single bit clear style insn.
3764 : :
3765 : : This could have been done with a target dependent splitter, but
3766 : : then every target with single bit manipulation insns would need
3767 : : to implement such splitters. */
3768 : 572617 : if (exact_log2 (~(c1 | c2)) >= 0)
3769 : : {
3770 : 102598 : rtx temp = gen_rtx_AND (mode, XEXP (op0, 0), GEN_INT (c1 | c2));
3771 : 102598 : temp = gen_rtx_IOR (mode, temp, trueop1);
3772 : 102598 : return temp;
3773 : : }
3774 : : }
3775 : :
3776 : : /* Convert (A & B) | A to A. */
3777 : 15879847 : if (GET_CODE (op0) == AND
3778 : 4486771 : && (rtx_equal_p (XEXP (op0, 0), op1)
3779 : 4486664 : || rtx_equal_p (XEXP (op0, 1), op1))
3780 : 3770 : && ! side_effects_p (XEXP (op0, 0))
3781 : 15883617 : && ! side_effects_p (XEXP (op0, 1)))
3782 : : return op1;
3783 : :
3784 : : /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3785 : : mode size to (rotate A CX). */
3786 : 15876077 : tem = simplify_rotate_op (op0, op1, mode);
3787 : 15876077 : if (tem)
3788 : : return tem;
3789 : :
3790 : : /* If OP0 is (ashiftrt (plus ...) C), it might actually be
3791 : : a (sign_extend (plus ...)). Then check if OP1 is a CONST_INT and
3792 : : the PLUS does not affect any of the bits in OP1: then we can do
3793 : : the IOR as a PLUS and we can associate. This is valid if OP1
3794 : : can be safely shifted left C bits. */
3795 : 15873554 : if (CONST_INT_P (trueop1) && GET_CODE (op0) == ASHIFTRT
3796 : 6660 : && GET_CODE (XEXP (op0, 0)) == PLUS
3797 : 141 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
3798 : 87 : && CONST_INT_P (XEXP (op0, 1))
3799 : 87 : && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
3800 : : {
3801 : 87 : int count = INTVAL (XEXP (op0, 1));
3802 : 87 : HOST_WIDE_INT mask = UINTVAL (trueop1) << count;
3803 : :
3804 : 87 : if (mask >> count == INTVAL (trueop1)
3805 : 80 : && trunc_int_for_mode (mask, mode) == mask
3806 : 154 : && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
3807 : 0 : return simplify_gen_binary (ASHIFTRT, mode,
3808 : : plus_constant (mode, XEXP (op0, 0),
3809 : 0 : mask),
3810 : : XEXP (op0, 1));
3811 : : }
3812 : :
3813 : : /* The following happens with bitfield merging.
3814 : : (X & C) | ((X | Y) & ~C) -> X | (Y & ~C) */
3815 : 15873554 : if (GET_CODE (op0) == AND
3816 : 4483001 : && GET_CODE (op1) == AND
3817 : 334777 : && CONST_INT_P (XEXP (op0, 1))
3818 : 166077 : && CONST_INT_P (XEXP (op1, 1))
3819 : 160423 : && (INTVAL (XEXP (op0, 1))
3820 : 160423 : == ~INTVAL (XEXP (op1, 1))))
3821 : : {
3822 : : /* The IOR may be on both sides. */
3823 : 38745 : rtx top0 = NULL_RTX, top1 = NULL_RTX;
3824 : 38745 : if (GET_CODE (XEXP (op1, 0)) == IOR)
3825 : : top0 = op0, top1 = op1;
3826 : 38691 : else if (GET_CODE (XEXP (op0, 0)) == IOR)
3827 : 3 : top0 = op1, top1 = op0;
3828 : 38745 : if (top0 && top1)
3829 : : {
3830 : : /* X may be on either side of the inner IOR. */
3831 : 57 : rtx tem = NULL_RTX;
3832 : 57 : if (rtx_equal_p (XEXP (top0, 0),
3833 : 57 : XEXP (XEXP (top1, 0), 0)))
3834 : 43 : tem = XEXP (XEXP (top1, 0), 1);
3835 : 14 : else if (rtx_equal_p (XEXP (top0, 0),
3836 : 14 : XEXP (XEXP (top1, 0), 1)))
3837 : 5 : tem = XEXP (XEXP (top1, 0), 0);
3838 : 48 : if (tem)
3839 : 48 : return simplify_gen_binary (IOR, mode, XEXP (top0, 0),
3840 : : simplify_gen_binary
3841 : 48 : (AND, mode, tem, XEXP (top1, 1)));
3842 : : }
3843 : : }
3844 : :
3845 : : /* Convert (ior (and A C) (and B C)) into (and (ior A B) C). */
3846 : 15873506 : if (GET_CODE (op0) == GET_CODE (op1)
3847 : 3846249 : && (GET_CODE (op0) == AND
3848 : : || GET_CODE (op0) == IOR
3849 : 3846249 : || GET_CODE (op0) == LSHIFTRT
3850 : 3510029 : || GET_CODE (op0) == ASHIFTRT
3851 : 3509935 : || GET_CODE (op0) == ASHIFT
3852 : 3484141 : || GET_CODE (op0) == ROTATE
3853 : 3484141 : || GET_CODE (op0) == ROTATERT))
3854 : : {
3855 : 362108 : tem = simplify_distributive_operation (code, mode, op0, op1);
3856 : 362108 : if (tem)
3857 : : return tem;
3858 : : }
3859 : :
3860 : : /* Convert (ior (and (not A) B) A) into A | B. */
3861 : 15788048 : if (GET_CODE (op0) == AND
3862 : 4397635 : && GET_CODE (XEXP (op0, 0)) == NOT
3863 : 15938501 : && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1))
3864 : 3367 : return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
3865 : :
3866 : 15784681 : tem = simplify_with_subreg_not (code, mode, op0, op1);
3867 : 15784681 : if (tem)
3868 : : return tem;
3869 : :
3870 : 15784676 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3871 : 15784676 : if (tem)
3872 : : return tem;
3873 : :
3874 : 15784646 : tem = simplify_associative_operation (code, mode, op0, op1);
3875 : 15784646 : if (tem)
3876 : : return tem;
3877 : :
3878 : 15383673 : tem = simplify_logical_relational_operation (code, mode, op0, op1);
3879 : 15383673 : if (tem)
3880 : : return tem;
3881 : : break;
3882 : :
3883 : 1945227 : case XOR:
3884 : 1945227 : if (trueop1 == CONST0_RTX (mode))
3885 : : return op0;
3886 : 1873966 : if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
3887 : 23574 : return simplify_gen_unary (NOT, mode, op0, mode);
3888 : 1850392 : if (rtx_equal_p (trueop0, trueop1)
3889 : 2467 : && ! side_effects_p (op0)
3890 : 1852859 : && GET_MODE_CLASS (mode) != MODE_CC)
3891 : 2467 : return CONST0_RTX (mode);
3892 : :
3893 : : /* Canonicalize XOR of the most significant bit to PLUS. */
3894 : 1847925 : if (CONST_SCALAR_INT_P (op1)
3895 : 1847925 : && mode_signbit_p (mode, op1))
3896 : 41473 : return simplify_gen_binary (PLUS, mode, op0, op1);
3897 : : /* (xor (plus X C1) C2) is (xor X (C1^C2)) if C1 is signbit. */
3898 : 1806452 : if (CONST_SCALAR_INT_P (op1)
3899 : 684325 : && GET_CODE (op0) == PLUS
3900 : 2493 : && CONST_SCALAR_INT_P (XEXP (op0, 1))
3901 : 1808038 : && mode_signbit_p (mode, XEXP (op0, 1)))
3902 : 189 : return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3903 : : simplify_gen_binary (XOR, mode, op1,
3904 : 189 : XEXP (op0, 1)));
3905 : :
3906 : : /* If we are XORing two things that have no bits in common,
3907 : : convert them into an IOR. This helps to detect rotation encoded
3908 : : using those methods and possibly other simplifications. */
3909 : :
3910 : 1806263 : if (HWI_COMPUTABLE_MODE_P (mode)
3911 : 1522961 : && (nonzero_bits (op0, mode)
3912 : 1522961 : & nonzero_bits (op1, mode)) == 0)
3913 : 12232 : return (simplify_gen_binary (IOR, mode, op0, op1));
3914 : :
3915 : : /* Convert (xor (plus (A - 1)) (neg A)) to -1. */
3916 : 1794031 : if (match_plus_neg_pattern (op0, op1, mode))
3917 : 0 : return CONSTM1_RTX (mode);
3918 : :
3919 : : /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
3920 : : Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
3921 : : (NOT y). */
3922 : 1794031 : {
3923 : 1794031 : int num_negated = 0;
3924 : :
3925 : 1794031 : if (GET_CODE (op0) == NOT)
3926 : 1013 : num_negated++, op0 = XEXP (op0, 0);
3927 : 1794031 : if (GET_CODE (op1) == NOT)
3928 : 0 : num_negated++, op1 = XEXP (op1, 0);
3929 : :
3930 : 0 : if (num_negated == 2)
3931 : 0 : return simplify_gen_binary (XOR, mode, op0, op1);
3932 : 1794031 : else if (num_negated == 1)
3933 : 1013 : return simplify_gen_unary (NOT, mode,
3934 : : simplify_gen_binary (XOR, mode, op0, op1),
3935 : 1013 : mode);
3936 : : }
3937 : :
3938 : : /* Convert (xor (and A B) B) to (and (not A) B). The latter may
3939 : : correspond to a machine insn or result in further simplifications
3940 : : if B is a constant. */
3941 : :
3942 : 1793018 : if (GET_CODE (op0) == AND
3943 : 175208 : && rtx_equal_p (XEXP (op0, 1), op1)
3944 : 1827248 : && ! side_effects_p (op1))
3945 : 34230 : return simplify_gen_binary (AND, mode,
3946 : : simplify_gen_unary (NOT, mode,
3947 : : XEXP (op0, 0), mode),
3948 : 34230 : op1);
3949 : :
3950 : 1758788 : else if (GET_CODE (op0) == AND
3951 : 140978 : && rtx_equal_p (XEXP (op0, 0), op1)
3952 : 1760136 : && ! side_effects_p (op1))
3953 : 1348 : return simplify_gen_binary (AND, mode,
3954 : : simplify_gen_unary (NOT, mode,
3955 : : XEXP (op0, 1), mode),
3956 : 1348 : op1);
3957 : :
3958 : : /* Given (xor (ior (xor A B) C) D), where B, C and D are
3959 : : constants, simplify to (xor (ior A C) (B&~C)^D), canceling
3960 : : out bits inverted twice and not set by C. Similarly, given
3961 : : (xor (and (xor A B) C) D), simplify without inverting C in
3962 : : the xor operand: (xor (and A C) (B&C)^D).
3963 : : */
3964 : 1757440 : else if ((GET_CODE (op0) == IOR || GET_CODE (op0) == AND)
3965 : 161712 : && GET_CODE (XEXP (op0, 0)) == XOR
3966 : 5912 : && CONST_INT_P (op1)
3967 : 83 : && CONST_INT_P (XEXP (op0, 1))
3968 : 38 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
3969 : : {
3970 : 38 : enum rtx_code op = GET_CODE (op0);
3971 : 38 : rtx a = XEXP (XEXP (op0, 0), 0);
3972 : 38 : rtx b = XEXP (XEXP (op0, 0), 1);
3973 : 38 : rtx c = XEXP (op0, 1);
3974 : 38 : rtx d = op1;
3975 : 38 : HOST_WIDE_INT bval = INTVAL (b);
3976 : 38 : HOST_WIDE_INT cval = INTVAL (c);
3977 : 38 : HOST_WIDE_INT dval = INTVAL (d);
3978 : 38 : HOST_WIDE_INT xcval;
3979 : :
3980 : 38 : if (op == IOR)
3981 : 8 : xcval = ~cval;
3982 : : else
3983 : : xcval = cval;
3984 : :
3985 : 38 : return simplify_gen_binary (XOR, mode,
3986 : : simplify_gen_binary (op, mode, a, c),
3987 : 38 : gen_int_mode ((bval & xcval) ^ dval,
3988 : : mode));
3989 : : }
3990 : :
3991 : : /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P),
3992 : : we can transform like this:
3993 : : (A&B)^C == ~(A&B)&C | ~C&(A&B)
3994 : : == (~A|~B)&C | ~C&(A&B) * DeMorgan's Law
3995 : : == ~A&C | ~B&C | A&(~C&B) * Distribute and re-order
3996 : : Attempt a few simplifications when B and C are both constants. */
3997 : 1757402 : if (GET_CODE (op0) == AND
3998 : 139600 : && CONST_INT_P (op1)
3999 : 12926 : && CONST_INT_P (XEXP (op0, 1)))
4000 : : {
4001 : 11055 : rtx a = XEXP (op0, 0);
4002 : 11055 : rtx b = XEXP (op0, 1);
4003 : 11055 : rtx c = op1;
4004 : 11055 : HOST_WIDE_INT bval = INTVAL (b);
4005 : 11055 : HOST_WIDE_INT cval = INTVAL (c);
4006 : :
4007 : : /* Instead of computing ~A&C, we compute its negated value,
4008 : : ~(A|~C). If it yields -1, ~A&C is zero, so we can
4009 : : optimize for sure. If it does not simplify, we still try
4010 : : to compute ~A&C below, but since that always allocates
4011 : : RTL, we don't try that before committing to returning a
4012 : : simplified expression. */
4013 : 11055 : rtx n_na_c = simplify_binary_operation (IOR, mode, a,
4014 : : GEN_INT (~cval));
4015 : :
4016 : 11055 : if ((~cval & bval) == 0)
4017 : : {
4018 : 437 : rtx na_c = NULL_RTX;
4019 : 437 : if (n_na_c)
4020 : 0 : na_c = simplify_gen_unary (NOT, mode, n_na_c, mode);
4021 : : else
4022 : : {
4023 : : /* If ~A does not simplify, don't bother: we don't
4024 : : want to simplify 2 operations into 3, and if na_c
4025 : : were to simplify with na, n_na_c would have
4026 : : simplified as well. */
4027 : 437 : rtx na = simplify_unary_operation (NOT, mode, a, mode);
4028 : 437 : if (na)
4029 : 0 : na_c = simplify_gen_binary (AND, mode, na, c);
4030 : : }
4031 : :
4032 : : /* Try to simplify ~A&C | ~B&C. */
4033 : 0 : if (na_c != NULL_RTX)
4034 : 0 : return simplify_gen_binary (IOR, mode, na_c,
4035 : 0 : gen_int_mode (~bval & cval, mode));
4036 : : }
4037 : : else
4038 : : {
4039 : : /* If ~A&C is zero, simplify A&(~C&B) | ~B&C. */
4040 : 10618 : if (n_na_c == CONSTM1_RTX (mode))
4041 : : {
4042 : 0 : rtx a_nc_b = simplify_gen_binary (AND, mode, a,
4043 : 0 : gen_int_mode (~cval & bval,
4044 : : mode));
4045 : 0 : return simplify_gen_binary (IOR, mode, a_nc_b,
4046 : 0 : gen_int_mode (~bval & cval,
4047 : : mode));
4048 : : }
4049 : : }
4050 : : }
4051 : :
4052 : : /* If we have (xor (and (xor A B) C) A) with C a constant we can instead
4053 : : do (ior (and A ~C) (and B C)) which is a machine instruction on some
4054 : : machines, and also has shorter instruction path length. */
4055 : 1757402 : if (GET_CODE (op0) == AND
4056 : 139600 : && GET_CODE (XEXP (op0, 0)) == XOR
4057 : 5414 : && CONST_INT_P (XEXP (op0, 1))
4058 : 1759552 : && rtx_equal_p (XEXP (XEXP (op0, 0), 0), trueop1))
4059 : : {
4060 : 7 : rtx a = trueop1;
4061 : 7 : rtx b = XEXP (XEXP (op0, 0), 1);
4062 : 7 : rtx c = XEXP (op0, 1);
4063 : 7 : rtx nc = simplify_gen_unary (NOT, mode, c, mode);
4064 : 7 : rtx a_nc = simplify_gen_binary (AND, mode, a, nc);
4065 : 7 : rtx bc = simplify_gen_binary (AND, mode, b, c);
4066 : 7 : return simplify_gen_binary (IOR, mode, a_nc, bc);
4067 : : }
4068 : : /* Similarly, (xor (and (xor A B) C) B) as (ior (and A C) (and B ~C)) */
4069 : 1757395 : else if (GET_CODE (op0) == AND
4070 : 139593 : && GET_CODE (XEXP (op0, 0)) == XOR
4071 : 5407 : && CONST_INT_P (XEXP (op0, 1))
4072 : 1759538 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), trueop1))
4073 : : {
4074 : 8 : rtx a = XEXP (XEXP (op0, 0), 0);
4075 : 8 : rtx b = trueop1;
4076 : 8 : rtx c = XEXP (op0, 1);
4077 : 8 : rtx nc = simplify_gen_unary (NOT, mode, c, mode);
4078 : 8 : rtx b_nc = simplify_gen_binary (AND, mode, b, nc);
4079 : 8 : rtx ac = simplify_gen_binary (AND, mode, a, c);
4080 : 8 : return simplify_gen_binary (IOR, mode, ac, b_nc);
4081 : : }
4082 : :
4083 : : /* (xor (comparison foo bar) (const_int 1)) can become the reversed
4084 : : comparison if STORE_FLAG_VALUE is 1. */
4085 : 1757387 : if (STORE_FLAG_VALUE == 1
4086 : 1757387 : && trueop1 == const1_rtx
4087 : 252637 : && COMPARISON_P (op0)
4088 : 1765473 : && (reversed = reversed_comparison (op0, mode)))
4089 : : return reversed;
4090 : :
4091 : : /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
4092 : : is (lt foo (const_int 0)), so we can perform the above
4093 : : simplification if STORE_FLAG_VALUE is 1. */
4094 : :
4095 : 1749309 : if (is_a <scalar_int_mode> (mode, &int_mode)
4096 : : && STORE_FLAG_VALUE == 1
4097 : 1470198 : && trueop1 == const1_rtx
4098 : 244559 : && GET_CODE (op0) == LSHIFTRT
4099 : 35730 : && CONST_INT_P (XEXP (op0, 1))
4100 : 35730 : && INTVAL (XEXP (op0, 1)) == GET_MODE_PRECISION (int_mode) - 1)
4101 : 34828 : return gen_rtx_GE (int_mode, XEXP (op0, 0), const0_rtx);
4102 : :
4103 : : /* (xor (comparison foo bar) (const_int sign-bit))
4104 : : when STORE_FLAG_VALUE is the sign bit. */
4105 : 1714481 : if (is_a <scalar_int_mode> (mode, &int_mode)
4106 : 1435370 : && val_signbit_p (int_mode, STORE_FLAG_VALUE)
4107 : 0 : && trueop1 == const_true_rtx
4108 : 0 : && COMPARISON_P (op0)
4109 : 0 : && (reversed = reversed_comparison (op0, int_mode)))
4110 : : return reversed;
4111 : :
4112 : : /* Convert (xor (and A C) (and B C)) into (and (xor A B) C). */
4113 : 1714481 : if (GET_CODE (op0) == GET_CODE (op1)
4114 : 527316 : && (GET_CODE (op0) == AND
4115 : 527316 : || GET_CODE (op0) == LSHIFTRT
4116 : 465170 : || GET_CODE (op0) == ASHIFTRT
4117 : 465119 : || GET_CODE (op0) == ASHIFT
4118 : 465003 : || GET_CODE (op0) == ROTATE
4119 : 464895 : || GET_CODE (op0) == ROTATERT))
4120 : : {
4121 : 62955 : tem = simplify_distributive_operation (code, mode, op0, op1);
4122 : 62955 : if (tem)
4123 : : return tem;
4124 : : }
4125 : :
4126 : : /* Convert (xor (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
4127 : : mode size to (rotate A CX). */
4128 : 1655865 : tem = simplify_rotate_op (op0, op1, mode);
4129 : 1655865 : if (tem)
4130 : : return tem;
4131 : :
4132 : : /* Convert (xor (and (not A) B) A) into A | B. */
4133 : 1654485 : if (GET_CODE (op0) == AND
4134 : 81260 : && GET_CODE (XEXP (op0, 0)) == NOT
4135 : 1659084 : && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1))
4136 : 1 : return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
4137 : :
4138 : : /* Convert (xor (and (rotate (~1) A) B) (ashift 1 A))
4139 : : into B | (1 << A). */
4140 : 1654484 : if (SHIFT_COUNT_TRUNCATED
4141 : : && GET_CODE (op0) == AND
4142 : : && GET_CODE (XEXP (op0, 0)) == ROTATE
4143 : : && CONST_INT_P (XEXP (XEXP (op0, 0), 0))
4144 : : && INTVAL (XEXP (XEXP (op0, 0), 0)) == -2
4145 : : && GET_CODE (op1) == ASHIFT
4146 : : && CONST_INT_P (XEXP (op1, 0))
4147 : : && INTVAL (XEXP (op1, 0)) == 1
4148 : : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), XEXP (op1, 1))
4149 : : && !side_effects_p (XEXP (op1, 1)))
4150 : : return simplify_gen_binary (IOR, mode, XEXP (op0, 1), op1);
4151 : :
4152 : 1654484 : tem = simplify_with_subreg_not (code, mode, op0, op1);
4153 : 1654484 : if (tem)
4154 : : return tem;
4155 : :
4156 : 1654484 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
4157 : 1654484 : if (tem)
4158 : : return tem;
4159 : :
4160 : 1654484 : tem = simplify_associative_operation (code, mode, op0, op1);
4161 : 1654484 : if (tem)
4162 : : return tem;
4163 : : break;
4164 : :
4165 : 25492018 : case AND:
4166 : 25492018 : if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
4167 : : return trueop1;
4168 : 25209403 : if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
4169 : : return op0;
4170 : 24819871 : if (HWI_COMPUTABLE_MODE_P (mode))
4171 : : {
4172 : : /* When WORD_REGISTER_OPERATIONS is true, we need to know the
4173 : : nonzero bits in WORD_MODE rather than MODE. */
4174 : 21825085 : scalar_int_mode tmode = as_a <scalar_int_mode> (mode);
4175 : 21825085 : if (WORD_REGISTER_OPERATIONS
4176 : : && GET_MODE_BITSIZE (tmode) < BITS_PER_WORD)
4177 : : tmode = word_mode;
4178 : 21825085 : HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, tmode);
4179 : 21825085 : HOST_WIDE_INT nzop1;
4180 : 21825085 : if (CONST_INT_P (trueop1))
4181 : : {
4182 : 18617447 : HOST_WIDE_INT val1 = INTVAL (trueop1);
4183 : : /* If we are turning off bits already known off in OP0, we need
4184 : : not do an AND. */
4185 : 18617447 : if ((nzop0 & ~val1) == 0)
4186 : 470615 : return op0;
4187 : :
4188 : : /* Canonicalize (and (subreg (lshiftrt X shift)) mask) into
4189 : : (and (lshiftrt (subreg X) shift) mask).
4190 : :
4191 : : Keeps shift and AND in the same mode, improving recognition.
4192 : : Only applied when subreg is a lowpart, shift is valid,
4193 : : and no precision is lost. */
4194 : 6299511 : if (SUBREG_P (op0) && subreg_lowpart_p (op0)
4195 : 6283356 : && GET_CODE (XEXP (op0, 0)) == LSHIFTRT
4196 : 151511 : && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
4197 : 122833 : && INTVAL (XEXP (XEXP (op0, 0), 1)) >= 0
4198 : 122833 : && INTVAL (XEXP (XEXP (op0, 0), 1)) < HOST_BITS_PER_WIDE_INT
4199 : 18368701 : && ((INTVAL (XEXP (XEXP (op0, 0), 1))
4200 : 122832 : + floor_log2 (val1))
4201 : 18245869 : < GET_MODE_PRECISION (as_a <scalar_int_mode> (mode))))
4202 : : {
4203 : 36421 : tem = XEXP (XEXP (op0, 0), 0);
4204 : 36421 : if (SUBREG_P (tem))
4205 : : {
4206 : 600 : if (subreg_lowpart_p (tem))
4207 : 600 : tem = SUBREG_REG (tem);
4208 : : else
4209 : : tem = NULL_RTX;
4210 : : }
4211 : 600 : if (tem != NULL_RTX)
4212 : : {
4213 : 36421 : offset = subreg_lowpart_offset (mode, GET_MODE (tem));
4214 : 36421 : tem = simplify_gen_subreg (mode, tem, GET_MODE (tem),
4215 : 36421 : offset);
4216 : 36421 : if (tem)
4217 : : {
4218 : 36421 : unsigned shiftamt = INTVAL (XEXP (XEXP (op0, 0), 1));
4219 : 36421 : rtx shiftamtrtx = gen_int_shift_amount (mode,
4220 : 36421 : shiftamt);
4221 : 36421 : op0 = simplify_gen_binary (LSHIFTRT, mode, tem,
4222 : : shiftamtrtx);
4223 : 36421 : return simplify_gen_binary (AND, mode, op0, op1);
4224 : : }
4225 : : }
4226 : : }
4227 : : }
4228 : 21417086 : nzop1 = nonzero_bits (trueop1, mode);
4229 : : /* If we are clearing all the nonzero bits, the result is zero. */
4230 : 21417086 : if ((nzop1 & nzop0) == 0
4231 : 21417086 : && !side_effects_p (op0) && !side_effects_p (op1))
4232 : 62616 : return CONST0_RTX (mode);
4233 : : }
4234 : 24352605 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
4235 : 24352605 : && GET_MODE_CLASS (mode) != MODE_CC)
4236 : : return op0;
4237 : : /* A & (~A) -> 0 */
4238 : 663568 : if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
4239 : 24341953 : || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
4240 : 4000 : && ! side_effects_p (op0)
4241 : 24349907 : && GET_MODE_CLASS (mode) != MODE_CC)
4242 : 4000 : return CONST0_RTX (mode);
4243 : :
4244 : : /* Convert (and (plus (A - 1)) (neg A)) to 0. */
4245 : 24341907 : if (match_plus_neg_pattern (op0, op1, mode))
4246 : 2 : return CONST0_RTX (mode);
4247 : :
4248 : : /* Transform (and (extend X) C) into (zero_extend (and X C)) if
4249 : : there are no nonzero bits of C outside of X's mode. */
4250 : 48683810 : if ((GET_CODE (op0) == SIGN_EXTEND
4251 : 24341905 : || GET_CODE (op0) == ZERO_EXTEND)
4252 : 100876 : && CONST_SCALAR_INT_P (trueop1)
4253 : 86336 : && is_a <scalar_int_mode> (mode, &int_mode)
4254 : 86336 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
4255 : 24428241 : && (wi::mask (GET_MODE_PRECISION (inner_mode), true,
4256 : 86336 : GET_MODE_PRECISION (int_mode))
4257 : 24428241 : & rtx_mode_t (trueop1, mode)) == 0)
4258 : : {
4259 : 84026 : machine_mode imode = GET_MODE (XEXP (op0, 0));
4260 : 84026 : tem = immed_wide_int_const (rtx_mode_t (trueop1, mode), imode);
4261 : 84026 : tem = simplify_gen_binary (AND, imode, XEXP (op0, 0), tem);
4262 : 84026 : return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
4263 : : }
4264 : :
4265 : : /* Transform (and (truncate X) C) into (truncate (and X C)). This way
4266 : : we might be able to further simplify the AND with X and potentially
4267 : : remove the truncation altogether. */
4268 : 24257879 : if (GET_CODE (op0) == TRUNCATE && CONST_INT_P (trueop1))
4269 : : {
4270 : 6 : rtx x = XEXP (op0, 0);
4271 : 6 : machine_mode xmode = GET_MODE (x);
4272 : 6 : tem = simplify_gen_binary (AND, xmode, x,
4273 : 6 : gen_int_mode (INTVAL (trueop1), xmode));
4274 : 6 : return simplify_gen_unary (TRUNCATE, mode, tem, xmode);
4275 : : }
4276 : :
4277 : : /* Canonicalize (A | C1) & C2 as (A & C2) | (C1 & C2). */
4278 : 24257873 : if (GET_CODE (op0) == IOR
4279 : 1582569 : && CONST_INT_P (trueop1)
4280 : 253846 : && CONST_INT_P (XEXP (op0, 1)))
4281 : : {
4282 : 154893 : HOST_WIDE_INT tmp = INTVAL (trueop1) & INTVAL (XEXP (op0, 1));
4283 : 154893 : return simplify_gen_binary (IOR, mode,
4284 : : simplify_gen_binary (AND, mode,
4285 : : XEXP (op0, 0), op1),
4286 : 154893 : gen_int_mode (tmp, mode));
4287 : : }
4288 : :
4289 : : /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
4290 : : insn (and may simplify more). */
4291 : 24102980 : if (GET_CODE (op0) == XOR
4292 : 127572 : && rtx_equal_p (XEXP (op0, 0), op1)
4293 : 24104378 : && ! side_effects_p (op1))
4294 : 1398 : return simplify_gen_binary (AND, mode,
4295 : : simplify_gen_unary (NOT, mode,
4296 : : XEXP (op0, 1), mode),
4297 : 1398 : op1);
4298 : :
4299 : 24101582 : if (GET_CODE (op0) == XOR
4300 : 126174 : && rtx_equal_p (XEXP (op0, 1), op1)
4301 : 24105203 : && ! side_effects_p (op1))
4302 : 3621 : return simplify_gen_binary (AND, mode,
4303 : : simplify_gen_unary (NOT, mode,
4304 : : XEXP (op0, 0), mode),
4305 : 3621 : op1);
4306 : :
4307 : : /* Similarly for (~(A ^ B)) & A. */
4308 : 24097961 : if (GET_CODE (op0) == NOT
4309 : 659614 : && GET_CODE (XEXP (op0, 0)) == XOR
4310 : 3348 : && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
4311 : 24098015 : && ! side_effects_p (op1))
4312 : 54 : return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
4313 : :
4314 : 24097907 : if (GET_CODE (op0) == NOT
4315 : 659560 : && GET_CODE (XEXP (op0, 0)) == XOR
4316 : 3294 : && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
4317 : 24097944 : && ! side_effects_p (op1))
4318 : 37 : return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
4319 : :
4320 : : /* Convert (A | B) & A to A. */
4321 : 24097870 : if (GET_CODE (op0) == IOR
4322 : 1427676 : && (rtx_equal_p (XEXP (op0, 0), op1)
4323 : 1427128 : || rtx_equal_p (XEXP (op0, 1), op1))
4324 : 743 : && ! side_effects_p (XEXP (op0, 0))
4325 : 24098613 : && ! side_effects_p (XEXP (op0, 1)))
4326 : : return op1;
4327 : :
4328 : : /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
4329 : : ((A & N) + B) & M -> (A + B) & M
4330 : : Similarly if (N & M) == 0,
4331 : : ((A | N) + B) & M -> (A + B) & M
4332 : : and for - instead of + and/or ^ instead of |.
4333 : : Also, if (N & M) == 0, then
4334 : : (A +- N) & M -> A & M. */
4335 : 24097127 : if (CONST_INT_P (trueop1)
4336 : 18020979 : && HWI_COMPUTABLE_MODE_P (mode)
4337 : 17984606 : && ~UINTVAL (trueop1)
4338 : 17984606 : && (UINTVAL (trueop1) & (UINTVAL (trueop1) + 1)) == 0
4339 : 35377252 : && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS))
4340 : : {
4341 : 1005275 : rtx pmop[2];
4342 : 1005275 : int which;
4343 : :
4344 : 1005275 : pmop[0] = XEXP (op0, 0);
4345 : 1005275 : pmop[1] = XEXP (op0, 1);
4346 : :
4347 : 1005275 : if (CONST_INT_P (pmop[1])
4348 : 546235 : && (UINTVAL (pmop[1]) & UINTVAL (trueop1)) == 0)
4349 : 167820 : return simplify_gen_binary (AND, mode, pmop[0], op1);
4350 : :
4351 : 2536974 : for (which = 0; which < 2; which++)
4352 : : {
4353 : 1691316 : tem = pmop[which];
4354 : 1691316 : switch (GET_CODE (tem))
4355 : : {
4356 : 12459 : case AND:
4357 : 12459 : if (CONST_INT_P (XEXP (tem, 1))
4358 : 10969 : && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1))
4359 : : == UINTVAL (trueop1))
4360 : 8064 : pmop[which] = XEXP (tem, 0);
4361 : : break;
4362 : 1751 : case IOR:
4363 : 1751 : case XOR:
4364 : 1751 : if (CONST_INT_P (XEXP (tem, 1))
4365 : 741 : && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1)) == 0)
4366 : 139 : pmop[which] = XEXP (tem, 0);
4367 : : break;
4368 : : default:
4369 : : break;
4370 : : }
4371 : : }
4372 : :
4373 : 845658 : if (pmop[0] != XEXP (op0, 0) || pmop[1] != XEXP (op0, 1))
4374 : : {
4375 : 8203 : tem = simplify_gen_binary (GET_CODE (op0), mode,
4376 : : pmop[0], pmop[1]);
4377 : 8203 : return simplify_gen_binary (code, mode, tem, op1);
4378 : : }
4379 : : }
4380 : :
4381 : : /* (and X (ior (not X) Y) -> (and X Y) */
4382 : 23929307 : if (GET_CODE (op1) == IOR
4383 : 1094591 : && GET_CODE (XEXP (op1, 0)) == NOT
4384 : 23934710 : && rtx_equal_p (op0, XEXP (XEXP (op1, 0), 0)))
4385 : 0 : return simplify_gen_binary (AND, mode, op0, XEXP (op1, 1));
4386 : :
4387 : : /* (and (ior (not X) Y) X) -> (and X Y) */
4388 : 23929307 : if (GET_CODE (op0) == IOR
4389 : 1426933 : && GET_CODE (XEXP (op0, 0)) == NOT
4390 : 23979415 : && rtx_equal_p (op1, XEXP (XEXP (op0, 0), 0)))
4391 : 6 : return simplify_gen_binary (AND, mode, op1, XEXP (op0, 1));
4392 : :
4393 : : /* (and X (ior Y (not X)) -> (and X Y) */
4394 : 23929301 : if (GET_CODE (op1) == IOR
4395 : 1094591 : && GET_CODE (XEXP (op1, 1)) == NOT
4396 : 23929566 : && rtx_equal_p (op0, XEXP (XEXP (op1, 1), 0)))
4397 : 0 : return simplify_gen_binary (AND, mode, op0, XEXP (op1, 0));
4398 : :
4399 : : /* (and (ior Y (not X)) X) -> (and X Y) */
4400 : 23929301 : if (GET_CODE (op0) == IOR
4401 : 1426927 : && GET_CODE (XEXP (op0, 1)) == NOT
4402 : 23937726 : && rtx_equal_p (op1, XEXP (XEXP (op0, 1), 0)))
4403 : 6 : return simplify_gen_binary (AND, mode, op1, XEXP (op0, 0));
4404 : :
4405 : : /* (and (ior/xor (X Y) (not Y)) -> X & ~Y */
4406 : 23929295 : if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
4407 : 1549474 : && GET_CODE (op1) == NOT
4408 : 24041179 : && rtx_equal_p (XEXP (op1, 0), XEXP (op0, 1)))
4409 : 23 : return simplify_gen_binary (AND, mode, XEXP (op0, 0),
4410 : : simplify_gen_unary (NOT, mode,
4411 : : XEXP (op1, 0),
4412 : 23 : mode));
4413 : : /* (and (ior/xor (Y X) (not Y)) -> X & ~Y */
4414 : 23929272 : if ((GET_CODE (op0) == IOR || GET_CODE (op0) == XOR)
4415 : 1549451 : && GET_CODE (op1) == NOT
4416 : 24041133 : && rtx_equal_p (XEXP (op1, 0), XEXP (op0, 0)))
4417 : 4 : return simplify_gen_binary (AND, mode, XEXP (op0, 1),
4418 : : simplify_gen_unary (NOT, mode,
4419 : : XEXP (op1, 0),
4420 : 4 : mode));
4421 : :
4422 : : /* Convert (and (ior A C) (ior B C)) into (ior (and A B) C). */
4423 : 23929268 : if (GET_CODE (op0) == GET_CODE (op1)
4424 : 2287384 : && (GET_CODE (op0) == AND
4425 : : || GET_CODE (op0) == IOR
4426 : 2287384 : || GET_CODE (op0) == LSHIFTRT
4427 : 1193495 : || GET_CODE (op0) == ASHIFTRT
4428 : 1193386 : || GET_CODE (op0) == ASHIFT
4429 : 1193235 : || GET_CODE (op0) == ROTATE
4430 : 1193235 : || GET_CODE (op0) == ROTATERT))
4431 : : {
4432 : 1094149 : tem = simplify_distributive_operation (code, mode, op0, op1);
4433 : 1094149 : if (tem)
4434 : : return tem;
4435 : : }
4436 : :
4437 : : /* (and:v4si
4438 : : (ashiftrt:v4si A 16)
4439 : : (const_vector: 0xffff x4))
4440 : : is just (lshiftrt:v4si A 16). */
4441 : 22882764 : if (VECTOR_MODE_P (mode) && GET_CODE (op0) == ASHIFTRT
4442 : 4216 : && (CONST_INT_P (XEXP (op0, 1))
4443 : 1850 : || (GET_CODE (XEXP (op0, 1)) == CONST_VECTOR
4444 : 92 : && const_vec_duplicate_p (XEXP (op0, 1))
4445 : 0 : && CONST_INT_P (XVECEXP (XEXP (op0, 1), 0, 0))))
4446 : 2366 : && GET_CODE (op1) == CONST_VECTOR
4447 : 22882780 : && const_vec_duplicate_p (op1)
4448 : 22882822 : && CONST_INT_P (XVECEXP (op1, 0, 0)))
4449 : : {
4450 : 112 : unsigned HOST_WIDE_INT shift_count
4451 : : = (CONST_INT_P (XEXP (op0, 1))
4452 : 56 : ? UINTVAL (XEXP (op0, 1))
4453 : 0 : : UINTVAL (XVECEXP (XEXP (op0, 1), 0, 0)));
4454 : 56 : unsigned HOST_WIDE_INT inner_prec
4455 : 112 : = GET_MODE_PRECISION (GET_MODE_INNER (mode));
4456 : :
4457 : : /* Avoid UD shift count. */
4458 : 56 : if (shift_count < inner_prec
4459 : 56 : && (UINTVAL (XVECEXP (op1, 0, 0))
4460 : 56 : == (HOST_WIDE_INT_1U << (inner_prec - shift_count)) - 1))
4461 : 42 : return simplify_gen_binary (LSHIFTRT, mode, XEXP (op0, 0), XEXP (op0, 1));
4462 : : }
4463 : :
4464 : 22882722 : tem = simplify_with_subreg_not (code, mode, op0, op1);
4465 : 22882722 : if (tem)
4466 : : return tem;
4467 : :
4468 : 22880314 : tem = simplify_byte_swapping_operation (code, mode, op0, op1);
4469 : 22880314 : if (tem)
4470 : : return tem;
4471 : :
4472 : 22879841 : tem = simplify_associative_operation (code, mode, op0, op1);
4473 : 22879841 : if (tem)
4474 : : return tem;
4475 : : break;
4476 : :
4477 : 950993 : case UDIV:
4478 : : /* 0/x is 0 (or x&0 if x has side-effects). */
4479 : 950993 : if (trueop0 == CONST0_RTX (mode)
4480 : 340 : && !cfun->can_throw_non_call_exceptions)
4481 : : {
4482 : 340 : if (side_effects_p (op1))
4483 : 0 : return simplify_gen_binary (AND, mode, op1, trueop0);
4484 : : return trueop0;
4485 : : }
4486 : : /* x/1 is x. */
4487 : 950653 : if (trueop1 == CONST1_RTX (mode))
4488 : : {
4489 : 241162 : tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4490 : 241162 : if (tem)
4491 : : return tem;
4492 : : }
4493 : : /* Convert divide by power of two into shift. */
4494 : 709491 : if (CONST_INT_P (trueop1)
4495 : 1050168 : && (val = exact_log2 (UINTVAL (trueop1))) > 0)
4496 : 340677 : return simplify_gen_binary (LSHIFTRT, mode, op0,
4497 : 340677 : gen_int_shift_amount (mode, val));
4498 : : break;
4499 : :
4500 : 1158210 : case DIV:
4501 : : /* Handle floating point and integers separately. */
4502 : 1158210 : if (SCALAR_FLOAT_MODE_P (mode))
4503 : : {
4504 : : /* Maybe change 0.0 / x to 0.0. This transformation isn't
4505 : : safe for modes with NaNs, since 0.0 / 0.0 will then be
4506 : : NaN rather than 0.0. Nor is it safe for modes with signed
4507 : : zeros, since dividing 0 by a negative number gives -0.0 */
4508 : 330544 : if (trueop0 == CONST0_RTX (mode)
4509 : 2916 : && !HONOR_NANS (mode)
4510 : 14 : && !HONOR_SIGNED_ZEROS (mode)
4511 : 330558 : && ! side_effects_p (op1))
4512 : : return op0;
4513 : : /* x/1.0 is x. */
4514 : 330530 : if (trueop1 == CONST1_RTX (mode)
4515 : 330530 : && !HONOR_SNANS (mode))
4516 : : return op0;
4517 : :
4518 : 330525 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
4519 : 27431 : && trueop1 != CONST0_RTX (mode))
4520 : : {
4521 : 21239 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
4522 : :
4523 : : /* x/-1.0 is -x. */
4524 : 21239 : if (real_equal (d1, &dconstm1)
4525 : 21239 : && !HONOR_SNANS (mode))
4526 : 0 : return simplify_gen_unary (NEG, mode, op0, mode);
4527 : :
4528 : : /* Change FP division by a constant into multiplication.
4529 : : Only do this with -freciprocal-math. */
4530 : 21239 : if (flag_reciprocal_math
4531 : 21239 : && !real_equal (d1, &dconst0))
4532 : : {
4533 : 7 : REAL_VALUE_TYPE d;
4534 : 7 : real_arithmetic (&d, RDIV_EXPR, &dconst1, d1);
4535 : 7 : tem = const_double_from_real_value (d, mode);
4536 : 7 : return simplify_gen_binary (MULT, mode, op0, tem);
4537 : : }
4538 : : }
4539 : : }
4540 : 827666 : else if (SCALAR_INT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
4541 : : {
4542 : : /* 0/x is 0 (or x&0 if x has side-effects). */
4543 : 806333 : if (trueop0 == CONST0_RTX (mode)
4544 : 643 : && !cfun->can_throw_non_call_exceptions)
4545 : : {
4546 : 566 : if (side_effects_p (op1))
4547 : 8 : return simplify_gen_binary (AND, mode, op1, trueop0);
4548 : : return trueop0;
4549 : : }
4550 : : /* x/1 is x. */
4551 : 805767 : if (trueop1 == CONST1_RTX (mode))
4552 : : {
4553 : 293 : tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4554 : 293 : if (tem)
4555 : : return tem;
4556 : : }
4557 : : /* x/-1 is -x. */
4558 : 805474 : if (trueop1 == CONSTM1_RTX (mode))
4559 : : {
4560 : 215 : rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
4561 : 215 : if (x)
4562 : 215 : return simplify_gen_unary (NEG, mode, x, mode);
4563 : : }
4564 : : }
4565 : : break;
4566 : :
4567 : 931336 : case UMOD:
4568 : : /* 0%x is 0 (or x&0 if x has side-effects). */
4569 : 931336 : if (trueop0 == CONST0_RTX (mode))
4570 : : {
4571 : 818 : if (side_effects_p (op1))
4572 : 0 : return simplify_gen_binary (AND, mode, op1, trueop0);
4573 : : return trueop0;
4574 : : }
4575 : : /* x%1 is 0 (of x&0 if x has side-effects). */
4576 : 930518 : if (trueop1 == CONST1_RTX (mode))
4577 : : {
4578 : 276287 : if (side_effects_p (op0))
4579 : 0 : return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
4580 : 276287 : return CONST0_RTX (mode);
4581 : : }
4582 : : /* Implement modulus by power of two as AND. */
4583 : 654231 : if (CONST_INT_P (trueop1)
4584 : 970068 : && exact_log2 (UINTVAL (trueop1)) > 0)
4585 : 315837 : return simplify_gen_binary (AND, mode, op0,
4586 : 315837 : gen_int_mode (UINTVAL (trueop1) - 1,
4587 : : mode));
4588 : : break;
4589 : :
4590 : 337399 : case MOD:
4591 : : /* 0%x is 0 (or x&0 if x has side-effects). */
4592 : 337399 : if (trueop0 == CONST0_RTX (mode))
4593 : : {
4594 : 642 : if (side_effects_p (op1))
4595 : 8 : return simplify_gen_binary (AND, mode, op1, trueop0);
4596 : : return trueop0;
4597 : : }
4598 : : /* x%1 and x%-1 is 0 (or x&0 if x has side-effects). */
4599 : 336757 : if (trueop1 == CONST1_RTX (mode) || trueop1 == constm1_rtx)
4600 : : {
4601 : 406 : if (side_effects_p (op0))
4602 : 0 : return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
4603 : 406 : return CONST0_RTX (mode);
4604 : : }
4605 : : break;
4606 : :
4607 : 135086 : case ROTATERT:
4608 : 135086 : case ROTATE:
4609 : 135086 : if (trueop1 == CONST0_RTX (mode))
4610 : : return op0;
4611 : : /* Canonicalize rotates by constant amount. If the condition of
4612 : : reversing direction is met, then reverse the direction. */
4613 : : #if defined(HAVE_rotate) && defined(HAVE_rotatert)
4614 : 134996 : if (reverse_rotate_by_imm_p (mode, (code == ROTATE), trueop1))
4615 : : {
4616 : 11244 : int new_amount = GET_MODE_UNIT_PRECISION (mode) - INTVAL (trueop1);
4617 : 11244 : rtx new_amount_rtx = gen_int_shift_amount (mode, new_amount);
4618 : 11624 : return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
4619 : : mode, op0, new_amount_rtx);
4620 : : }
4621 : : #endif
4622 : : /* ROTATE/ROTATERT:HI (X:HI, 8) is BSWAP:HI (X). Other combinations
4623 : : such as SImode with a count of 16 do not correspond to RTL BSWAP
4624 : : semantics. */
4625 : 123752 : tem = unwrap_const_vec_duplicate (trueop1);
4626 : 123752 : if (GET_MODE_UNIT_BITSIZE (mode) == (2 * BITS_PER_UNIT)
4627 : 123752 : && CONST_INT_P (tem) && INTVAL (tem) == BITS_PER_UNIT)
4628 : 435 : return simplify_gen_unary (BSWAP, mode, op0, mode);
4629 : :
4630 : : /* FALLTHRU */
4631 : 5087142 : case ASHIFTRT:
4632 : 5087142 : if (trueop1 == CONST0_RTX (mode))
4633 : : return op0;
4634 : 5085336 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4635 : : return op0;
4636 : : /* Rotating ~0 always results in ~0. */
4637 : 5085178 : if (CONST_INT_P (trueop0)
4638 : 14785 : && HWI_COMPUTABLE_MODE_P (mode)
4639 : 14741 : && UINTVAL (trueop0) == GET_MODE_MASK (mode)
4640 : 5085178 : && ! side_effects_p (op1))
4641 : : return op0;
4642 : :
4643 : 31130311 : canonicalize_shift:
4644 : : /* Given:
4645 : : scalar modes M1, M2
4646 : : scalar constants c1, c2
4647 : : size (M2) > size (M1)
4648 : : c1 == size (M2) - size (M1)
4649 : : optimize:
4650 : : ([a|l]shiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int <c1>))
4651 : : <low_part>)
4652 : : (const_int <c2>))
4653 : : to:
4654 : : (subreg:M1 ([a|l]shiftrt:M2 (reg:M2) (const_int <c1 + c2>))
4655 : : <low_part>). */
4656 : 31130311 : if ((code == ASHIFTRT || code == LSHIFTRT)
4657 : 11798686 : && is_a <scalar_int_mode> (mode, &int_mode)
4658 : 11023666 : && SUBREG_P (op0)
4659 : 1023835 : && CONST_INT_P (op1)
4660 : 1022811 : && GET_CODE (SUBREG_REG (op0)) == LSHIFTRT
4661 : 23308 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op0)),
4662 : : &inner_mode)
4663 : 23308 : && CONST_INT_P (XEXP (SUBREG_REG (op0), 1))
4664 : 46310 : && GET_MODE_BITSIZE (inner_mode) > GET_MODE_BITSIZE (int_mode)
4665 : 23155 : && (INTVAL (XEXP (SUBREG_REG (op0), 1))
4666 : 46310 : == GET_MODE_BITSIZE (inner_mode) - GET_MODE_BITSIZE (int_mode))
4667 : 31153143 : && subreg_lowpart_p (op0))
4668 : : {
4669 : 22832 : rtx tmp = gen_int_shift_amount
4670 : 22832 : (inner_mode, INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (op1));
4671 : :
4672 : : /* Combine would usually zero out the value when combining two
4673 : : local shifts and the range becomes larger or equal to the mode.
4674 : : However since we fold away one of the shifts here combine won't
4675 : : see it so we should immediately zero the result if it's out of
4676 : : range. */
4677 : 22832 : if (code == LSHIFTRT
4678 : 42096 : && INTVAL (tmp) >= GET_MODE_BITSIZE (inner_mode))
4679 : 0 : tmp = const0_rtx;
4680 : : else
4681 : 22832 : tmp = simplify_gen_binary (code,
4682 : : inner_mode,
4683 : 22832 : XEXP (SUBREG_REG (op0), 0),
4684 : : tmp);
4685 : :
4686 : 22832 : return lowpart_subreg (int_mode, tmp, inner_mode);
4687 : : }
4688 : :
4689 : 31107479 : if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
4690 : : {
4691 : : val = INTVAL (op1) & (GET_MODE_UNIT_PRECISION (mode) - 1);
4692 : : if (val != INTVAL (op1))
4693 : : return simplify_gen_binary (code, mode, op0,
4694 : : gen_int_shift_amount (mode, val));
4695 : : }
4696 : :
4697 : : /* Simplify:
4698 : :
4699 : : (code:M1
4700 : : (subreg:M1
4701 : : ([al]shiftrt:M2
4702 : : (subreg:M2
4703 : : (ashift:M1 X C1))
4704 : : C2))
4705 : : C3)
4706 : :
4707 : : to:
4708 : :
4709 : : (code:M1
4710 : : ([al]shiftrt:M1
4711 : : (ashift:M1 X C1+N)
4712 : : C2+N)
4713 : : C3)
4714 : :
4715 : : where M1 is N bits wider than M2. Optimizing the (subreg:M1 ...)
4716 : : directly would be arithmetically correct, but restricting the
4717 : : simplification to shifts by constants is more conservative,
4718 : : since it is more likely to lead to further simplifications. */
4719 : 31107479 : if (is_a<scalar_int_mode> (mode, &int_mode)
4720 : 5413303 : && paradoxical_subreg_p (op0)
4721 : 4953848 : && is_a<scalar_int_mode> (GET_MODE (SUBREG_REG (op0)), &inner_mode)
4722 : 4953762 : && (GET_CODE (SUBREG_REG (op0)) == ASHIFTRT
4723 : 4953762 : || GET_CODE (SUBREG_REG (op0)) == LSHIFTRT)
4724 : 141223 : && CONST_INT_P (op1))
4725 : : {
4726 : 141223 : auto xcode = GET_CODE (SUBREG_REG (op0));
4727 : 141223 : rtx xop0 = XEXP (SUBREG_REG (op0), 0);
4728 : 141223 : rtx xop1 = XEXP (SUBREG_REG (op0), 1);
4729 : 141223 : if (SUBREG_P (xop0)
4730 : 8856 : && GET_MODE (SUBREG_REG (xop0)) == mode
4731 : 8828 : && GET_CODE (SUBREG_REG (xop0)) == ASHIFT
4732 : 605 : && CONST_INT_P (xop1)
4733 : 141828 : && UINTVAL (xop1) < GET_MODE_PRECISION (inner_mode))
4734 : : {
4735 : 605 : rtx yop0 = XEXP (SUBREG_REG (xop0), 0);
4736 : 605 : rtx yop1 = XEXP (SUBREG_REG (xop0), 1);
4737 : 605 : if (CONST_INT_P (yop1)
4738 : 605 : && UINTVAL (yop1) < GET_MODE_PRECISION (inner_mode))
4739 : : {
4740 : 1210 : auto bias = (GET_MODE_BITSIZE (int_mode)
4741 : 605 : - GET_MODE_BITSIZE (inner_mode));
4742 : 605 : tem = simplify_gen_binary (ASHIFT, mode, yop0,
4743 : 605 : GEN_INT (INTVAL (yop1) + bias));
4744 : 605 : tem = simplify_gen_binary (xcode, mode, tem,
4745 : 605 : GEN_INT (INTVAL (xop1) + bias));
4746 : 605 : return simplify_gen_binary (code, mode, tem, op1);
4747 : : }
4748 : : }
4749 : : }
4750 : : break;
4751 : :
4752 : 0 : case SS_ASHIFT:
4753 : 0 : if (CONST_INT_P (trueop0)
4754 : 0 : && HWI_COMPUTABLE_MODE_P (mode)
4755 : 0 : && (UINTVAL (trueop0) == (GET_MODE_MASK (mode) >> 1)
4756 : 0 : || mode_signbit_p (mode, trueop0))
4757 : 0 : && ! side_effects_p (op1))
4758 : : return op0;
4759 : 0 : goto simplify_ashift;
4760 : :
4761 : 0 : case US_ASHIFT:
4762 : 0 : if (CONST_INT_P (trueop0)
4763 : 0 : && HWI_COMPUTABLE_MODE_P (mode)
4764 : 0 : && UINTVAL (trueop0) == GET_MODE_MASK (mode)
4765 : 0 : && ! side_effects_p (op1))
4766 : : return op0;
4767 : : /* FALLTHRU */
4768 : :
4769 : 19652407 : case ASHIFT:
4770 : 19652407 : simplify_ashift:
4771 : 19652407 : if (trueop1 == CONST0_RTX (mode))
4772 : : return op0;
4773 : 19486003 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4774 : : return op0;
4775 : 19456615 : if (mem_depth
4776 : 248292 : && code == ASHIFT
4777 : 248292 : && CONST_INT_P (trueop1)
4778 : 248284 : && is_a <scalar_int_mode> (mode, &int_mode)
4779 : 19704887 : && IN_RANGE (UINTVAL (trueop1),
4780 : : 1, GET_MODE_PRECISION (int_mode) - 1))
4781 : : {
4782 : 248272 : auto c = (wi::one (GET_MODE_PRECISION (int_mode))
4783 : 248272 : << UINTVAL (trueop1));
4784 : 248272 : rtx new_op1 = immed_wide_int_const (c, int_mode);
4785 : 248272 : return simplify_gen_binary (MULT, int_mode, op0, new_op1);
4786 : 248272 : }
4787 : 19208343 : goto canonicalize_shift;
4788 : :
4789 : 8647500 : case LSHIFTRT:
4790 : 8647500 : if (trueop1 == CONST0_RTX (mode))
4791 : : return op0;
4792 : 6838187 : if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
4793 : : return op0;
4794 : : /* Optimize (lshiftrt (clz X) C) as (eq X 0). */
4795 : 6836790 : if (GET_CODE (op0) == CLZ
4796 : 0 : && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
4797 : 0 : && CONST_INT_P (trueop1)
4798 : : && STORE_FLAG_VALUE == 1
4799 : 6836790 : && INTVAL (trueop1) < GET_MODE_UNIT_PRECISION (mode))
4800 : : {
4801 : 0 : unsigned HOST_WIDE_INT zero_val = 0;
4802 : :
4803 : 0 : if (CLZ_DEFINED_VALUE_AT_ZERO (inner_mode, zero_val)
4804 : 0 : && zero_val == GET_MODE_PRECISION (inner_mode)
4805 : 0 : && INTVAL (trueop1) == exact_log2 (zero_val))
4806 : 0 : return simplify_gen_relational (EQ, mode, inner_mode,
4807 : 0 : XEXP (op0, 0), const0_rtx);
4808 : : }
4809 : 6836790 : goto canonicalize_shift;
4810 : :
4811 : 225584 : case SMIN:
4812 : 225584 : if (HWI_COMPUTABLE_MODE_P (mode)
4813 : 205367 : && mode_signbit_p (mode, trueop1)
4814 : 0 : && ! side_effects_p (op0))
4815 : : return op1;
4816 : 225584 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4817 : : return op0;
4818 : 225446 : tem = simplify_associative_operation (code, mode, op0, op1);
4819 : 225446 : if (tem)
4820 : : return tem;
4821 : : break;
4822 : :
4823 : 460445 : case SMAX:
4824 : 460445 : if (HWI_COMPUTABLE_MODE_P (mode)
4825 : 433681 : && CONST_INT_P (trueop1)
4826 : 404034 : && (UINTVAL (trueop1) == GET_MODE_MASK (mode) >> 1)
4827 : 0 : && ! side_effects_p (op0))
4828 : : return op1;
4829 : 460445 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4830 : : return op0;
4831 : 460340 : tem = simplify_associative_operation (code, mode, op0, op1);
4832 : 460340 : if (tem)
4833 : : return tem;
4834 : : break;
4835 : :
4836 : 232455 : case UMIN:
4837 : 232455 : if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
4838 : : return op1;
4839 : 232440 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4840 : : return op0;
4841 : 232339 : tem = simplify_associative_operation (code, mode, op0, op1);
4842 : 232339 : if (tem)
4843 : : return tem;
4844 : : break;
4845 : :
4846 : 225063 : case UMAX:
4847 : 225063 : if (trueop1 == constm1_rtx && ! side_effects_p (op0))
4848 : : return op1;
4849 : 225063 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4850 : : return op0;
4851 : 224973 : tem = simplify_associative_operation (code, mode, op0, op1);
4852 : 224973 : if (tem)
4853 : : return tem;
4854 : : break;
4855 : :
4856 : 11665 : case SS_PLUS:
4857 : 11665 : case US_PLUS:
4858 : 11665 : case SS_MINUS:
4859 : 11665 : case US_MINUS:
4860 : : /* Simplify x +/- 0 to x, if possible. */
4861 : 11665 : if (trueop1 == CONST0_RTX (mode))
4862 : : return op0;
4863 : : return 0;
4864 : :
4865 : 0 : case SS_MULT:
4866 : 0 : case US_MULT:
4867 : : /* Simplify x * 0 to 0, if possible. */
4868 : 0 : if (trueop1 == CONST0_RTX (mode)
4869 : 0 : && !side_effects_p (op0))
4870 : : return op1;
4871 : :
4872 : : /* Simplify x * 1 to x, if possible. */
4873 : 0 : if (trueop1 == CONST1_RTX (mode))
4874 : : return op0;
4875 : : return 0;
4876 : :
4877 : 528222 : case SMUL_HIGHPART:
4878 : 528222 : case UMUL_HIGHPART:
4879 : : /* Simplify x * 0 to 0, if possible. */
4880 : 528222 : if (trueop1 == CONST0_RTX (mode)
4881 : 528222 : && !side_effects_p (op0))
4882 : : return op1;
4883 : : return 0;
4884 : :
4885 : 0 : case SS_DIV:
4886 : 0 : case US_DIV:
4887 : : /* Simplify x / 1 to x, if possible. */
4888 : 0 : if (trueop1 == CONST1_RTX (mode))
4889 : : return op0;
4890 : : return 0;
4891 : :
4892 : 0 : case COPYSIGN:
4893 : 0 : if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
4894 : : return op0;
4895 : 0 : if (CONST_DOUBLE_AS_FLOAT_P (trueop1))
4896 : : {
4897 : 0 : REAL_VALUE_TYPE f1;
4898 : 0 : real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (trueop1));
4899 : 0 : rtx tmp = simplify_gen_unary (ABS, mode, op0, mode);
4900 : 0 : if (REAL_VALUE_NEGATIVE (f1))
4901 : 0 : tmp = simplify_unary_operation (NEG, mode, tmp, mode);
4902 : 0 : return tmp;
4903 : : }
4904 : 0 : if (GET_CODE (op0) == NEG || GET_CODE (op0) == ABS)
4905 : 0 : return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
4906 : 0 : if (GET_CODE (op1) == ABS
4907 : 0 : && ! side_effects_p (op1))
4908 : 0 : return simplify_gen_unary (ABS, mode, op0, mode);
4909 : 0 : if (GET_CODE (op0) == COPYSIGN
4910 : 0 : && ! side_effects_p (XEXP (op0, 1)))
4911 : 0 : return simplify_gen_binary (COPYSIGN, mode, XEXP (op0, 0), op1);
4912 : 0 : if (GET_CODE (op1) == COPYSIGN
4913 : 0 : && ! side_effects_p (XEXP (op1, 0)))
4914 : 0 : return simplify_gen_binary (COPYSIGN, mode, op0, XEXP (op1, 1));
4915 : : return 0;
4916 : :
4917 : 1302 : case VEC_SERIES:
4918 : 2604 : if (op1 == CONST0_RTX (GET_MODE_INNER (mode)))
4919 : 92 : return gen_vec_duplicate (mode, op0);
4920 : 1210 : if (valid_for_const_vector_p (mode, op0)
4921 : 1210 : && valid_for_const_vector_p (mode, op1))
4922 : 93 : return gen_const_vec_series (mode, op0, op1);
4923 : : return 0;
4924 : :
4925 : 3358123 : case VEC_SELECT:
4926 : 3358123 : if (!VECTOR_MODE_P (mode))
4927 : : {
4928 : 905496 : gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
4929 : 1810992 : gcc_assert (mode == GET_MODE_INNER (GET_MODE (trueop0)));
4930 : 905496 : gcc_assert (GET_CODE (trueop1) == PARALLEL);
4931 : 905496 : gcc_assert (XVECLEN (trueop1, 0) == 1);
4932 : :
4933 : : /* We can't reason about selections made at runtime. */
4934 : 905496 : if (!CONST_INT_P (XVECEXP (trueop1, 0, 0)))
4935 : 447932783 : return 0;
4936 : :
4937 : 905496 : if (vec_duplicate_p (trueop0, &elt0))
4938 : 2152 : return elt0;
4939 : :
4940 : 903344 : if (GET_CODE (trueop0) == CONST_VECTOR)
4941 : 7150 : return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP
4942 : : (trueop1, 0, 0)));
4943 : :
4944 : : /* Extract a scalar element from a nested VEC_SELECT expression
4945 : : (with optional nested VEC_CONCAT expression). Some targets
4946 : : (i386) extract scalar element from a vector using chain of
4947 : : nested VEC_SELECT expressions. When input operand is a memory
4948 : : operand, this operation can be simplified to a simple scalar
4949 : : load from an offseted memory address. */
4950 : 896194 : int n_elts;
4951 : 896194 : if (GET_CODE (trueop0) == VEC_SELECT
4952 : 965788 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
4953 : 69594 : .is_constant (&n_elts)))
4954 : : {
4955 : 69594 : rtx op0 = XEXP (trueop0, 0);
4956 : 69594 : rtx op1 = XEXP (trueop0, 1);
4957 : :
4958 : 69594 : int i = INTVAL (XVECEXP (trueop1, 0, 0));
4959 : 69594 : int elem;
4960 : :
4961 : 69594 : rtvec vec;
4962 : 69594 : rtx tmp_op, tmp;
4963 : :
4964 : 69594 : gcc_assert (GET_CODE (op1) == PARALLEL);
4965 : 69594 : gcc_assert (i < n_elts);
4966 : :
4967 : : /* Select element, pointed by nested selector. */
4968 : 69594 : elem = INTVAL (XVECEXP (op1, 0, i));
4969 : :
4970 : : /* Handle the case when nested VEC_SELECT wraps VEC_CONCAT. */
4971 : 69594 : if (GET_CODE (op0) == VEC_CONCAT)
4972 : : {
4973 : 27560 : rtx op00 = XEXP (op0, 0);
4974 : 27560 : rtx op01 = XEXP (op0, 1);
4975 : :
4976 : 27560 : machine_mode mode00, mode01;
4977 : 27560 : int n_elts00, n_elts01;
4978 : :
4979 : 27560 : mode00 = GET_MODE (op00);
4980 : 27560 : mode01 = GET_MODE (op01);
4981 : :
4982 : : /* Find out the number of elements of each operand.
4983 : : Since the concatenated result has a constant number
4984 : : of elements, the operands must too. */
4985 : 27560 : n_elts00 = GET_MODE_NUNITS (mode00).to_constant ();
4986 : 27560 : n_elts01 = GET_MODE_NUNITS (mode01).to_constant ();
4987 : :
4988 : 27560 : gcc_assert (n_elts == n_elts00 + n_elts01);
4989 : :
4990 : : /* Select correct operand of VEC_CONCAT
4991 : : and adjust selector. */
4992 : 27560 : if (elem < n_elts01)
4993 : : tmp_op = op00;
4994 : : else
4995 : : {
4996 : 41 : tmp_op = op01;
4997 : 41 : elem -= n_elts00;
4998 : : }
4999 : : }
5000 : : else
5001 : : tmp_op = op0;
5002 : :
5003 : 69594 : vec = rtvec_alloc (1);
5004 : 69594 : RTVEC_ELT (vec, 0) = GEN_INT (elem);
5005 : :
5006 : 69594 : tmp = gen_rtx_fmt_ee (code, mode,
5007 : : tmp_op, gen_rtx_PARALLEL (VOIDmode, vec));
5008 : 69594 : return tmp;
5009 : : }
5010 : : }
5011 : : else
5012 : : {
5013 : 2452627 : gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
5014 : 7357881 : gcc_assert (GET_MODE_INNER (mode)
5015 : : == GET_MODE_INNER (GET_MODE (trueop0)));
5016 : 2452627 : gcc_assert (GET_CODE (trueop1) == PARALLEL);
5017 : :
5018 : 2452627 : if (vec_duplicate_p (trueop0, &elt0))
5019 : : /* It doesn't matter which elements are selected by trueop1,
5020 : : because they are all the same. */
5021 : 15173 : return gen_vec_duplicate (mode, elt0);
5022 : :
5023 : 2437454 : if (GET_CODE (trueop0) == CONST_VECTOR)
5024 : : {
5025 : 17218 : unsigned n_elts = XVECLEN (trueop1, 0);
5026 : 17218 : rtvec v = rtvec_alloc (n_elts);
5027 : 17218 : unsigned int i;
5028 : :
5029 : 34436 : gcc_assert (known_eq (n_elts, GET_MODE_NUNITS (mode)));
5030 : 88226 : for (i = 0; i < n_elts; i++)
5031 : : {
5032 : 71008 : rtx x = XVECEXP (trueop1, 0, i);
5033 : :
5034 : 71008 : if (!CONST_INT_P (x))
5035 : : return 0;
5036 : :
5037 : 71008 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0,
5038 : : INTVAL (x));
5039 : : }
5040 : :
5041 : 17218 : return gen_rtx_CONST_VECTOR (mode, v);
5042 : : }
5043 : :
5044 : : /* Recognize the identity. */
5045 : 2420236 : if (GET_MODE (trueop0) == mode)
5046 : : {
5047 : 564688 : bool maybe_ident = true;
5048 : 564688 : for (int i = 0; i < XVECLEN (trueop1, 0); i++)
5049 : : {
5050 : 564309 : rtx j = XVECEXP (trueop1, 0, i);
5051 : 564309 : if (!CONST_INT_P (j) || INTVAL (j) != i)
5052 : : {
5053 : : maybe_ident = false;
5054 : : break;
5055 : : }
5056 : : }
5057 : 341862 : if (maybe_ident)
5058 : : return trueop0;
5059 : : }
5060 : :
5061 : : /* If we select a low-part subreg, return that. */
5062 : 2419857 : if (vec_series_lowpart_p (mode, GET_MODE (trueop0), trueop1))
5063 : : {
5064 : 0 : rtx new_rtx = lowpart_subreg (mode, trueop0,
5065 : 0 : GET_MODE (trueop0));
5066 : 0 : if (new_rtx != NULL_RTX)
5067 : : return new_rtx;
5068 : : }
5069 : :
5070 : : /* If we build {a,b} then permute it, build the result directly. */
5071 : 2419857 : if (XVECLEN (trueop1, 0) == 2
5072 : 577510 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
5073 : 577510 : && CONST_INT_P (XVECEXP (trueop1, 0, 1))
5074 : 577510 : && GET_CODE (trueop0) == VEC_CONCAT
5075 : 171816 : && GET_CODE (XEXP (trueop0, 0)) == VEC_CONCAT
5076 : 79 : && GET_MODE (XEXP (trueop0, 0)) == mode
5077 : 79 : && GET_CODE (XEXP (trueop0, 1)) == VEC_CONCAT
5078 : 56 : && GET_MODE (XEXP (trueop0, 1)) == mode)
5079 : : {
5080 : 56 : unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5081 : 56 : unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
5082 : 56 : rtx subop0, subop1;
5083 : :
5084 : 56 : gcc_assert (i0 < 4 && i1 < 4);
5085 : 56 : subop0 = XEXP (XEXP (trueop0, i0 / 2), i0 % 2);
5086 : 56 : subop1 = XEXP (XEXP (trueop0, i1 / 2), i1 % 2);
5087 : :
5088 : 56 : return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
5089 : : }
5090 : :
5091 : 2419801 : if (XVECLEN (trueop1, 0) == 2
5092 : 577454 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
5093 : 577454 : && CONST_INT_P (XVECEXP (trueop1, 0, 1))
5094 : 577454 : && GET_CODE (trueop0) == VEC_CONCAT
5095 : 171760 : && GET_MODE (trueop0) == mode)
5096 : : {
5097 : 2 : unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5098 : 2 : unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
5099 : 2 : rtx subop0, subop1;
5100 : :
5101 : 2 : gcc_assert (i0 < 2 && i1 < 2);
5102 : 2 : subop0 = XEXP (trueop0, i0);
5103 : 2 : subop1 = XEXP (trueop0, i1);
5104 : :
5105 : 2 : return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
5106 : : }
5107 : :
5108 : : /* If we select one half of a vec_concat, return that. */
5109 : 2419799 : int l0, l1;
5110 : 2419799 : if (GET_CODE (trueop0) == VEC_CONCAT
5111 : 2998226 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
5112 : 1499113 : .is_constant (&l0))
5113 : 2998226 : && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 1)))
5114 : 1499113 : .is_constant (&l1))
5115 : 3918912 : && CONST_INT_P (XVECEXP (trueop1, 0, 0)))
5116 : : {
5117 : 1499113 : rtx subop0 = XEXP (trueop0, 0);
5118 : 1499113 : rtx subop1 = XEXP (trueop0, 1);
5119 : 1499113 : machine_mode mode0 = GET_MODE (subop0);
5120 : 1499113 : machine_mode mode1 = GET_MODE (subop1);
5121 : 1499113 : int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
5122 : 1499113 : if (i0 == 0 && !side_effects_p (op1) && mode == mode0)
5123 : : {
5124 : 959007 : bool success = true;
5125 : 959007 : for (int i = 1; i < l0; ++i)
5126 : : {
5127 : 958678 : rtx j = XVECEXP (trueop1, 0, i);
5128 : 958678 : if (!CONST_INT_P (j) || INTVAL (j) != i)
5129 : : {
5130 : : success = false;
5131 : : break;
5132 : : }
5133 : : }
5134 : 875913 : if (success)
5135 : : return subop0;
5136 : : }
5137 : 1498784 : if (i0 == l0 && !side_effects_p (op0) && mode == mode1)
5138 : : {
5139 : 596 : bool success = true;
5140 : 596 : for (int i = 1; i < l1; ++i)
5141 : : {
5142 : 547 : rtx j = XVECEXP (trueop1, 0, i);
5143 : 547 : if (!CONST_INT_P (j) || INTVAL (j) != i0 + i)
5144 : : {
5145 : : success = false;
5146 : : break;
5147 : : }
5148 : : }
5149 : 78 : if (success)
5150 : : return subop1;
5151 : : }
5152 : : }
5153 : :
5154 : : /* Simplify vec_select of a subreg of X to just a vec_select of X
5155 : : when X has same component mode as vec_select. */
5156 : 2419421 : unsigned HOST_WIDE_INT subreg_offset = 0;
5157 : 2419421 : if (GET_CODE (trueop0) == SUBREG
5158 : 354586 : && GET_MODE_INNER (mode)
5159 : 709172 : == GET_MODE_INNER (GET_MODE (SUBREG_REG (trueop0)))
5160 : 28126 : && GET_MODE_NUNITS (mode).is_constant (&l1)
5161 : 2774007 : && constant_multiple_p (subreg_memory_offset (trueop0),
5162 : 28126 : GET_MODE_UNIT_BITSIZE (mode),
5163 : : &subreg_offset))
5164 : : {
5165 : 14063 : poly_uint64 nunits
5166 : 28126 : = GET_MODE_NUNITS (GET_MODE (SUBREG_REG (trueop0)));
5167 : 14063 : bool success = true;
5168 : 80553 : for (int i = 0; i != l1; i++)
5169 : : {
5170 : 76863 : rtx idx = XVECEXP (trueop1, 0, i);
5171 : 76863 : if (!CONST_INT_P (idx)
5172 : 76863 : || maybe_ge (UINTVAL (idx) + subreg_offset, nunits))
5173 : : {
5174 : : success = false;
5175 : : break;
5176 : : }
5177 : : }
5178 : :
5179 : 14063 : if (success)
5180 : : {
5181 : 3690 : rtx par = trueop1;
5182 : 3690 : if (subreg_offset)
5183 : : {
5184 : 0 : rtvec vec = rtvec_alloc (l1);
5185 : 0 : for (int i = 0; i < l1; i++)
5186 : 0 : RTVEC_ELT (vec, i)
5187 : 0 : = GEN_INT (INTVAL (XVECEXP (trueop1, 0, i))
5188 : : + subreg_offset);
5189 : 0 : par = gen_rtx_PARALLEL (VOIDmode, vec);
5190 : : }
5191 : 3690 : return gen_rtx_VEC_SELECT (mode, SUBREG_REG (trueop0), par);
5192 : : }
5193 : : }
5194 : : }
5195 : :
5196 : 3242331 : if (XVECLEN (trueop1, 0) == 1
5197 : 826684 : && CONST_INT_P (XVECEXP (trueop1, 0, 0))
5198 : 826684 : && GET_CODE (trueop0) == VEC_CONCAT)
5199 : : {
5200 : 1259 : rtx vec = trueop0;
5201 : 2518 : offset = INTVAL (XVECEXP (trueop1, 0, 0)) * GET_MODE_SIZE (mode);
5202 : :
5203 : : /* Try to find the element in the VEC_CONCAT. */
5204 : 1259 : while (GET_MODE (vec) != mode
5205 : 2518 : && GET_CODE (vec) == VEC_CONCAT)
5206 : : {
5207 : 1259 : poly_int64 vec_size;
5208 : :
5209 : 1259 : if (CONST_INT_P (XEXP (vec, 0)))
5210 : : {
5211 : : /* vec_concat of two const_ints doesn't make sense with
5212 : : respect to modes. */
5213 : 3 : if (CONST_INT_P (XEXP (vec, 1)))
5214 : 384388313 : return 0;
5215 : :
5216 : 3 : vec_size = GET_MODE_SIZE (GET_MODE (trueop0))
5217 : 9 : - GET_MODE_SIZE (GET_MODE (XEXP (vec, 1)));
5218 : : }
5219 : : else
5220 : 2512 : vec_size = GET_MODE_SIZE (GET_MODE (XEXP (vec, 0)));
5221 : :
5222 : 1259 : if (known_lt (offset, vec_size))
5223 : : vec = XEXP (vec, 0);
5224 : 313 : else if (known_ge (offset, vec_size))
5225 : : {
5226 : 313 : offset -= vec_size;
5227 : 313 : vec = XEXP (vec, 1);
5228 : : }
5229 : : else
5230 : : break;
5231 : 1259 : vec = avoid_constant_pool_reference (vec);
5232 : : }
5233 : :
5234 : 1259 : if (GET_MODE (vec) == mode)
5235 : : return vec;
5236 : : }
5237 : :
5238 : : /* If we select elements in a vec_merge that all come from the same
5239 : : operand, select from that operand directly. */
5240 : 3241247 : if (GET_CODE (op0) == VEC_MERGE)
5241 : : {
5242 : 9649 : rtx trueop02 = avoid_constant_pool_reference (XEXP (op0, 2));
5243 : 9649 : if (CONST_INT_P (trueop02))
5244 : : {
5245 : 3198 : unsigned HOST_WIDE_INT sel = UINTVAL (trueop02);
5246 : 3198 : bool all_operand0 = true;
5247 : 3198 : bool all_operand1 = true;
5248 : 10510 : for (int i = 0; i < XVECLEN (trueop1, 0); i++)
5249 : : {
5250 : 7312 : rtx j = XVECEXP (trueop1, 0, i);
5251 : 7312 : if (sel & (HOST_WIDE_INT_1U << UINTVAL (j)))
5252 : : all_operand1 = false;
5253 : : else
5254 : 3223 : all_operand0 = false;
5255 : : }
5256 : 3198 : if (all_operand0 && !side_effects_p (XEXP (op0, 1)))
5257 : 1437 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 0), op1);
5258 : 1761 : if (all_operand1 && !side_effects_p (XEXP (op0, 0)))
5259 : 47 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 1), op1);
5260 : : }
5261 : : }
5262 : :
5263 : : /* If we have two nested selects that are inverses of each
5264 : : other, replace them with the source operand. */
5265 : 3239763 : if (GET_CODE (trueop0) == VEC_SELECT
5266 : 70244 : && GET_MODE (XEXP (trueop0, 0)) == mode)
5267 : : {
5268 : 1275 : rtx op0_subop1 = XEXP (trueop0, 1);
5269 : 1275 : gcc_assert (GET_CODE (op0_subop1) == PARALLEL);
5270 : 2550 : gcc_assert (known_eq (XVECLEN (trueop1, 0), GET_MODE_NUNITS (mode)));
5271 : :
5272 : : /* Apply the outer ordering vector to the inner one. (The inner
5273 : : ordering vector is expressly permitted to be of a different
5274 : : length than the outer one.) If the result is { 0, 1, ..., n-1 }
5275 : : then the two VEC_SELECTs cancel. */
5276 : 1581 : for (int i = 0; i < XVECLEN (trueop1, 0); ++i)
5277 : : {
5278 : 1581 : rtx x = XVECEXP (trueop1, 0, i);
5279 : 1581 : if (!CONST_INT_P (x))
5280 : : return 0;
5281 : 1581 : rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
5282 : 1581 : if (!CONST_INT_P (y) || i != INTVAL (y))
5283 : : return 0;
5284 : : }
5285 : : return XEXP (trueop0, 0);
5286 : : }
5287 : :
5288 : : return 0;
5289 : 4166886 : case VEC_CONCAT:
5290 : 4166886 : {
5291 : 4166886 : machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
5292 : 4166886 : ? GET_MODE (trueop0)
5293 : 4166886 : : GET_MODE_INNER (mode));
5294 : 4166886 : machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
5295 : 4166886 : ? GET_MODE (trueop1)
5296 : 4166886 : : GET_MODE_INNER (mode));
5297 : :
5298 : 4166886 : gcc_assert (VECTOR_MODE_P (mode));
5299 : 16667544 : gcc_assert (known_eq (GET_MODE_SIZE (op0_mode)
5300 : : + GET_MODE_SIZE (op1_mode),
5301 : : GET_MODE_SIZE (mode)));
5302 : :
5303 : 4166886 : if (VECTOR_MODE_P (op0_mode))
5304 : 5646918 : gcc_assert (GET_MODE_INNER (mode)
5305 : : == GET_MODE_INNER (op0_mode));
5306 : : else
5307 : 4569160 : gcc_assert (GET_MODE_INNER (mode) == op0_mode);
5308 : :
5309 : 4166886 : if (VECTOR_MODE_P (op1_mode))
5310 : 5646918 : gcc_assert (GET_MODE_INNER (mode)
5311 : : == GET_MODE_INNER (op1_mode));
5312 : : else
5313 : 4569160 : gcc_assert (GET_MODE_INNER (mode) == op1_mode);
5314 : :
5315 : 4166886 : unsigned int n_elts, in_n_elts;
5316 : 4166886 : if ((GET_CODE (trueop0) == CONST_VECTOR
5317 : 4166886 : || CONST_SCALAR_INT_P (trueop0)
5318 : 4005916 : || CONST_DOUBLE_AS_FLOAT_P (trueop0))
5319 : 162413 : && (GET_CODE (trueop1) == CONST_VECTOR
5320 : 162413 : || CONST_SCALAR_INT_P (trueop1)
5321 : 162413 : || CONST_DOUBLE_AS_FLOAT_P (trueop1))
5322 : 0 : && GET_MODE_NUNITS (mode).is_constant (&n_elts)
5323 : 4166886 : && GET_MODE_NUNITS (op0_mode).is_constant (&in_n_elts))
5324 : : {
5325 : 0 : rtvec v = rtvec_alloc (n_elts);
5326 : 0 : unsigned int i;
5327 : 0 : for (i = 0; i < n_elts; i++)
5328 : : {
5329 : 0 : if (i < in_n_elts)
5330 : : {
5331 : 0 : if (!VECTOR_MODE_P (op0_mode))
5332 : 0 : RTVEC_ELT (v, i) = trueop0;
5333 : : else
5334 : 0 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
5335 : : }
5336 : : else
5337 : : {
5338 : 0 : if (!VECTOR_MODE_P (op1_mode))
5339 : 0 : RTVEC_ELT (v, i) = trueop1;
5340 : : else
5341 : 0 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
5342 : : i - in_n_elts);
5343 : : }
5344 : : }
5345 : :
5346 : 0 : return gen_rtx_CONST_VECTOR (mode, v);
5347 : : }
5348 : :
5349 : : /* Try to merge two VEC_SELECTs from the same vector into a single one.
5350 : : Restrict the transformation to avoid generating a VEC_SELECT with a
5351 : : mode unrelated to its operand. */
5352 : 4166886 : if (GET_CODE (trueop0) == VEC_SELECT
5353 : 129823 : && GET_CODE (trueop1) == VEC_SELECT
5354 : 28526 : && rtx_equal_p (XEXP (trueop0, 0), XEXP (trueop1, 0))
5355 : 4182984 : && GET_MODE_INNER (GET_MODE (XEXP (trueop0, 0)))
5356 : 32196 : == GET_MODE_INNER(mode))
5357 : : {
5358 : 16098 : rtx par0 = XEXP (trueop0, 1);
5359 : 16098 : rtx par1 = XEXP (trueop1, 1);
5360 : 16098 : int len0 = XVECLEN (par0, 0);
5361 : 16098 : int len1 = XVECLEN (par1, 0);
5362 : 16098 : rtvec vec = rtvec_alloc (len0 + len1);
5363 : 99128 : for (int i = 0; i < len0; i++)
5364 : 83030 : RTVEC_ELT (vec, i) = XVECEXP (par0, 0, i);
5365 : 99128 : for (int i = 0; i < len1; i++)
5366 : 83030 : RTVEC_ELT (vec, len0 + i) = XVECEXP (par1, 0, i);
5367 : 16098 : return simplify_gen_binary (VEC_SELECT, mode, XEXP (trueop0, 0),
5368 : 16098 : gen_rtx_PARALLEL (VOIDmode, vec));
5369 : : }
5370 : : /* (vec_concat:
5371 : : (subreg_lowpart:N OP)
5372 : : (vec_select:N OP P)) --> OP when P selects the high half
5373 : : of the OP. */
5374 : 4150788 : if (GET_CODE (trueop0) == SUBREG
5375 : 475689 : && subreg_lowpart_p (trueop0)
5376 : 475461 : && GET_CODE (trueop1) == VEC_SELECT
5377 : 49 : && SUBREG_REG (trueop0) == XEXP (trueop1, 0)
5378 : 0 : && !side_effects_p (XEXP (trueop1, 0))
5379 : 4150788 : && vec_series_highpart_p (op1_mode, mode, XEXP (trueop1, 1)))
5380 : 0 : return XEXP (trueop1, 0);
5381 : : }
5382 : : return 0;
5383 : :
5384 : 0 : default:
5385 : 0 : gcc_unreachable ();
5386 : : }
5387 : :
5388 : 376456822 : if (mode == GET_MODE (op0)
5389 : 321939684 : && mode == GET_MODE (op1)
5390 : 97953445 : && vec_duplicate_p (op0, &elt0)
5391 : 376573890 : && vec_duplicate_p (op1, &elt1))
5392 : : {
5393 : : /* Try applying the operator to ELT and see if that simplifies.
5394 : : We can duplicate the result if so.
5395 : :
5396 : : The reason we don't use simplify_gen_binary is that it isn't
5397 : : necessarily a win to convert things like:
5398 : :
5399 : : (plus:V (vec_duplicate:V (reg:S R1))
5400 : : (vec_duplicate:V (reg:S R2)))
5401 : :
5402 : : to:
5403 : :
5404 : : (vec_duplicate:V (plus:S (reg:S R1) (reg:S R2)))
5405 : :
5406 : : The first might be done entirely in vector registers while the
5407 : : second might need a move between register files. */
5408 : 118 : tem = simplify_binary_operation (code, GET_MODE_INNER (mode),
5409 : : elt0, elt1);
5410 : 59 : if (tem)
5411 : 2 : return gen_vec_duplicate (mode, tem);
5412 : : }
5413 : :
5414 : : return 0;
5415 : : }
5416 : :
5417 : : /* Return true if binary operation OP distributes over addition in operand
5418 : : OPNO, with the other operand being held constant. OPNO counts from 1. */
5419 : :
5420 : : static bool
5421 : 7173 : distributes_over_addition_p (rtx_code op, int opno)
5422 : : {
5423 : 0 : switch (op)
5424 : : {
5425 : : case PLUS:
5426 : : case MINUS:
5427 : : case MULT:
5428 : : return true;
5429 : :
5430 : 0 : case ASHIFT:
5431 : 0 : return opno == 1;
5432 : :
5433 : 0 : default:
5434 : 0 : return false;
5435 : : }
5436 : : }
5437 : :
5438 : : rtx
5439 : 482039172 : simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
5440 : : rtx op0, rtx op1)
5441 : : {
5442 : 482039172 : if (VECTOR_MODE_P (mode)
5443 : 14697926 : && code != VEC_CONCAT
5444 : 10520750 : && GET_CODE (op0) == CONST_VECTOR
5445 : 192493 : && GET_CODE (op1) == CONST_VECTOR)
5446 : : {
5447 : 7890 : bool step_ok_p;
5448 : 7890 : if (CONST_VECTOR_STEPPED_P (op0)
5449 : 7890 : && CONST_VECTOR_STEPPED_P (op1))
5450 : : /* We can operate directly on the encoding if:
5451 : :
5452 : : a3 - a2 == a2 - a1 && b3 - b2 == b2 - b1
5453 : : implies
5454 : : (a3 op b3) - (a2 op b2) == (a2 op b2) - (a1 op b1)
5455 : :
5456 : : Addition and subtraction are the supported operators
5457 : : for which this is true. */
5458 : 717 : step_ok_p = (code == PLUS || code == MINUS);
5459 : 7173 : else if (CONST_VECTOR_STEPPED_P (op0))
5460 : : /* We can operate directly on stepped encodings if:
5461 : :
5462 : : a3 - a2 == a2 - a1
5463 : : implies:
5464 : : (a3 op c) - (a2 op c) == (a2 op c) - (a1 op c)
5465 : :
5466 : : which is true if (x -> x op c) distributes over addition. */
5467 : 1042 : step_ok_p = distributes_over_addition_p (code, 1);
5468 : : else
5469 : : /* Similarly in reverse. */
5470 : 6131 : step_ok_p = distributes_over_addition_p (code, 2);
5471 : 7890 : rtx_vector_builder builder;
5472 : 7890 : if (!builder.new_binary_operation (mode, op0, op1, step_ok_p))
5473 : : return 0;
5474 : :
5475 : 7890 : unsigned int count = builder.encoded_nelts ();
5476 : 51213 : for (unsigned int i = 0; i < count; i++)
5477 : : {
5478 : 86914 : rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
5479 : : CONST_VECTOR_ELT (op0, i),
5480 : 43457 : CONST_VECTOR_ELT (op1, i));
5481 : 43457 : if (!x || !valid_for_const_vector_p (mode, x))
5482 : 134 : return 0;
5483 : 43323 : builder.quick_push (x);
5484 : : }
5485 : 7756 : return builder.build ();
5486 : 7890 : }
5487 : :
5488 : 482031282 : if (VECTOR_MODE_P (mode)
5489 : 14690036 : && code == VEC_CONCAT
5490 : 4177176 : && (CONST_SCALAR_INT_P (op0)
5491 : 4027161 : || CONST_FIXED_P (op0)
5492 : 4027161 : || CONST_DOUBLE_AS_FLOAT_P (op0)
5493 : 4024354 : || CONST_VECTOR_P (op0))
5494 : 172703 : && (CONST_SCALAR_INT_P (op1)
5495 : 170866 : || CONST_DOUBLE_AS_FLOAT_P (op1)
5496 : 169502 : || CONST_FIXED_P (op1)
5497 : 169502 : || CONST_VECTOR_P (op1)))
5498 : : {
5499 : : /* Both inputs have a constant number of elements, so the result
5500 : : must too. */
5501 : 10290 : unsigned n_elts = GET_MODE_NUNITS (mode).to_constant ();
5502 : 10290 : rtvec v = rtvec_alloc (n_elts);
5503 : :
5504 : 10290 : gcc_assert (n_elts >= 2);
5505 : 10290 : if (n_elts == 2)
5506 : : {
5507 : 3201 : gcc_assert (GET_CODE (op0) != CONST_VECTOR);
5508 : 3201 : gcc_assert (GET_CODE (op1) != CONST_VECTOR);
5509 : :
5510 : 3201 : RTVEC_ELT (v, 0) = op0;
5511 : 3201 : RTVEC_ELT (v, 1) = op1;
5512 : : }
5513 : : else
5514 : : {
5515 : 7089 : unsigned op0_n_elts = GET_MODE_NUNITS (GET_MODE (op0)).to_constant ();
5516 : 7089 : unsigned op1_n_elts = GET_MODE_NUNITS (GET_MODE (op1)).to_constant ();
5517 : 7089 : unsigned i;
5518 : :
5519 : 7089 : gcc_assert (GET_CODE (op0) == CONST_VECTOR);
5520 : 7089 : gcc_assert (GET_CODE (op1) == CONST_VECTOR);
5521 : 7089 : gcc_assert (op0_n_elts + op1_n_elts == n_elts);
5522 : :
5523 : 60749 : for (i = 0; i < op0_n_elts; ++i)
5524 : 53660 : RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op0, i);
5525 : 60941 : for (i = 0; i < op1_n_elts; ++i)
5526 : 53852 : RTVEC_ELT (v, op0_n_elts+i) = CONST_VECTOR_ELT (op1, i);
5527 : : }
5528 : :
5529 : 10290 : return gen_rtx_CONST_VECTOR (mode, v);
5530 : : }
5531 : :
5532 : 470578329 : if (VECTOR_MODE_P (mode)
5533 : 14679746 : && GET_CODE (op0) == CONST_VECTOR
5534 : 197395 : && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1))
5535 : 482020992 : && (CONST_VECTOR_DUPLICATE_P (op0)
5536 : : || CONST_VECTOR_NUNITS (op0).is_constant ()))
5537 : : {
5538 : 142980 : switch (code)
5539 : : {
5540 : 142980 : case PLUS:
5541 : 142980 : case MINUS:
5542 : 142980 : case MULT:
5543 : 142980 : case DIV:
5544 : 142980 : case MOD:
5545 : 142980 : case UDIV:
5546 : 142980 : case UMOD:
5547 : 142980 : case AND:
5548 : 142980 : case IOR:
5549 : 142980 : case XOR:
5550 : 142980 : case SMIN:
5551 : 142980 : case SMAX:
5552 : 142980 : case UMIN:
5553 : 142980 : case UMAX:
5554 : 142980 : case LSHIFTRT:
5555 : 142980 : case ASHIFTRT:
5556 : 142980 : case ASHIFT:
5557 : 142980 : case ROTATE:
5558 : 142980 : case ROTATERT:
5559 : 142980 : case SS_PLUS:
5560 : 142980 : case US_PLUS:
5561 : 142980 : case SS_MINUS:
5562 : 142980 : case US_MINUS:
5563 : 142980 : case SS_ASHIFT:
5564 : 142980 : case US_ASHIFT:
5565 : 142980 : case COPYSIGN:
5566 : 142980 : break;
5567 : : default:
5568 : : return NULL_RTX;
5569 : : }
5570 : :
5571 : 142980 : unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op0)
5572 : 142980 : ? CONST_VECTOR_NPATTERNS (op0)
5573 : 150696 : : CONST_VECTOR_NUNITS (op0).to_constant ());
5574 : 142980 : rtx_vector_builder builder (mode, npatterns, 1);
5575 : 298984 : for (unsigned i = 0; i < npatterns; i++)
5576 : : {
5577 : 312008 : rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
5578 : 156004 : CONST_VECTOR_ELT (op0, i), op1);
5579 : 156004 : if (!x || !valid_for_const_vector_p (mode, x))
5580 : 0 : return 0;
5581 : 156004 : builder.quick_push (x);
5582 : : }
5583 : 142980 : return builder.build ();
5584 : : }
5585 : :
5586 : 481878012 : if (SCALAR_FLOAT_MODE_P (mode)
5587 : 6406324 : && CONST_DOUBLE_AS_FLOAT_P (op0)
5588 : 76506 : && CONST_DOUBLE_AS_FLOAT_P (op1)
5589 : 11672 : && mode == GET_MODE (op0) && mode == GET_MODE (op1))
5590 : : {
5591 : 11672 : if (code == AND
5592 : : || code == IOR
5593 : 11672 : || code == XOR)
5594 : : {
5595 : 2519 : long tmp0[4];
5596 : 2519 : long tmp1[4];
5597 : 2519 : REAL_VALUE_TYPE r;
5598 : 2519 : int i;
5599 : :
5600 : 2519 : real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0),
5601 : 2519 : GET_MODE (op0));
5602 : 2519 : real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1),
5603 : 2519 : GET_MODE (op1));
5604 : 12595 : for (i = 0; i < 4; i++)
5605 : : {
5606 : 10076 : switch (code)
5607 : : {
5608 : 5284 : case AND:
5609 : 5284 : tmp0[i] &= tmp1[i];
5610 : 5284 : break;
5611 : 2512 : case IOR:
5612 : 2512 : tmp0[i] |= tmp1[i];
5613 : 2512 : break;
5614 : 2280 : case XOR:
5615 : 2280 : tmp0[i] ^= tmp1[i];
5616 : 2280 : break;
5617 : : default:
5618 : : gcc_unreachable ();
5619 : : }
5620 : : }
5621 : 2519 : real_from_target (&r, tmp0, mode);
5622 : 2519 : return const_double_from_real_value (r, mode);
5623 : : }
5624 : 9153 : else if (code == COPYSIGN)
5625 : : {
5626 : 0 : REAL_VALUE_TYPE f0, f1;
5627 : 0 : real_convert (&f0, mode, CONST_DOUBLE_REAL_VALUE (op0));
5628 : 0 : real_convert (&f1, mode, CONST_DOUBLE_REAL_VALUE (op1));
5629 : 0 : real_copysign (&f0, &f1);
5630 : 0 : return const_double_from_real_value (f0, mode);
5631 : : }
5632 : : else
5633 : : {
5634 : 9153 : REAL_VALUE_TYPE f0, f1, value, result;
5635 : 9153 : const REAL_VALUE_TYPE *opr0, *opr1;
5636 : 9153 : bool inexact;
5637 : :
5638 : 9153 : opr0 = CONST_DOUBLE_REAL_VALUE (op0);
5639 : 9153 : opr1 = CONST_DOUBLE_REAL_VALUE (op1);
5640 : :
5641 : 9153 : if (HONOR_SNANS (mode)
5642 : 9153 : && (REAL_VALUE_ISSIGNALING_NAN (*opr0)
5643 : 803 : || REAL_VALUE_ISSIGNALING_NAN (*opr1)))
5644 : 10 : return 0;
5645 : :
5646 : 9143 : real_convert (&f0, mode, opr0);
5647 : 9143 : real_convert (&f1, mode, opr1);
5648 : :
5649 : 9143 : if (code == DIV
5650 : 4190 : && real_equal (&f1, &dconst0)
5651 : 12865 : && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
5652 : 3718 : return 0;
5653 : :
5654 : 27024 : if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
5655 : 5333 : && flag_trapping_math
5656 : 5257 : && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
5657 : : {
5658 : 9 : int s0 = REAL_VALUE_NEGATIVE (f0);
5659 : 9 : int s1 = REAL_VALUE_NEGATIVE (f1);
5660 : :
5661 : 9 : switch (code)
5662 : : {
5663 : 0 : case PLUS:
5664 : : /* Inf + -Inf = NaN plus exception. */
5665 : 0 : if (s0 != s1)
5666 : : return 0;
5667 : : break;
5668 : 0 : case MINUS:
5669 : : /* Inf - Inf = NaN plus exception. */
5670 : 0 : if (s0 == s1)
5671 : : return 0;
5672 : : break;
5673 : : case DIV:
5674 : : /* Inf / Inf = NaN plus exception. */
5675 : : return 0;
5676 : : default:
5677 : : break;
5678 : : }
5679 : : }
5680 : :
5681 : 8104 : if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
5682 : 1992 : && flag_trapping_math
5683 : 7362 : && ((REAL_VALUE_ISINF (f0) && real_equal (&f1, &dconst0))
5684 : 1938 : || (REAL_VALUE_ISINF (f1)
5685 : 16 : && real_equal (&f0, &dconst0))))
5686 : : /* Inf * 0 = NaN plus exception. */
5687 : 24 : return 0;
5688 : :
5689 : 5392 : inexact = real_arithmetic (&value, rtx_to_tree_code (code),
5690 : : &f0, &f1);
5691 : 5392 : real_convert (&result, mode, &value);
5692 : :
5693 : : /* Don't constant fold this floating point operation if
5694 : : the result has overflowed and flag_trapping_math. */
5695 : :
5696 : 5392 : if (flag_trapping_math
5697 : 20896 : && MODE_HAS_INFINITIES (mode)
5698 : 5224 : && REAL_VALUE_ISINF (result)
5699 : 1104 : && !REAL_VALUE_ISINF (f0)
5700 : 6482 : && !REAL_VALUE_ISINF (f1))
5701 : : /* Overflow plus exception. */
5702 : 1090 : return 0;
5703 : :
5704 : : /* Don't constant fold this floating point operation if the
5705 : : result may dependent upon the run-time rounding mode and
5706 : : flag_rounding_math is set, or if GCC's software emulation
5707 : : is unable to accurately represent the result. */
5708 : :
5709 : 4302 : if ((flag_rounding_math
5710 : 27433 : || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
5711 : 4302 : && (inexact || !real_identical (&result, &value)))
5712 : 378 : return NULL_RTX;
5713 : :
5714 : 3924 : return const_double_from_real_value (result, mode);
5715 : : }
5716 : : }
5717 : :
5718 : : /* We can fold some multi-word operations. */
5719 : 481866340 : scalar_int_mode int_mode;
5720 : 481866340 : if (is_a <scalar_int_mode> (mode, &int_mode)
5721 : 411987869 : && CONST_SCALAR_INT_P (op0)
5722 : 40438297 : && CONST_SCALAR_INT_P (op1)
5723 : 33939659 : && GET_MODE_PRECISION (int_mode) <= MAX_BITSIZE_MODE_ANY_INT)
5724 : : {
5725 : 33939659 : wide_int result;
5726 : 33939659 : wi::overflow_type overflow;
5727 : 33939659 : rtx_mode_t pop0 = rtx_mode_t (op0, int_mode);
5728 : 33939659 : rtx_mode_t pop1 = rtx_mode_t (op1, int_mode);
5729 : :
5730 : : #if TARGET_SUPPORTS_WIDE_INT == 0
5731 : : /* This assert keeps the simplification from producing a result
5732 : : that cannot be represented in a CONST_DOUBLE but a lot of
5733 : : upstream callers expect that this function never fails to
5734 : : simplify something and so you if you added this to the test
5735 : : above the code would die later anyway. If this assert
5736 : : happens, you just need to make the port support wide int. */
5737 : : gcc_assert (GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_DOUBLE_INT);
5738 : : #endif
5739 : 33939659 : switch (code)
5740 : : {
5741 : 1123425 : case MINUS:
5742 : 1123425 : result = wi::sub (pop0, pop1);
5743 : 1123425 : break;
5744 : :
5745 : 26660012 : case PLUS:
5746 : 26660012 : result = wi::add (pop0, pop1);
5747 : 26660012 : break;
5748 : :
5749 : 309101 : case MULT:
5750 : 309101 : result = wi::mul (pop0, pop1);
5751 : 309101 : break;
5752 : :
5753 : 5563 : case DIV:
5754 : 5563 : result = wi::div_trunc (pop0, pop1, SIGNED, &overflow);
5755 : 5563 : if (overflow)
5756 : : return NULL_RTX;
5757 : : break;
5758 : :
5759 : 223 : case MOD:
5760 : 223 : result = wi::mod_trunc (pop0, pop1, SIGNED, &overflow);
5761 : 223 : if (overflow)
5762 : : return NULL_RTX;
5763 : : break;
5764 : :
5765 : 6801 : case UDIV:
5766 : 6801 : result = wi::div_trunc (pop0, pop1, UNSIGNED, &overflow);
5767 : 6801 : if (overflow)
5768 : : return NULL_RTX;
5769 : : break;
5770 : :
5771 : 16564 : case UMOD:
5772 : 16564 : result = wi::mod_trunc (pop0, pop1, UNSIGNED, &overflow);
5773 : 16564 : if (overflow)
5774 : : return NULL_RTX;
5775 : : break;
5776 : :
5777 : 602274 : case AND:
5778 : 602274 : result = wi::bit_and (pop0, pop1);
5779 : 602274 : break;
5780 : :
5781 : 305092 : case IOR:
5782 : 305092 : result = wi::bit_or (pop0, pop1);
5783 : 305092 : break;
5784 : :
5785 : 90200 : case XOR:
5786 : 90200 : result = wi::bit_xor (pop0, pop1);
5787 : 90200 : break;
5788 : :
5789 : 1773 : case SMIN:
5790 : 1773 : result = wi::smin (pop0, pop1);
5791 : 1773 : break;
5792 : :
5793 : 1833 : case SMAX:
5794 : 1833 : result = wi::smax (pop0, pop1);
5795 : 1833 : break;
5796 : :
5797 : 3210 : case UMIN:
5798 : 3210 : result = wi::umin (pop0, pop1);
5799 : 3210 : break;
5800 : :
5801 : 2801 : case UMAX:
5802 : 2801 : result = wi::umax (pop0, pop1);
5803 : 2801 : break;
5804 : :
5805 : 4768092 : case LSHIFTRT:
5806 : 4768092 : case ASHIFTRT:
5807 : 4768092 : case ASHIFT:
5808 : 4768092 : case SS_ASHIFT:
5809 : 4768092 : case US_ASHIFT:
5810 : 4768092 : {
5811 : : /* The shift count might be in SImode while int_mode might
5812 : : be narrower. On IA-64 it is even DImode. If the shift
5813 : : count is too large and doesn't fit into int_mode, we'd
5814 : : ICE. So, if int_mode is narrower than word, use
5815 : : word_mode for the shift count. */
5816 : 4768092 : if (GET_MODE (op1) == VOIDmode
5817 : 5119432 : && GET_MODE_PRECISION (int_mode) < BITS_PER_WORD)
5818 : 1556672 : pop1 = rtx_mode_t (op1, word_mode);
5819 : :
5820 : 4768092 : wide_int wop1 = pop1;
5821 : 4768092 : if (SHIFT_COUNT_TRUNCATED)
5822 : : wop1 = wi::umod_trunc (wop1, GET_MODE_PRECISION (int_mode));
5823 : 4768092 : else if (wi::geu_p (wop1, GET_MODE_PRECISION (int_mode)))
5824 : 124 : return NULL_RTX;
5825 : :
5826 : 4767968 : switch (code)
5827 : : {
5828 : 2696554 : case LSHIFTRT:
5829 : 2696554 : result = wi::lrshift (pop0, wop1);
5830 : 2696554 : break;
5831 : :
5832 : 58114 : case ASHIFTRT:
5833 : 58114 : result = wi::arshift (pop0, wop1);
5834 : 58114 : break;
5835 : :
5836 : 2013300 : case ASHIFT:
5837 : 2013300 : result = wi::lshift (pop0, wop1);
5838 : 2013300 : break;
5839 : :
5840 : 0 : case SS_ASHIFT:
5841 : 0 : if (wi::leu_p (wop1, wi::clrsb (pop0)))
5842 : 0 : result = wi::lshift (pop0, wop1);
5843 : 0 : else if (wi::neg_p (pop0))
5844 : 0 : result = wi::min_value (int_mode, SIGNED);
5845 : : else
5846 : 0 : result = wi::max_value (int_mode, SIGNED);
5847 : : break;
5848 : :
5849 : 0 : case US_ASHIFT:
5850 : 0 : if (wi::eq_p (pop0, 0))
5851 : 0 : result = pop0;
5852 : 0 : else if (wi::leu_p (wop1, wi::clz (pop0)))
5853 : 0 : result = wi::lshift (pop0, wop1);
5854 : : else
5855 : 0 : result = wi::max_value (int_mode, UNSIGNED);
5856 : : break;
5857 : :
5858 : 0 : default:
5859 : 0 : gcc_unreachable ();
5860 : : }
5861 : 4767968 : break;
5862 : 4768092 : }
5863 : 34131 : case ROTATE:
5864 : 34131 : case ROTATERT:
5865 : 34131 : {
5866 : : /* The rotate count might be in SImode while int_mode might
5867 : : be narrower. On IA-64 it is even DImode. If the shift
5868 : : count is too large and doesn't fit into int_mode, we'd
5869 : : ICE. So, if int_mode is narrower than word, use
5870 : : word_mode for the shift count. */
5871 : 34131 : if (GET_MODE (op1) == VOIDmode
5872 : 42906 : && GET_MODE_PRECISION (int_mode) < BITS_PER_WORD)
5873 : 20207 : pop1 = rtx_mode_t (op1, word_mode);
5874 : :
5875 : 34131 : if (wi::neg_p (pop1))
5876 : : return NULL_RTX;
5877 : :
5878 : 34061 : switch (code)
5879 : : {
5880 : 11450 : case ROTATE:
5881 : 11450 : result = wi::lrotate (pop0, pop1);
5882 : 11450 : break;
5883 : :
5884 : 22611 : case ROTATERT:
5885 : 22611 : result = wi::rrotate (pop0, pop1);
5886 : 22611 : break;
5887 : :
5888 : 0 : default:
5889 : 0 : gcc_unreachable ();
5890 : : }
5891 : : break;
5892 : : }
5893 : :
5894 : 2270 : case SS_PLUS:
5895 : 2270 : result = wi::add (pop0, pop1, SIGNED, &overflow);
5896 : 4484 : clamp_signed_saturation:
5897 : 4484 : if (overflow == wi::OVF_OVERFLOW)
5898 : 314 : result = wi::max_value (GET_MODE_PRECISION (int_mode), SIGNED);
5899 : 4170 : else if (overflow == wi::OVF_UNDERFLOW)
5900 : 278 : result = wi::min_value (GET_MODE_PRECISION (int_mode), SIGNED);
5901 : 3892 : else if (overflow != wi::OVF_NONE)
5902 : : return NULL_RTX;
5903 : : break;
5904 : :
5905 : 2220 : case US_PLUS:
5906 : 2220 : result = wi::add (pop0, pop1, UNSIGNED, &overflow);
5907 : 2220 : clamp_unsigned_saturation:
5908 : 2220 : if (overflow != wi::OVF_NONE)
5909 : 461 : result = wi::max_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
5910 : : break;
5911 : :
5912 : 2214 : case SS_MINUS:
5913 : 2214 : result = wi::sub (pop0, pop1, SIGNED, &overflow);
5914 : 2214 : goto clamp_signed_saturation;
5915 : :
5916 : 1852 : case US_MINUS:
5917 : 1852 : result = wi::sub (pop0, pop1, UNSIGNED, &overflow);
5918 : 1852 : if (overflow != wi::OVF_NONE)
5919 : 1203 : result = wi::min_value (GET_MODE_PRECISION (int_mode), UNSIGNED);
5920 : : break;
5921 : :
5922 : 0 : case SS_MULT:
5923 : 0 : result = wi::mul (pop0, pop1, SIGNED, &overflow);
5924 : 0 : goto clamp_signed_saturation;
5925 : :
5926 : 0 : case US_MULT:
5927 : 0 : result = wi::mul (pop0, pop1, UNSIGNED, &overflow);
5928 : 0 : goto clamp_unsigned_saturation;
5929 : :
5930 : 8 : case SMUL_HIGHPART:
5931 : 8 : result = wi::mul_high (pop0, pop1, SIGNED);
5932 : 8 : break;
5933 : :
5934 : 0 : case UMUL_HIGHPART:
5935 : 0 : result = wi::mul_high (pop0, pop1, UNSIGNED);
5936 : 0 : break;
5937 : :
5938 : : default:
5939 : : return NULL_RTX;
5940 : : }
5941 : 33938920 : return immed_wide_int_const (result, int_mode);
5942 : 33939659 : }
5943 : :
5944 : : /* Handle polynomial integers. */
5945 : : if (NUM_POLY_INT_COEFFS > 1
5946 : : && is_a <scalar_int_mode> (mode, &int_mode)
5947 : : && poly_int_rtx_p (op0)
5948 : : && poly_int_rtx_p (op1))
5949 : : {
5950 : : poly_wide_int result;
5951 : : switch (code)
5952 : : {
5953 : : case PLUS:
5954 : : result = wi::to_poly_wide (op0, mode) + wi::to_poly_wide (op1, mode);
5955 : : break;
5956 : :
5957 : : case MINUS:
5958 : : result = wi::to_poly_wide (op0, mode) - wi::to_poly_wide (op1, mode);
5959 : : break;
5960 : :
5961 : : case MULT:
5962 : : if (CONST_SCALAR_INT_P (op1))
5963 : : result = wi::to_poly_wide (op0, mode) * rtx_mode_t (op1, mode);
5964 : : else
5965 : : return NULL_RTX;
5966 : : break;
5967 : :
5968 : : case ASHIFT:
5969 : : if (CONST_SCALAR_INT_P (op1))
5970 : : {
5971 : : wide_int shift
5972 : : = rtx_mode_t (op1,
5973 : : GET_MODE (op1) == VOIDmode
5974 : : && GET_MODE_PRECISION (int_mode) < BITS_PER_WORD
5975 : : ? word_mode : mode);
5976 : : if (SHIFT_COUNT_TRUNCATED)
5977 : : shift = wi::umod_trunc (shift, GET_MODE_PRECISION (int_mode));
5978 : : else if (wi::geu_p (shift, GET_MODE_PRECISION (int_mode)))
5979 : : return NULL_RTX;
5980 : : result = wi::to_poly_wide (op0, mode) << shift;
5981 : : }
5982 : : else
5983 : : return NULL_RTX;
5984 : : break;
5985 : :
5986 : : case IOR:
5987 : : if (!CONST_SCALAR_INT_P (op1)
5988 : : || !can_ior_p (wi::to_poly_wide (op0, mode),
5989 : : rtx_mode_t (op1, mode), &result))
5990 : : return NULL_RTX;
5991 : : break;
5992 : :
5993 : : default:
5994 : : return NULL_RTX;
5995 : : }
5996 : : return immed_wide_int_const (result, int_mode);
5997 : : }
5998 : :
5999 : : return NULL_RTX;
6000 : : }
6001 : :
6002 : :
6003 : :
6004 : : /* Return a positive integer if X should sort after Y. The value
6005 : : returned is 1 if and only if X and Y are both regs. */
6006 : :
6007 : : static int
6008 : 114067414 : simplify_plus_minus_op_data_cmp (rtx x, rtx y)
6009 : : {
6010 : 114067414 : int result;
6011 : :
6012 : 114067414 : result = (commutative_operand_precedence (y)
6013 : 114067414 : - commutative_operand_precedence (x));
6014 : 114067414 : if (result)
6015 : 79831482 : return result + result;
6016 : :
6017 : : /* Group together equal REGs to do more simplification. */
6018 : 34235932 : if (REG_P (x) && REG_P (y))
6019 : 8364141 : return REGNO (x) > REGNO (y);
6020 : :
6021 : : return 0;
6022 : : }
6023 : :
6024 : : /* Simplify and canonicalize a PLUS or MINUS, at least one of whose
6025 : : operands may be another PLUS or MINUS.
6026 : :
6027 : : Rather than test for specific case, we do this by a brute-force method
6028 : : and do all possible simplifications until no more changes occur. Then
6029 : : we rebuild the operation.
6030 : :
6031 : : May return NULL_RTX when no changes were made. */
6032 : :
6033 : : rtx
6034 : 38265733 : simplify_context::simplify_plus_minus (rtx_code code, machine_mode mode,
6035 : : rtx op0, rtx op1)
6036 : : {
6037 : 38265733 : struct simplify_plus_minus_op_data
6038 : : {
6039 : : rtx op;
6040 : : short neg;
6041 : : } ops[16];
6042 : 38265733 : rtx result, tem;
6043 : 38265733 : int n_ops = 2;
6044 : 38265733 : int changed, n_constants, canonicalized = 0;
6045 : 38265733 : int i, j;
6046 : :
6047 : 38265733 : memset (ops, 0, sizeof ops);
6048 : :
6049 : : /* Set up the two operands and then expand them until nothing has been
6050 : : changed. If we run out of room in our array, give up; this should
6051 : : almost never happen. */
6052 : :
6053 : 38265733 : ops[0].op = op0;
6054 : 38265733 : ops[0].neg = 0;
6055 : 38265733 : ops[1].op = op1;
6056 : 38265733 : ops[1].neg = (code == MINUS);
6057 : :
6058 : 77861542 : do
6059 : : {
6060 : 77861542 : changed = 0;
6061 : 77861542 : n_constants = 0;
6062 : :
6063 : 315256200 : for (i = 0; i < n_ops; i++)
6064 : : {
6065 : 237394672 : rtx this_op = ops[i].op;
6066 : 237394672 : int this_neg = ops[i].neg;
6067 : 237394672 : enum rtx_code this_code = GET_CODE (this_op);
6068 : :
6069 : 237394672 : switch (this_code)
6070 : : {
6071 : 38745071 : case PLUS:
6072 : 38745071 : case MINUS:
6073 : 38745071 : if (n_ops == ARRAY_SIZE (ops))
6074 : : return NULL_RTX;
6075 : :
6076 : 38745057 : ops[n_ops].op = XEXP (this_op, 1);
6077 : 38745057 : ops[n_ops].neg = (this_code == MINUS) ^ this_neg;
6078 : 38745057 : n_ops++;
6079 : :
6080 : 38745057 : ops[i].op = XEXP (this_op, 0);
6081 : 38745057 : changed = 1;
6082 : : /* If this operand was negated then we will potentially
6083 : : canonicalize the expression. Similarly if we don't
6084 : : place the operands adjacent we're re-ordering the
6085 : : expression and thus might be performing a
6086 : : canonicalization. Ignore register re-ordering.
6087 : : ??? It might be better to shuffle the ops array here,
6088 : : but then (plus (plus (A, B), plus (C, D))) wouldn't
6089 : : be seen as non-canonical. */
6090 : 38745057 : if (this_neg
6091 : 38020742 : || (i != n_ops - 2
6092 : 37335054 : && !(REG_P (ops[i].op) && REG_P (ops[n_ops - 1].op))))
6093 : 237394658 : canonicalized = 1;
6094 : : break;
6095 : :
6096 : 1679 : case NEG:
6097 : 1679 : ops[i].op = XEXP (this_op, 0);
6098 : 1679 : ops[i].neg = ! this_neg;
6099 : 1679 : changed = 1;
6100 : 1679 : canonicalized = 1;
6101 : 1679 : break;
6102 : :
6103 : 1473810 : case CONST:
6104 : 1473810 : if (n_ops != ARRAY_SIZE (ops)
6105 : 1473810 : && GET_CODE (XEXP (this_op, 0)) == PLUS
6106 : 1353198 : && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
6107 : 1329980 : && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
6108 : : {
6109 : 1329980 : ops[i].op = XEXP (XEXP (this_op, 0), 0);
6110 : 1329980 : ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
6111 : 1329980 : ops[n_ops].neg = this_neg;
6112 : 1329980 : n_ops++;
6113 : 1329980 : changed = 1;
6114 : 1329980 : canonicalized = 1;
6115 : : }
6116 : : break;
6117 : :
6118 : 40963 : case NOT:
6119 : : /* ~a -> (-a - 1) */
6120 : 40963 : if (n_ops != ARRAY_SIZE (ops))
6121 : : {
6122 : 40963 : ops[n_ops].op = CONSTM1_RTX (mode);
6123 : 40963 : ops[n_ops++].neg = this_neg;
6124 : 40963 : ops[i].op = XEXP (this_op, 0);
6125 : 40963 : ops[i].neg = !this_neg;
6126 : 40963 : changed = 1;
6127 : 40963 : canonicalized = 1;
6128 : : }
6129 : : break;
6130 : :
6131 : 120325091 : CASE_CONST_SCALAR_INT:
6132 : 120325091 : case CONST_POLY_INT:
6133 : 120325091 : n_constants++;
6134 : 120325091 : if (this_neg)
6135 : : {
6136 : 1181687 : ops[i].op = neg_poly_int_rtx (mode, this_op);
6137 : 1181687 : ops[i].neg = 0;
6138 : 1181687 : changed = 1;
6139 : 1181687 : canonicalized = 1;
6140 : : }
6141 : : break;
6142 : :
6143 : : default:
6144 : : break;
6145 : : }
6146 : : }
6147 : : }
6148 : 77861528 : while (changed);
6149 : :
6150 : 38265719 : if (n_constants > 1)
6151 : 24178514 : canonicalized = 1;
6152 : :
6153 : 38265719 : gcc_assert (n_ops >= 2);
6154 : :
6155 : : /* If we only have two operands, we can avoid the loops. */
6156 : 38265719 : if (n_ops == 2)
6157 : : {
6158 : 0 : enum rtx_code code = ops[0].neg || ops[1].neg ? MINUS : PLUS;
6159 : 0 : rtx lhs, rhs;
6160 : :
6161 : : /* Get the two operands. Be careful with the order, especially for
6162 : : the cases where code == MINUS. */
6163 : 0 : if (ops[0].neg && ops[1].neg)
6164 : : {
6165 : 0 : lhs = gen_rtx_NEG (mode, ops[0].op);
6166 : 0 : rhs = ops[1].op;
6167 : : }
6168 : 0 : else if (ops[0].neg)
6169 : : {
6170 : 0 : lhs = ops[1].op;
6171 : 0 : rhs = ops[0].op;
6172 : : }
6173 : : else
6174 : : {
6175 : 0 : lhs = ops[0].op;
6176 : 0 : rhs = ops[1].op;
6177 : : }
6178 : :
6179 : 0 : return simplify_const_binary_operation (code, mode, lhs, rhs);
6180 : : }
6181 : :
6182 : : /* Now simplify each pair of operands until nothing changes. */
6183 : 63238563 : while (1)
6184 : : {
6185 : : /* Insertion sort is good enough for a small array. */
6186 : 167045404 : for (i = 1; i < n_ops; i++)
6187 : : {
6188 : 103806841 : struct simplify_plus_minus_op_data save;
6189 : 103806841 : int cmp;
6190 : :
6191 : 103806841 : j = i - 1;
6192 : 103806841 : cmp = simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op);
6193 : 103806841 : if (cmp <= 0)
6194 : 91790750 : continue;
6195 : : /* Just swapping registers doesn't count as canonicalization. */
6196 : 12016091 : if (cmp != 1)
6197 : 9149787 : canonicalized = 1;
6198 : :
6199 : 12016091 : save = ops[i];
6200 : 14412548 : do
6201 : 14412548 : ops[j + 1] = ops[j];
6202 : 14412548 : while (j--
6203 : 26428639 : && simplify_plus_minus_op_data_cmp (ops[j].op, save.op) > 0);
6204 : 12016091 : ops[j + 1] = save;
6205 : : }
6206 : :
6207 : 63238563 : changed = 0;
6208 : 167045404 : for (i = n_ops - 1; i > 0; i--)
6209 : 249100724 : for (j = i - 1; j >= 0; j--)
6210 : : {
6211 : 146095879 : rtx lhs = ops[j].op, rhs = ops[i].op;
6212 : 146095879 : int lneg = ops[j].neg, rneg = ops[i].neg;
6213 : :
6214 : 146095879 : if (lhs != 0 && rhs != 0)
6215 : : {
6216 : 120311837 : enum rtx_code ncode = PLUS;
6217 : :
6218 : 120311837 : if (lneg != rneg)
6219 : : {
6220 : 10162933 : ncode = MINUS;
6221 : 10162933 : if (lneg)
6222 : 6581365 : std::swap (lhs, rhs);
6223 : : }
6224 : 110148904 : else if (swap_commutative_operands_p (lhs, rhs))
6225 : 214499 : std::swap (lhs, rhs);
6226 : :
6227 : 120311837 : if ((GET_CODE (lhs) == CONST || CONST_INT_P (lhs))
6228 : 28518086 : && (GET_CODE (rhs) == CONST || CONST_INT_P (rhs)))
6229 : : {
6230 : 24329476 : rtx tem_lhs, tem_rhs;
6231 : :
6232 : 24329476 : tem_lhs = GET_CODE (lhs) == CONST ? XEXP (lhs, 0) : lhs;
6233 : 24329476 : tem_rhs = GET_CODE (rhs) == CONST ? XEXP (rhs, 0) : rhs;
6234 : 24329476 : tem = simplify_binary_operation (ncode, mode, tem_lhs,
6235 : : tem_rhs);
6236 : :
6237 : 24329476 : if (tem && !CONSTANT_P (tem))
6238 : 1741 : tem = gen_rtx_CONST (GET_MODE (tem), tem);
6239 : : }
6240 : : else
6241 : 95982361 : tem = simplify_binary_operation (ncode, mode, lhs, rhs);
6242 : :
6243 : 95984102 : if (tem)
6244 : : {
6245 : : /* Reject "simplifications" that just wrap the two
6246 : : arguments in a CONST. Failure to do so can result
6247 : : in infinite recursion with simplify_binary_operation
6248 : : when it calls us to simplify CONST operations.
6249 : : Also, if we find such a simplification, don't try
6250 : : any more combinations with this rhs: We must have
6251 : : something like symbol+offset, ie. one of the
6252 : : trivial CONST expressions we handle later. */
6253 : 26264149 : if (GET_CODE (tem) == CONST
6254 : 803737 : && GET_CODE (XEXP (tem, 0)) == ncode
6255 : 803191 : && XEXP (XEXP (tem, 0), 0) == lhs
6256 : 801996 : && XEXP (XEXP (tem, 0), 1) == rhs)
6257 : : break;
6258 : 25462153 : lneg &= rneg;
6259 : 25462153 : if (GET_CODE (tem) == NEG)
6260 : 45429 : tem = XEXP (tem, 0), lneg = !lneg;
6261 : 25462153 : if (poly_int_rtx_p (tem) && lneg)
6262 : 0 : tem = neg_poly_int_rtx (mode, tem), lneg = 0;
6263 : :
6264 : 25462153 : ops[i].op = tem;
6265 : 25462153 : ops[i].neg = lneg;
6266 : 25462153 : ops[j].op = NULL_RTX;
6267 : 25462153 : changed = 1;
6268 : 25462153 : canonicalized = 1;
6269 : : }
6270 : : }
6271 : : }
6272 : :
6273 : 63238563 : if (!changed)
6274 : : break;
6275 : :
6276 : : /* Pack all the operands to the lower-numbered entries. */
6277 : 100833159 : for (i = 0, j = 0; j < n_ops; j++)
6278 : 75860315 : if (ops[j].op)
6279 : : {
6280 : 50398162 : ops[i] = ops[j];
6281 : 50398162 : i++;
6282 : : }
6283 : : n_ops = i;
6284 : : }
6285 : :
6286 : : /* If nothing changed, check that rematerialization of rtl instructions
6287 : : is still required. */
6288 : 38265719 : if (!canonicalized)
6289 : : {
6290 : : /* Perform rematerialization if only all operands are registers and
6291 : : all operations are PLUS. */
6292 : : /* ??? Also disallow (non-global, non-frame) fixed registers to work
6293 : : around rs6000 and how it uses the CA register. See PR67145. */
6294 : 5052265 : for (i = 0; i < n_ops; i++)
6295 : 4069977 : if (ops[i].neg
6296 : 3810938 : || !REG_P (ops[i].op)
6297 : 7305870 : || (REGNO (ops[i].op) < FIRST_PSEUDO_REGISTER
6298 : 318103 : && fixed_regs[REGNO (ops[i].op)]
6299 : 539 : && !global_regs[REGNO (ops[i].op)]
6300 : 539 : && ops[i].op != frame_pointer_rtx
6301 : 108 : && ops[i].op != arg_pointer_rtx
6302 : 94 : && ops[i].op != stack_pointer_rtx))
6303 : : return NULL_RTX;
6304 : 982288 : goto gen_result;
6305 : : }
6306 : :
6307 : : /* Create (minus -C X) instead of (neg (const (plus X C))). */
6308 : 36449347 : if (n_ops == 2
6309 : 23267890 : && CONST_INT_P (ops[1].op)
6310 : 22809747 : && CONSTANT_P (ops[0].op)
6311 : 210 : && ops[0].neg)
6312 : 104 : return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
6313 : :
6314 : : /* We suppressed creation of trivial CONST expressions in the
6315 : : combination loop to avoid recursion. Create one manually now.
6316 : : The combination loop should have ensured that there is exactly
6317 : : one CONST_INT, and the sort will have ensured that it is last
6318 : : in the array and that any other constant will be next-to-last. */
6319 : :
6320 : 36449243 : if (n_ops > 1
6321 : 35892506 : && poly_int_rtx_p (ops[n_ops - 1].op)
6322 : 70148673 : && CONSTANT_P (ops[n_ops - 2].op))
6323 : : {
6324 : 1398033 : rtx value = ops[n_ops - 1].op;
6325 : 1398033 : if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg)
6326 : 681774 : value = neg_poly_int_rtx (mode, value);
6327 : 1398033 : if (CONST_INT_P (value))
6328 : : {
6329 : 2796066 : ops[n_ops - 2].op = plus_constant (mode, ops[n_ops - 2].op,
6330 : 1398033 : INTVAL (value));
6331 : 1398033 : n_ops--;
6332 : : }
6333 : : }
6334 : :
6335 : : /* Put a non-negated operand first, if possible. */
6336 : :
6337 : 38117308 : for (i = 0; i < n_ops && ops[i].neg; i++)
6338 : 1668065 : continue;
6339 : 36449243 : if (i == n_ops)
6340 : 9819 : ops[0].op = gen_rtx_NEG (mode, ops[0].op);
6341 : 36439424 : else if (i != 0)
6342 : : {
6343 : 1568126 : tem = ops[0].op;
6344 : 1568126 : ops[0] = ops[i];
6345 : 1568126 : ops[i].op = tem;
6346 : 1568126 : ops[i].neg = 1;
6347 : : }
6348 : :
6349 : : /* Now make the result by performing the requested operations. */
6350 : 34871298 : gen_result:
6351 : 37431531 : result = ops[0].op;
6352 : 87282747 : for (i = 1; i < n_ops; i++)
6353 : 99702432 : result = gen_rtx_fmt_ee (ops[i].neg ? MINUS : PLUS,
6354 : : mode, result, ops[i].op);
6355 : :
6356 : : return result;
6357 : 1668065 : }
6358 : :
6359 : : /* Check whether an operand is suitable for calling simplify_plus_minus. */
6360 : : static bool
6361 : 516928424 : plus_minus_operand_p (const_rtx x)
6362 : : {
6363 : 516928424 : return GET_CODE (x) == PLUS
6364 : 516928424 : || GET_CODE (x) == MINUS
6365 : 516928424 : || (GET_CODE (x) == CONST
6366 : 1841010 : && GET_CODE (XEXP (x, 0)) == PLUS
6367 : 1237616 : && CONSTANT_P (XEXP (XEXP (x, 0), 0))
6368 : 1160749 : && CONSTANT_P (XEXP (XEXP (x, 0), 1)));
6369 : : }
6370 : :
6371 : : /* Like simplify_binary_operation except used for relational operators.
6372 : : MODE is the mode of the result. If MODE is VOIDmode, both operands must
6373 : : not also be VOIDmode.
6374 : :
6375 : : CMP_MODE specifies in which mode the comparison is done in, so it is
6376 : : the mode of the operands. If CMP_MODE is VOIDmode, it is taken from
6377 : : the operands or, if both are VOIDmode, the operands are compared in
6378 : : "infinite precision". */
6379 : : rtx
6380 : 130558854 : simplify_context::simplify_relational_operation (rtx_code code,
6381 : : machine_mode mode,
6382 : : machine_mode cmp_mode,
6383 : : rtx op0, rtx op1)
6384 : : {
6385 : 130558854 : rtx tem, trueop0, trueop1;
6386 : :
6387 : 130558854 : if (cmp_mode == VOIDmode)
6388 : 28338230 : cmp_mode = GET_MODE (op0);
6389 : 28338230 : if (cmp_mode == VOIDmode)
6390 : 454604 : cmp_mode = GET_MODE (op1);
6391 : :
6392 : 130558854 : tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
6393 : 130558854 : if (tem)
6394 : 857138 : return relational_result (mode, cmp_mode, tem);
6395 : :
6396 : : /* For the following tests, ensure const0_rtx is op1. */
6397 : 129701716 : if (swap_commutative_operands_p (op0, op1)
6398 : 129701716 : || (op0 == const0_rtx && op1 != const0_rtx))
6399 : 2617129 : std::swap (op0, op1), code = swap_condition (code);
6400 : :
6401 : : /* If op0 is a compare, extract the comparison arguments from it. */
6402 : 129701716 : if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
6403 : 13791353 : return simplify_gen_relational (code, mode, VOIDmode,
6404 : 13791353 : XEXP (op0, 0), XEXP (op0, 1));
6405 : :
6406 : 115910363 : if (GET_MODE_CLASS (cmp_mode) == MODE_CC)
6407 : : return NULL_RTX;
6408 : :
6409 : 85051982 : trueop0 = avoid_constant_pool_reference (op0);
6410 : 85051982 : trueop1 = avoid_constant_pool_reference (op1);
6411 : 85051982 : return simplify_relational_operation_1 (code, mode, cmp_mode,
6412 : 85051982 : trueop0, trueop1);
6413 : : }
6414 : :
6415 : : /* This part of simplify_relational_operation is only used when CMP_MODE
6416 : : is not in class MODE_CC (i.e. it is a real comparison).
6417 : :
6418 : : MODE is the mode of the result, while CMP_MODE specifies in which
6419 : : mode the comparison is done in, so it is the mode of the operands. */
6420 : :
6421 : : rtx
6422 : 85051982 : simplify_context::simplify_relational_operation_1 (rtx_code code,
6423 : : machine_mode mode,
6424 : : machine_mode cmp_mode,
6425 : : rtx op0, rtx op1)
6426 : : {
6427 : 85051982 : enum rtx_code op0code = GET_CODE (op0);
6428 : :
6429 : 85051982 : if (op1 == const0_rtx && COMPARISON_P (op0))
6430 : : {
6431 : : /* If op0 is a comparison, extract the comparison arguments
6432 : : from it. */
6433 : 467249 : if (code == NE)
6434 : : {
6435 : 214788 : if (GET_MODE (op0) == mode)
6436 : 164 : return simplify_rtx (op0);
6437 : : else
6438 : 214624 : return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
6439 : 214624 : XEXP (op0, 0), XEXP (op0, 1));
6440 : : }
6441 : 252461 : else if (code == EQ)
6442 : : {
6443 : 126993 : enum rtx_code new_code = reversed_comparison_code (op0, NULL);
6444 : 126993 : if (new_code != UNKNOWN)
6445 : 126689 : return simplify_gen_relational (new_code, mode, VOIDmode,
6446 : 126689 : XEXP (op0, 0), XEXP (op0, 1));
6447 : : }
6448 : : }
6449 : :
6450 : : /* (LTU/GEU (PLUS a C) C), where C is constant, can be simplified to
6451 : : (GEU/LTU a -C). Likewise for (LTU/GEU (PLUS a C) a). */
6452 : 84710505 : if ((code == LTU || code == GEU)
6453 : 5032233 : && GET_CODE (op0) == PLUS
6454 : 675938 : && CONST_INT_P (XEXP (op0, 1))
6455 : 449877 : && (rtx_equal_p (op1, XEXP (op0, 0))
6456 : 331610 : || rtx_equal_p (op1, XEXP (op0, 1)))
6457 : : /* (LTU/GEU (PLUS a 0) 0) is not the same as (GEU/LTU a 0). */
6458 : 84895990 : && XEXP (op0, 1) != const0_rtx)
6459 : : {
6460 : 185485 : rtx new_cmp
6461 : 185485 : = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
6462 : 187688 : return simplify_gen_relational ((code == LTU ? GEU : LTU), mode,
6463 : 185485 : cmp_mode, XEXP (op0, 0), new_cmp);
6464 : : }
6465 : :
6466 : : /* (GTU (PLUS a C) (C - 1)) where C is a non-zero constant can be
6467 : : transformed into (LTU a -C). */
6468 : 84525020 : if (code == GTU && GET_CODE (op0) == PLUS && CONST_INT_P (op1)
6469 : 369737 : && CONST_INT_P (XEXP (op0, 1))
6470 : 299496 : && (UINTVAL (op1) == UINTVAL (XEXP (op0, 1)) - 1)
6471 : 28500 : && XEXP (op0, 1) != const0_rtx)
6472 : : {
6473 : 28500 : rtx new_cmp
6474 : 28500 : = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
6475 : 28500 : return simplify_gen_relational (LTU, mode, cmp_mode,
6476 : 28500 : XEXP (op0, 0), new_cmp);
6477 : : }
6478 : :
6479 : : /* Canonicalize (LTU/GEU (PLUS a b) b) as (LTU/GEU (PLUS a b) a). */
6480 : 84496520 : if ((code == LTU || code == GEU)
6481 : 4846748 : && GET_CODE (op0) == PLUS
6482 : 490453 : && rtx_equal_p (op1, XEXP (op0, 1))
6483 : : /* Don't recurse "infinitely" for (LTU/GEU (PLUS b b) b). */
6484 : 84501820 : && !rtx_equal_p (op1, XEXP (op0, 0)))
6485 : 5300 : return simplify_gen_relational (code, mode, cmp_mode, op0,
6486 : 5300 : copy_rtx (XEXP (op0, 0)));
6487 : :
6488 : 84491220 : if (op1 == const0_rtx)
6489 : : {
6490 : : /* Canonicalize (GTU x 0) as (NE x 0). */
6491 : 37582079 : if (code == GTU)
6492 : 176117 : return simplify_gen_relational (NE, mode, cmp_mode, op0, op1);
6493 : : /* Canonicalize (LEU x 0) as (EQ x 0). */
6494 : 37405962 : if (code == LEU)
6495 : 51337 : return simplify_gen_relational (EQ, mode, cmp_mode, op0, op1);
6496 : :
6497 : 37354625 : if ((code == NE || code == EQ)
6498 : : /* Verify op0 is IOR */
6499 : 33756579 : && GET_CODE (op0) == IOR
6500 : : /* only enters if op1 is 0 */
6501 : : /* Verify IOR operand is NE */
6502 : 532490 : && GET_CODE (XEXP (op0, 0)) == NE
6503 : : /* Verify second NE operand is 0 */
6504 : 6239 : && XEXP (XEXP (op0, 0), 1) == CONST0_RTX (mode))
6505 : : {
6506 : 6239 : rtx t = gen_rtx_IOR (cmp_mode, XEXP (XEXP (op0, 0), 0), XEXP (op0, 1));
6507 : 6239 : t = gen_rtx_fmt_ee (code, mode, t, CONST0_RTX (mode));
6508 : 6239 : return t;
6509 : : }
6510 : :
6511 : : }
6512 : 46909141 : else if (op1 == const1_rtx)
6513 : : {
6514 : 3222416 : switch (code)
6515 : : {
6516 : 9107 : case GE:
6517 : : /* Canonicalize (GE x 1) as (GT x 0). */
6518 : 9107 : return simplify_gen_relational (GT, mode, cmp_mode,
6519 : 9107 : op0, const0_rtx);
6520 : 177180 : case GEU:
6521 : : /* Canonicalize (GEU x 1) as (NE x 0). */
6522 : 177180 : return simplify_gen_relational (NE, mode, cmp_mode,
6523 : 177180 : op0, const0_rtx);
6524 : 10494 : case LT:
6525 : : /* Canonicalize (LT x 1) as (LE x 0). */
6526 : 10494 : return simplify_gen_relational (LE, mode, cmp_mode,
6527 : 10494 : op0, const0_rtx);
6528 : 55407 : case LTU:
6529 : : /* Canonicalize (LTU x 1) as (EQ x 0). */
6530 : 55407 : return simplify_gen_relational (EQ, mode, cmp_mode,
6531 : 55407 : op0, const0_rtx);
6532 : : default:
6533 : : break;
6534 : : }
6535 : : }
6536 : 43686725 : else if (op1 == constm1_rtx)
6537 : : {
6538 : : /* Canonicalize (LE x -1) as (LT x 0). */
6539 : 1170973 : if (code == LE)
6540 : 1662 : return simplify_gen_relational (LT, mode, cmp_mode, op0, const0_rtx);
6541 : : /* Canonicalize (GT x -1) as (GE x 0). */
6542 : 1169311 : if (code == GT)
6543 : 5031 : return simplify_gen_relational (GE, mode, cmp_mode, op0, const0_rtx);
6544 : : }
6545 : :
6546 : : /* (eq/ne (plus x cst1) cst2) simplifies to (eq/ne x (cst2 - cst1)) */
6547 : 80400600 : if ((code == EQ || code == NE)
6548 : 63236710 : && (op0code == PLUS || op0code == MINUS)
6549 : 2323726 : && CONSTANT_P (op1)
6550 : 971144 : && CONSTANT_P (XEXP (op0, 1))
6551 : 543341 : && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
6552 : : {
6553 : 543309 : rtx x = XEXP (op0, 0);
6554 : 543309 : rtx c = XEXP (op0, 1);
6555 : 543309 : enum rtx_code invcode = op0code == PLUS ? MINUS : PLUS;
6556 : 543309 : rtx tem = simplify_gen_binary (invcode, cmp_mode, op1, c);
6557 : :
6558 : : /* Detect an infinite recursive condition, where we oscillate at this
6559 : : simplification case between:
6560 : : A + B == C <---> C - B == A,
6561 : : where A, B, and C are all constants with non-simplifiable expressions,
6562 : : usually SYMBOL_REFs. */
6563 : 543309 : if (GET_CODE (tem) == invcode
6564 : 46 : && CONSTANT_P (x)
6565 : 543327 : && rtx_equal_p (c, XEXP (tem, 1)))
6566 : : return NULL_RTX;
6567 : :
6568 : 543291 : return simplify_gen_relational (code, mode, cmp_mode, x, tem);
6569 : : }
6570 : :
6571 : : /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is
6572 : : the same as (zero_extract:SI FOO (const_int 1) BAR). */
6573 : 62693401 : scalar_int_mode int_mode, int_cmp_mode;
6574 : 62693401 : if (code == NE
6575 : 33118691 : && op1 == const0_rtx
6576 : 2190042 : && is_int_mode (mode, &int_mode)
6577 : 83400752 : && is_a <scalar_int_mode> (cmp_mode, &int_cmp_mode)
6578 : : /* ??? Work-around BImode bugs in the ia64 backend. */
6579 : 2190042 : && int_mode != BImode
6580 : 2190022 : && int_cmp_mode != BImode
6581 : 2190022 : && nonzero_bits (op0, int_cmp_mode) == 1
6582 : 62693401 : && STORE_FLAG_VALUE == 1)
6583 : 109170 : return GET_MODE_SIZE (int_mode) > GET_MODE_SIZE (int_cmp_mode)
6584 : 54585 : ? simplify_gen_unary (ZERO_EXTEND, int_mode, op0, int_cmp_mode)
6585 : 22841 : : lowpart_subreg (int_mode, op0, int_cmp_mode);
6586 : :
6587 : : /* (eq/ne (xor x y) 0) simplifies to (eq/ne x y). */
6588 : 83400752 : if ((code == EQ || code == NE)
6589 : 62638816 : && op1 == const0_rtx
6590 : 33618432 : && op0code == XOR)
6591 : 14110 : return simplify_gen_relational (code, mode, cmp_mode,
6592 : 14110 : XEXP (op0, 0), XEXP (op0, 1));
6593 : :
6594 : : /* (eq/ne (xor x y) x) simplifies to (eq/ne y 0). */
6595 : 62624706 : if ((code == EQ || code == NE)
6596 : 62624706 : && op0code == XOR
6597 : 4613 : && rtx_equal_p (XEXP (op0, 0), op1)
6598 : 0 : && !side_effects_p (XEXP (op0, 0)))
6599 : 0 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 1),
6600 : 0 : CONST0_RTX (mode));
6601 : :
6602 : : /* Likewise (eq/ne (xor x y) y) simplifies to (eq/ne x 0). */
6603 : 83386642 : if ((code == EQ || code == NE)
6604 : 62624706 : && op0code == XOR
6605 : 4613 : && rtx_equal_p (XEXP (op0, 1), op1)
6606 : 83386776 : && !side_effects_p (XEXP (op0, 1)))
6607 : 134 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6608 : 134 : CONST0_RTX (mode));
6609 : :
6610 : : /* (eq/ne (xor x C1) C2) simplifies to (eq/ne x (C1^C2)). */
6611 : 83386508 : if ((code == EQ || code == NE)
6612 : 62624572 : && op0code == XOR
6613 : 4479 : && CONST_SCALAR_INT_P (op1)
6614 : 1142 : && CONST_SCALAR_INT_P (XEXP (op0, 1)))
6615 : 602 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6616 : : simplify_gen_binary (XOR, cmp_mode,
6617 : 602 : XEXP (op0, 1), op1));
6618 : :
6619 : : /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or
6620 : : constant folding if x/y is a constant. */
6621 : 62623970 : if ((code == EQ || code == NE)
6622 : 62623970 : && (op0code == AND || op0code == IOR)
6623 : 4031703 : && !side_effects_p (op1)
6624 : 4031659 : && op1 != CONST0_RTX (cmp_mode))
6625 : : {
6626 : : /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to
6627 : : (eq/ne (and (not y) x) 0). */
6628 : 542540 : if ((op0code == AND && rtx_equal_p (XEXP (op0, 0), op1))
6629 : 1082062 : || (op0code == IOR && rtx_equal_p (XEXP (op0, 1), op1)))
6630 : : {
6631 : 25271 : rtx not_y = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 1),
6632 : : cmp_mode);
6633 : 25271 : rtx lhs = simplify_gen_binary (AND, cmp_mode, not_y, XEXP (op0, 0));
6634 : :
6635 : 25271 : return simplify_gen_relational (code, mode, cmp_mode, lhs,
6636 : 25271 : CONST0_RTX (cmp_mode));
6637 : : }
6638 : :
6639 : : /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to
6640 : : (eq/ne (and (not x) y) 0). */
6641 : 517337 : if ((op0code == AND && rtx_equal_p (XEXP (op0, 1), op1))
6642 : 1011725 : || (op0code == IOR && rtx_equal_p (XEXP (op0, 0), op1)))
6643 : : {
6644 : 45086 : rtx not_x = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 0),
6645 : : cmp_mode);
6646 : 45086 : rtx lhs = simplify_gen_binary (AND, cmp_mode, not_x, XEXP (op0, 1));
6647 : :
6648 : 45086 : return simplify_gen_relational (code, mode, cmp_mode, lhs,
6649 : 45086 : CONST0_RTX (cmp_mode));
6650 : : }
6651 : : }
6652 : :
6653 : : /* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped. */
6654 : 83315549 : if ((code == EQ || code == NE)
6655 : 62553613 : && GET_CODE (op0) == BSWAP
6656 : 324 : && CONST_SCALAR_INT_P (op1))
6657 : 93 : return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
6658 : : simplify_gen_unary (BSWAP, cmp_mode,
6659 : 93 : op1, cmp_mode));
6660 : :
6661 : : /* (eq/ne (bswap x) (bswap y)) simplifies to (eq/ne x y). */
6662 : 62553520 : if ((code == EQ || code == NE)
6663 : 62553520 : && GET_CODE (op0) == BSWAP
6664 : 231 : && GET_CODE (op1) == BSWAP)
6665 : 18 : return simplify_gen_relational (code, mode, cmp_mode,
6666 : 18 : XEXP (op0, 0), XEXP (op1, 0));
6667 : :
6668 : 83315438 : if (op0code == POPCOUNT && op1 == const0_rtx)
6669 : 0 : switch (code)
6670 : : {
6671 : 0 : case EQ:
6672 : 0 : case LE:
6673 : 0 : case LEU:
6674 : : /* (eq (popcount x) (const_int 0)) -> (eq x (const_int 0)). */
6675 : 0 : return simplify_gen_relational (EQ, mode, GET_MODE (XEXP (op0, 0)),
6676 : : XEXP (op0, 0),
6677 : 0 : CONST0_RTX (GET_MODE (XEXP (op0, 0))));
6678 : :
6679 : 0 : case NE:
6680 : 0 : case GT:
6681 : 0 : case GTU:
6682 : : /* (ne (popcount x) (const_int 0)) -> (ne x (const_int 0)). */
6683 : 0 : return simplify_gen_relational (NE, mode, GET_MODE (XEXP (op0, 0)),
6684 : : XEXP (op0, 0),
6685 : 0 : CONST0_RTX (GET_MODE (XEXP (op0, 0))));
6686 : :
6687 : : default:
6688 : : break;
6689 : : }
6690 : :
6691 : : /* (ne:SI (subreg:QI (ashift:SI x 7) 0) 0) -> (and:SI x 1). */
6692 : 83315438 : if (code == NE
6693 : 33017687 : && op1 == const0_rtx
6694 : 16470156 : && (op0code == TRUNCATE
6695 : 148069 : || (partial_subreg_p (op0)
6696 : 147405 : && subreg_lowpart_p (op0)))
6697 : 124921 : && SCALAR_INT_MODE_P (mode)
6698 : 83315438 : && STORE_FLAG_VALUE == 1)
6699 : : {
6700 : 30489 : rtx tmp = XEXP (op0, 0);
6701 : 30489 : if (GET_CODE (tmp) == ASHIFT
6702 : 1870 : && GET_MODE (tmp) == mode
6703 : 188 : && CONST_INT_P (XEXP (tmp, 1))
6704 : 188 : && is_int_mode (GET_MODE (op0), &int_mode)
6705 : 30677 : && INTVAL (XEXP (tmp, 1)) == GET_MODE_PRECISION (int_mode) - 1)
6706 : 188 : return simplify_gen_binary (AND, mode, XEXP (tmp, 0), const1_rtx);
6707 : : }
6708 : :
6709 : : /* For two unsigned booleans A and B:
6710 : :
6711 : : A > B == ~B & A
6712 : : A >= B == ~B | A
6713 : : A < B == ~A & B
6714 : : A <= B == ~A | B
6715 : : A == B == ~A ^ B (== ~B ^ A)
6716 : : A != B == A ^ B
6717 : :
6718 : : For signed comparisons, we have to take STORE_FLAG_VALUE into account,
6719 : : with the rules above applying for positive STORE_FLAG_VALUE and with
6720 : : the relations reversed for negative STORE_FLAG_VALUE. */
6721 : 83315250 : if (is_a<scalar_int_mode> (cmp_mode)
6722 : 80890707 : && COMPARISON_P (op0)
6723 : 83380753 : && COMPARISON_P (op1))
6724 : : {
6725 : 9853 : rtx t = NULL_RTX;
6726 : 9853 : if (code == GTU || code == (STORE_FLAG_VALUE > 0 ? GT : LT))
6727 : 755 : t = simplify_logical_relational_operation (AND, mode, op1, op0, true);
6728 : : else if (code == GEU || code == (STORE_FLAG_VALUE > 0 ? GE : LE))
6729 : 720 : t = simplify_logical_relational_operation (IOR, mode, op1, op0, true);
6730 : : else if (code == LTU || code == (STORE_FLAG_VALUE > 0 ? LT : GT))
6731 : 720 : t = simplify_logical_relational_operation (AND, mode, op0, op1, true);
6732 : : else if (code == LEU || code == (STORE_FLAG_VALUE > 0 ? LE : GE))
6733 : 720 : t = simplify_logical_relational_operation (IOR, mode, op0, op1, true);
6734 : : else if (code == EQ)
6735 : 3126 : t = simplify_logical_relational_operation (XOR, mode, op0, op1, true);
6736 : : else if (code == NE)
6737 : 3812 : t = simplify_logical_relational_operation (XOR, mode, op0, op1);
6738 : 9853 : if (t)
6739 : : return t;
6740 : : }
6741 : :
6742 : : return NULL_RTX;
6743 : : }
6744 : :
6745 : : enum
6746 : : {
6747 : : CMP_EQ = 1,
6748 : : CMP_LT = 2,
6749 : : CMP_GT = 4,
6750 : : CMP_LTU = 8,
6751 : : CMP_GTU = 16
6752 : : };
6753 : :
6754 : :
6755 : : /* Convert the known results for EQ, LT, GT, LTU, GTU contained in
6756 : : KNOWN_RESULT to a CONST_INT, based on the requested comparison CODE
6757 : : For KNOWN_RESULT to make sense it should be either CMP_EQ, or the
6758 : : logical OR of one of (CMP_LT, CMP_GT) and one of (CMP_LTU, CMP_GTU).
6759 : : For floating-point comparisons, assume that the operands were ordered. */
6760 : :
6761 : : static rtx
6762 : 690686 : comparison_result (enum rtx_code code, int known_results)
6763 : : {
6764 : 690686 : switch (code)
6765 : : {
6766 : 131082 : case EQ:
6767 : 131082 : case UNEQ:
6768 : 131082 : return (known_results & CMP_EQ) ? const_true_rtx : const0_rtx;
6769 : 445170 : case NE:
6770 : 445170 : case LTGT:
6771 : 445170 : return (known_results & CMP_EQ) ? const0_rtx : const_true_rtx;
6772 : :
6773 : 9443 : case LT:
6774 : 9443 : case UNLT:
6775 : 9443 : return (known_results & CMP_LT) ? const_true_rtx : const0_rtx;
6776 : 8554 : case GE:
6777 : 8554 : case UNGE:
6778 : 8554 : return (known_results & CMP_LT) ? const0_rtx : const_true_rtx;
6779 : :
6780 : 13036 : case GT:
6781 : 13036 : case UNGT:
6782 : 13036 : return (known_results & CMP_GT) ? const_true_rtx : const0_rtx;
6783 : 14748 : case LE:
6784 : 14748 : case UNLE:
6785 : 14748 : return (known_results & CMP_GT) ? const0_rtx : const_true_rtx;
6786 : :
6787 : 12715 : case LTU:
6788 : 12715 : return (known_results & CMP_LTU) ? const_true_rtx : const0_rtx;
6789 : 8919 : case GEU:
6790 : 8919 : return (known_results & CMP_LTU) ? const0_rtx : const_true_rtx;
6791 : :
6792 : 35752 : case GTU:
6793 : 35752 : return (known_results & CMP_GTU) ? const_true_rtx : const0_rtx;
6794 : 11259 : case LEU:
6795 : 11259 : return (known_results & CMP_GTU) ? const0_rtx : const_true_rtx;
6796 : :
6797 : 0 : case ORDERED:
6798 : 0 : return const_true_rtx;
6799 : 8 : case UNORDERED:
6800 : 8 : return const0_rtx;
6801 : 0 : default:
6802 : 0 : gcc_unreachable ();
6803 : : }
6804 : : }
6805 : :
6806 : : /* Check if the given comparison (done in the given MODE) is actually
6807 : : a tautology or a contradiction. If the mode is VOIDmode, the
6808 : : comparison is done in "infinite precision". If no simplification
6809 : : is possible, this function returns zero. Otherwise, it returns
6810 : : either const_true_rtx or const0_rtx. */
6811 : :
6812 : : rtx
6813 : 130648998 : simplify_const_relational_operation (enum rtx_code code,
6814 : : machine_mode mode,
6815 : : rtx op0, rtx op1)
6816 : : {
6817 : 137394627 : rtx tem;
6818 : 137394627 : rtx trueop0;
6819 : 137394627 : rtx trueop1;
6820 : :
6821 : 137394627 : gcc_assert (mode != VOIDmode
6822 : : || (GET_MODE (op0) == VOIDmode
6823 : : && GET_MODE (op1) == VOIDmode));
6824 : :
6825 : : /* We only handle MODE_CC comparisons that are COMPARE against zero. */
6826 : 137394627 : if (GET_MODE_CLASS (mode) == MODE_CC
6827 : 44654635 : && (op1 != const0_rtx
6828 : 44654635 : || GET_CODE (op0) != COMPARE))
6829 : : return NULL_RTX;
6830 : :
6831 : : /* If op0 is a compare, extract the comparison arguments from it. */
6832 : 106536246 : if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
6833 : : {
6834 : 13796254 : op1 = XEXP (op0, 1);
6835 : 13796254 : op0 = XEXP (op0, 0);
6836 : :
6837 : 13796254 : if (GET_MODE (op0) != VOIDmode)
6838 : 13684239 : mode = GET_MODE (op0);
6839 : 112015 : else if (GET_MODE (op1) != VOIDmode)
6840 : 102448 : mode = GET_MODE (op1);
6841 : : else
6842 : : return 0;
6843 : : }
6844 : :
6845 : : /* We can't simplify MODE_CC values since we don't know what the
6846 : : actual comparison is. */
6847 : 106526679 : if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
6848 : : return 0;
6849 : :
6850 : : /* Make sure the constant is second. */
6851 : 106526679 : if (swap_commutative_operands_p (op0, op1))
6852 : : {
6853 : 3103234 : std::swap (op0, op1);
6854 : 3103234 : code = swap_condition (code);
6855 : : }
6856 : :
6857 : 106526679 : trueop0 = avoid_constant_pool_reference (op0);
6858 : 106526679 : trueop1 = avoid_constant_pool_reference (op1);
6859 : :
6860 : : /* For integer comparisons of A and B maybe we can simplify A - B and can
6861 : : then simplify a comparison of that with zero. If A and B are both either
6862 : : a register or a CONST_INT, this can't help; testing for these cases will
6863 : : prevent infinite recursion here and speed things up.
6864 : :
6865 : : We can only do this for EQ and NE comparisons as otherwise we may
6866 : : lose or introduce overflow which we cannot disregard as undefined as
6867 : : we do not know the signedness of the operation on either the left or
6868 : : the right hand side of the comparison. */
6869 : :
6870 : 106526679 : if (INTEGRAL_MODE_P (mode)
6871 : 104204491 : && trueop1 != CONST0_RTX (mode)
6872 : 53282776 : && (code == EQ || code == NE)
6873 : 34093796 : && ! ((REG_P (op0)
6874 : 9544698 : || CONST_SCALAR_INT_P (trueop0)
6875 : 9516212 : || CONST_VECTOR_P (trueop0))
6876 : 24577604 : && (REG_P (op1)
6877 : 14952452 : || CONST_SCALAR_INT_P (trueop1)
6878 : 3319008 : || CONST_VECTOR_P (trueop1)))
6879 : 12833340 : && (tem = simplify_binary_operation (MINUS, mode, op0, op1)) != 0
6880 : : /* We cannot do this if tem is a nonzero address. */
6881 : 6745631 : && ! nonzero_address_p (tem))
6882 : 6745629 : return simplify_const_relational_operation (signed_condition (code),
6883 : 6745629 : mode, tem, CONST0_RTX (mode));
6884 : :
6885 : 99781050 : if (! HONOR_NANS (mode) && code == ORDERED)
6886 : 0 : return const_true_rtx;
6887 : :
6888 : 99781050 : if (! HONOR_NANS (mode) && code == UNORDERED)
6889 : 8 : return const0_rtx;
6890 : :
6891 : : /* For modes without NaNs, if the two operands are equal, we know the
6892 : : result except if they have side-effects. Even with NaNs we know
6893 : : the result of unordered comparisons and, if signaling NaNs are
6894 : : irrelevant, also the result of LT/GT/LTGT. */
6895 : 99781042 : if ((! HONOR_NANS (trueop0)
6896 : 2107112 : || code == UNEQ || code == UNLE || code == UNGE
6897 : : || ((code == LT || code == GT || code == LTGT)
6898 : 838153 : && ! HONOR_SNANS (trueop0)))
6899 : 98617188 : && rtx_equal_p (trueop0, trueop1)
6900 : 100264820 : && ! side_effects_p (trueop0))
6901 : 483770 : return comparison_result (code, CMP_EQ);
6902 : :
6903 : : /* If the operands are floating-point constants, see if we can fold
6904 : : the result. */
6905 : 99297272 : if (CONST_DOUBLE_AS_FLOAT_P (trueop0)
6906 : 1298 : && CONST_DOUBLE_AS_FLOAT_P (trueop1)
6907 : 1298 : && SCALAR_FLOAT_MODE_P (GET_MODE (trueop0)))
6908 : : {
6909 : 1298 : const REAL_VALUE_TYPE *d0 = CONST_DOUBLE_REAL_VALUE (trueop0);
6910 : 1298 : const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
6911 : :
6912 : : /* Comparisons are unordered iff at least one of the values is NaN. */
6913 : 1298 : if (REAL_VALUE_ISNAN (*d0) || REAL_VALUE_ISNAN (*d1))
6914 : 180 : switch (code)
6915 : : {
6916 : 0 : case UNEQ:
6917 : 0 : case UNLT:
6918 : 0 : case UNGT:
6919 : 0 : case UNLE:
6920 : 0 : case UNGE:
6921 : 0 : case NE:
6922 : 0 : case UNORDERED:
6923 : 0 : return const_true_rtx;
6924 : 180 : case EQ:
6925 : 180 : case LT:
6926 : 180 : case GT:
6927 : 180 : case LE:
6928 : 180 : case GE:
6929 : 180 : case LTGT:
6930 : 180 : case ORDERED:
6931 : 180 : return const0_rtx;
6932 : : default:
6933 : : return 0;
6934 : : }
6935 : :
6936 : 1207 : return comparison_result (code,
6937 : 1207 : (real_equal (d0, d1) ? CMP_EQ :
6938 : 1207 : real_less (d0, d1) ? CMP_LT : CMP_GT));
6939 : : }
6940 : :
6941 : : /* Otherwise, see if the operands are both integers. */
6942 : 99295974 : if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
6943 : 96572711 : && CONST_SCALAR_INT_P (trueop0) && CONST_SCALAR_INT_P (trueop1))
6944 : : {
6945 : : /* It would be nice if we really had a mode here. However, the
6946 : : largest int representable on the target is as good as
6947 : : infinite. */
6948 : 205798 : machine_mode cmode = (mode == VOIDmode) ? MAX_MODE_INT : mode;
6949 : 205798 : rtx_mode_t ptrueop0 = rtx_mode_t (trueop0, cmode);
6950 : 205798 : rtx_mode_t ptrueop1 = rtx_mode_t (trueop1, cmode);
6951 : :
6952 : 205798 : if (wi::eq_p (ptrueop0, ptrueop1))
6953 : 0 : return comparison_result (code, CMP_EQ);
6954 : : else
6955 : : {
6956 : 205798 : int cr = wi::lts_p (ptrueop0, ptrueop1) ? CMP_LT : CMP_GT;
6957 : 205798 : cr |= wi::ltu_p (ptrueop0, ptrueop1) ? CMP_LTU : CMP_GTU;
6958 : 205798 : return comparison_result (code, cr);
6959 : : }
6960 : : }
6961 : :
6962 : : /* Optimize comparisons with upper and lower bounds. */
6963 : 99090176 : scalar_int_mode int_mode;
6964 : 99090176 : if (CONST_INT_P (trueop1)
6965 : 70166948 : && is_a <scalar_int_mode> (mode, &int_mode)
6966 : 70166948 : && HWI_COMPUTABLE_MODE_P (int_mode)
6967 : 168721976 : && !side_effects_p (trueop0))
6968 : : {
6969 : 69544298 : int sign;
6970 : 69544298 : unsigned HOST_WIDE_INT nonzero = nonzero_bits (trueop0, int_mode);
6971 : 69544298 : HOST_WIDE_INT val = INTVAL (trueop1);
6972 : 69544298 : HOST_WIDE_INT mmin, mmax;
6973 : :
6974 : 69544298 : if (code == GEU
6975 : 69544298 : || code == LEU
6976 : 66442684 : || code == GTU
6977 : 66442684 : || code == LTU)
6978 : : sign = 0;
6979 : : else
6980 : 69544298 : sign = 1;
6981 : :
6982 : : /* Get a reduced range if the sign bit is zero. */
6983 : 69544298 : if (nonzero <= (GET_MODE_MASK (int_mode) >> 1))
6984 : : {
6985 : 6902438 : mmin = 0;
6986 : 6902438 : mmax = nonzero;
6987 : : }
6988 : : else
6989 : : {
6990 : 62641860 : rtx mmin_rtx, mmax_rtx;
6991 : 62641860 : get_mode_bounds (int_mode, sign, int_mode, &mmin_rtx, &mmax_rtx);
6992 : :
6993 : 62641860 : mmin = INTVAL (mmin_rtx);
6994 : 62641860 : mmax = INTVAL (mmax_rtx);
6995 : 62641860 : if (sign)
6996 : : {
6997 : 56611041 : unsigned int sign_copies
6998 : 56611041 : = num_sign_bit_copies (trueop0, int_mode);
6999 : :
7000 : 56611041 : mmin >>= (sign_copies - 1);
7001 : 56611041 : mmax >>= (sign_copies - 1);
7002 : : }
7003 : : }
7004 : :
7005 : 69544298 : switch (code)
7006 : : {
7007 : : /* x >= y is always true for y <= mmin, always false for y > mmax. */
7008 : 562709 : case GEU:
7009 : 562709 : if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
7010 : 11237 : return const_true_rtx;
7011 : 551472 : if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
7012 : 49 : return const0_rtx;
7013 : : break;
7014 : 927118 : case GE:
7015 : 927118 : if (val <= mmin)
7016 : 2177 : return const_true_rtx;
7017 : 924941 : if (val > mmax)
7018 : 0 : return const0_rtx;
7019 : : break;
7020 : :
7021 : : /* x <= y is always true for y >= mmax, always false for y < mmin. */
7022 : 2538905 : case LEU:
7023 : 2538905 : if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
7024 : 16918 : return const_true_rtx;
7025 : 2521987 : if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
7026 : 0 : return const0_rtx;
7027 : : break;
7028 : 2305815 : case LE:
7029 : 2305815 : if (val >= mmax)
7030 : 412 : return const_true_rtx;
7031 : 2305403 : if (val < mmin)
7032 : 0 : return const0_rtx;
7033 : : break;
7034 : :
7035 : 26228694 : case EQ:
7036 : : /* x == y is always false for y out of range. */
7037 : 26228694 : if (val < mmin || val > mmax)
7038 : 417 : return const0_rtx;
7039 : : break;
7040 : :
7041 : : /* x > y is always false for y >= mmax, always true for y < mmin. */
7042 : 2661827 : case GTU:
7043 : 2661827 : if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
7044 : 127828 : return const0_rtx;
7045 : 2533999 : if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
7046 : 0 : return const_true_rtx;
7047 : : break;
7048 : 1782474 : case GT:
7049 : 1782474 : if (val >= mmax)
7050 : 336 : return const0_rtx;
7051 : 1782138 : if (val < mmin)
7052 : 5 : return const_true_rtx;
7053 : : break;
7054 : :
7055 : : /* x < y is always false for y <= mmin, always true for y > mmax. */
7056 : 853392 : case LTU:
7057 : 853392 : if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
7058 : 2778 : return const0_rtx;
7059 : 850614 : if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
7060 : 87514 : return const_true_rtx;
7061 : : break;
7062 : 1117638 : case LT:
7063 : 1117638 : if (val <= mmin)
7064 : 2344 : return const0_rtx;
7065 : 1115294 : if (val > mmax)
7066 : 3496 : return const_true_rtx;
7067 : : break;
7068 : :
7069 : 30565726 : case NE:
7070 : : /* x != y is always true for y out of range. */
7071 : 30565726 : if (val < mmin || val > mmax)
7072 : 138 : return const_true_rtx;
7073 : : break;
7074 : :
7075 : : default:
7076 : : break;
7077 : : }
7078 : : }
7079 : :
7080 : : /* Optimize integer comparisons with zero. */
7081 : 98834527 : if (is_a <scalar_int_mode> (mode, &int_mode)
7082 : 96154345 : && trueop1 == const0_rtx
7083 : 50197556 : && !side_effects_p (trueop0))
7084 : : {
7085 : : /* Some addresses are known to be nonzero. We don't know
7086 : : their sign, but equality comparisons are known. */
7087 : 50108576 : if (nonzero_address_p (trueop0))
7088 : : {
7089 : 555 : if (code == EQ || code == LEU)
7090 : 291 : return const0_rtx;
7091 : 264 : if (code == NE || code == GTU)
7092 : 264 : return const_true_rtx;
7093 : : }
7094 : :
7095 : : /* See if the first operand is an IOR with a constant. If so, we
7096 : : may be able to determine the result of this comparison. */
7097 : 50108021 : if (GET_CODE (op0) == IOR)
7098 : : {
7099 : 610498 : rtx inner_const = avoid_constant_pool_reference (XEXP (op0, 1));
7100 : 610498 : if (CONST_INT_P (inner_const) && inner_const != const0_rtx)
7101 : : {
7102 : 290 : int sign_bitnum = GET_MODE_PRECISION (int_mode) - 1;
7103 : 580 : int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
7104 : 290 : && (UINTVAL (inner_const)
7105 : 290 : & (HOST_WIDE_INT_1U
7106 : : << sign_bitnum)));
7107 : :
7108 : 290 : switch (code)
7109 : : {
7110 : : case EQ:
7111 : : case LEU:
7112 : : return const0_rtx;
7113 : 4 : case NE:
7114 : 4 : case GTU:
7115 : 4 : return const_true_rtx;
7116 : 70 : case LT:
7117 : 70 : case LE:
7118 : 70 : if (has_sign)
7119 : 2 : return const_true_rtx;
7120 : : break;
7121 : 210 : case GT:
7122 : 210 : case GE:
7123 : 210 : if (has_sign)
7124 : : return const0_rtx;
7125 : : break;
7126 : : default:
7127 : : break;
7128 : : }
7129 : : }
7130 : : }
7131 : : }
7132 : :
7133 : : /* Optimize comparison of ABS with zero. */
7134 : 50523210 : if (trueop1 == CONST0_RTX (mode) && !side_effects_p (trueop0)
7135 : 149267769 : && (GET_CODE (trueop0) == ABS
7136 : 50433466 : || (GET_CODE (trueop0) == FLOAT_EXTEND
7137 : 34 : && GET_CODE (XEXP (trueop0, 0)) == ABS)))
7138 : : {
7139 : 535 : switch (code)
7140 : : {
7141 : 60 : case LT:
7142 : : /* Optimize abs(x) < 0.0. */
7143 : 60 : if (!INTEGRAL_MODE_P (mode) && !HONOR_SNANS (mode))
7144 : 0 : return const0_rtx;
7145 : : break;
7146 : :
7147 : 42 : case GE:
7148 : : /* Optimize abs(x) >= 0.0. */
7149 : 42 : if (!INTEGRAL_MODE_P (mode) && !HONOR_NANS (mode))
7150 : 0 : return const_true_rtx;
7151 : : break;
7152 : :
7153 : 0 : case UNGE:
7154 : : /* Optimize ! (abs(x) < 0.0). */
7155 : 0 : return const_true_rtx;
7156 : :
7157 : : default:
7158 : : break;
7159 : : }
7160 : : }
7161 : :
7162 : : return 0;
7163 : : }
7164 : :
7165 : : /* Recognize expressions of the form (X CMP 0) ? VAL : OP (X)
7166 : : where OP is CLZ or CTZ and VAL is the value from CLZ_DEFINED_VALUE_AT_ZERO
7167 : : or CTZ_DEFINED_VALUE_AT_ZERO respectively and return OP (X) if the expression
7168 : : can be simplified to that or NULL_RTX if not.
7169 : : Assume X is compared against zero with CMP_CODE and the true
7170 : : arm is TRUE_VAL and the false arm is FALSE_VAL. */
7171 : :
7172 : : rtx
7173 : 31373998 : simplify_context::simplify_cond_clz_ctz (rtx x, rtx_code cmp_code,
7174 : : rtx true_val, rtx false_val)
7175 : : {
7176 : 31373998 : if (cmp_code != EQ && cmp_code != NE)
7177 : : return NULL_RTX;
7178 : :
7179 : : /* Result on X == 0 and X !=0 respectively. */
7180 : 22858791 : rtx on_zero, on_nonzero;
7181 : 22858791 : if (cmp_code == EQ)
7182 : : {
7183 : : on_zero = true_val;
7184 : : on_nonzero = false_val;
7185 : : }
7186 : : else
7187 : : {
7188 : 12051004 : on_zero = false_val;
7189 : 12051004 : on_nonzero = true_val;
7190 : : }
7191 : :
7192 : 22858791 : rtx_code op_code = GET_CODE (on_nonzero);
7193 : 22858791 : if ((op_code != CLZ && op_code != CTZ)
7194 : 1860 : || !rtx_equal_p (XEXP (on_nonzero, 0), x)
7195 : 22859730 : || !CONST_INT_P (on_zero))
7196 : 22858496 : return NULL_RTX;
7197 : :
7198 : 295 : HOST_WIDE_INT op_val;
7199 : 295 : scalar_int_mode mode ATTRIBUTE_UNUSED
7200 : 295 : = as_a <scalar_int_mode> (GET_MODE (XEXP (on_nonzero, 0)));
7201 : 0 : if (((op_code == CLZ && CLZ_DEFINED_VALUE_AT_ZERO (mode, op_val))
7202 : 590 : || (op_code == CTZ && CTZ_DEFINED_VALUE_AT_ZERO (mode, op_val)))
7203 : 319 : && op_val == INTVAL (on_zero))
7204 : : return on_nonzero;
7205 : :
7206 : : return NULL_RTX;
7207 : : }
7208 : :
7209 : : /* Try to simplify X given that it appears within operand OP of a
7210 : : VEC_MERGE operation whose mask is MASK. X need not use the same
7211 : : vector mode as the VEC_MERGE, but it must have the same number of
7212 : : elements.
7213 : :
7214 : : Return the simplified X on success, otherwise return NULL_RTX. */
7215 : :
7216 : : rtx
7217 : 1611140 : simplify_context::simplify_merge_mask (rtx x, rtx mask, int op)
7218 : : {
7219 : 1611140 : gcc_assert (VECTOR_MODE_P (GET_MODE (x)));
7220 : 3222280 : poly_uint64 nunits = GET_MODE_NUNITS (GET_MODE (x));
7221 : 1611140 : if (GET_CODE (x) == VEC_MERGE && rtx_equal_p (XEXP (x, 2), mask))
7222 : : {
7223 : 5484 : if (side_effects_p (XEXP (x, 1 - op)))
7224 : : return NULL_RTX;
7225 : :
7226 : 5260 : return XEXP (x, op);
7227 : : }
7228 : 1605656 : if (UNARY_P (x)
7229 : 182562 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
7230 : 1663366 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits))
7231 : : {
7232 : 24266 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
7233 : 24266 : if (top0)
7234 : 448 : return simplify_gen_unary (GET_CODE (x), GET_MODE (x), top0,
7235 : 448 : GET_MODE (XEXP (x, 0)));
7236 : : }
7237 : 1605208 : if (BINARY_P (x)
7238 : 204627 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
7239 : 409136 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
7240 : 179280 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
7241 : 1890178 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits))
7242 : : {
7243 : 142485 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
7244 : 142485 : rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
7245 : 142485 : if (top0 || top1)
7246 : : {
7247 : 952 : if (COMPARISON_P (x))
7248 : 0 : return simplify_gen_relational (GET_CODE (x), GET_MODE (x),
7249 : 0 : GET_MODE (XEXP (x, 0)) != VOIDmode
7250 : : ? GET_MODE (XEXP (x, 0))
7251 : 0 : : GET_MODE (XEXP (x, 1)),
7252 : : top0 ? top0 : XEXP (x, 0),
7253 : 0 : top1 ? top1 : XEXP (x, 1));
7254 : : else
7255 : 952 : return simplify_gen_binary (GET_CODE (x), GET_MODE (x),
7256 : : top0 ? top0 : XEXP (x, 0),
7257 : 952 : top1 ? top1 : XEXP (x, 1));
7258 : : }
7259 : : }
7260 : 1604256 : if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY
7261 : 35705 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
7262 : 71410 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
7263 : 35705 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
7264 : 71410 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits)
7265 : 35705 : && VECTOR_MODE_P (GET_MODE (XEXP (x, 2)))
7266 : 1622436 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 2))), nunits))
7267 : : {
7268 : 9090 : rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
7269 : 9090 : rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
7270 : 9090 : rtx top2 = simplify_merge_mask (XEXP (x, 2), mask, op);
7271 : 9090 : if (top0 || top1 || top2)
7272 : 448 : return simplify_gen_ternary (GET_CODE (x), GET_MODE (x),
7273 : 448 : GET_MODE (XEXP (x, 0)),
7274 : : top0 ? top0 : XEXP (x, 0),
7275 : : top1 ? top1 : XEXP (x, 1),
7276 : 448 : top2 ? top2 : XEXP (x, 2));
7277 : : }
7278 : : return NULL_RTX;
7279 : : }
7280 : :
7281 : :
7282 : : /* Simplify CODE, an operation with result mode MODE and three operands,
7283 : : OP0, OP1, and OP2. OP0_MODE was the mode of OP0 before it became
7284 : : a constant. Return 0 if no simplifications is possible. */
7285 : :
7286 : : rtx
7287 : 42716267 : simplify_context::simplify_ternary_operation (rtx_code code, machine_mode mode,
7288 : : machine_mode op0_mode,
7289 : : rtx op0, rtx op1, rtx op2)
7290 : : {
7291 : 42716267 : bool any_change = false;
7292 : 42716267 : rtx tem, trueop2;
7293 : 42716267 : scalar_int_mode int_mode, int_op0_mode;
7294 : 42716267 : unsigned int n_elts;
7295 : :
7296 : 42716267 : switch (code)
7297 : : {
7298 : 336785 : case FMA:
7299 : : /* Simplify negations around the multiplication. */
7300 : : /* -a * -b + c => a * b + c. */
7301 : 336785 : if (GET_CODE (op0) == NEG)
7302 : : {
7303 : 80947 : tem = simplify_unary_operation (NEG, mode, op1, mode);
7304 : 80947 : if (tem)
7305 : 231 : op1 = tem, op0 = XEXP (op0, 0), any_change = true;
7306 : : }
7307 : 255838 : else if (GET_CODE (op1) == NEG)
7308 : : {
7309 : 1078 : tem = simplify_unary_operation (NEG, mode, op0, mode);
7310 : 1078 : if (tem)
7311 : 0 : op0 = tem, op1 = XEXP (op1, 0), any_change = true;
7312 : : }
7313 : :
7314 : : /* Canonicalize the two multiplication operands. */
7315 : : /* a * -b + c => -b * a + c. */
7316 : 336785 : if (swap_commutative_operands_p (op0, op1))
7317 : : std::swap (op0, op1), any_change = true;
7318 : :
7319 : 308395 : if (any_change)
7320 : 28612 : return gen_rtx_FMA (mode, op0, op1, op2);
7321 : : return NULL_RTX;
7322 : :
7323 : 650498 : case SIGN_EXTRACT:
7324 : 650498 : case ZERO_EXTRACT:
7325 : 650498 : if (CONST_INT_P (op0)
7326 : 20278 : && CONST_INT_P (op1)
7327 : 20278 : && CONST_INT_P (op2)
7328 : 42716299 : && is_a <scalar_int_mode> (mode, &int_mode)
7329 : 32 : && INTVAL (op1) + INTVAL (op2) <= GET_MODE_PRECISION (int_mode)
7330 : 650530 : && HWI_COMPUTABLE_MODE_P (int_mode))
7331 : : {
7332 : : /* Extracting a bit-field from a constant */
7333 : 32 : unsigned HOST_WIDE_INT val = UINTVAL (op0);
7334 : 32 : HOST_WIDE_INT op1val = INTVAL (op1);
7335 : 32 : HOST_WIDE_INT op2val = INTVAL (op2);
7336 : 32 : if (!BITS_BIG_ENDIAN)
7337 : 32 : val >>= op2val;
7338 : : else if (is_a <scalar_int_mode> (op0_mode, &int_op0_mode))
7339 : : val >>= GET_MODE_PRECISION (int_op0_mode) - op2val - op1val;
7340 : : else
7341 : : /* Not enough information to calculate the bit position. */
7342 : : break;
7343 : :
7344 : 32 : if (HOST_BITS_PER_WIDE_INT != op1val)
7345 : : {
7346 : : /* First zero-extend. */
7347 : 29 : val &= (HOST_WIDE_INT_1U << op1val) - 1;
7348 : : /* If desired, propagate sign bit. */
7349 : 29 : if (code == SIGN_EXTRACT
7350 : 5 : && (val & (HOST_WIDE_INT_1U << (op1val - 1)))
7351 : 5 : != 0)
7352 : 2 : val |= ~ ((HOST_WIDE_INT_1U << op1val) - 1);
7353 : : }
7354 : :
7355 : 32 : return gen_int_mode (val, int_mode);
7356 : : }
7357 : : break;
7358 : :
7359 : 40959852 : case IF_THEN_ELSE:
7360 : 40959852 : if (CONST_INT_P (op0))
7361 : 285137 : return op0 != const0_rtx ? op1 : op2;
7362 : :
7363 : : /* Convert c ? a : a into "a". */
7364 : 40767533 : if (rtx_equal_p (op1, op2) && ! side_effects_p (op0))
7365 : : return op1;
7366 : :
7367 : : /* Convert a != b ? a : b into "a". */
7368 : 40763877 : if (GET_CODE (op0) == NE
7369 : 15861800 : && ! side_effects_p (op0)
7370 : 15823886 : && ! HONOR_NANS (mode)
7371 : 15819121 : && ! HONOR_SIGNED_ZEROS (mode)
7372 : 56582998 : && ((rtx_equal_p (XEXP (op0, 0), op1)
7373 : 76536 : && rtx_equal_p (XEXP (op0, 1), op2))
7374 : 15819064 : || (rtx_equal_p (XEXP (op0, 0), op2)
7375 : 6417 : && rtx_equal_p (XEXP (op0, 1), op1))))
7376 : 152 : return op1;
7377 : :
7378 : : /* Convert a == b ? a : b into "b". */
7379 : 40763725 : if (GET_CODE (op0) == EQ
7380 : 13165048 : && ! side_effects_p (op0)
7381 : 13154663 : && ! HONOR_NANS (mode)
7382 : 13056026 : && ! HONOR_SIGNED_ZEROS (mode)
7383 : 53819751 : && ((rtx_equal_p (XEXP (op0, 0), op1)
7384 : 14455 : && rtx_equal_p (XEXP (op0, 1), op2))
7385 : 13056018 : || (rtx_equal_p (XEXP (op0, 0), op2)
7386 : 7269 : && rtx_equal_p (XEXP (op0, 1), op1))))
7387 : 19 : return op2;
7388 : :
7389 : : /* Convert a != 0 ? -a : 0 into "-a". */
7390 : 40763706 : if (GET_CODE (op0) == NE
7391 : 15861648 : && ! side_effects_p (op0)
7392 : 15823734 : && ! HONOR_NANS (mode)
7393 : 15818969 : && ! HONOR_SIGNED_ZEROS (mode)
7394 : 15818969 : && XEXP (op0, 1) == CONST0_RTX (mode)
7395 : 12046118 : && op2 == CONST0_RTX (mode)
7396 : 100749 : && GET_CODE (op1) == NEG
7397 : 40763769 : && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0)))
7398 : : return op1;
7399 : :
7400 : : /* Convert a == 0 ? 0 : -a into "-a". */
7401 : 40763701 : if (GET_CODE (op0) == EQ
7402 : 13165029 : && ! side_effects_p (op0)
7403 : 13154644 : && ! HONOR_NANS (mode)
7404 : 13056007 : && ! HONOR_SIGNED_ZEROS (mode)
7405 : 13056007 : && op1 == CONST0_RTX (mode)
7406 : 33340 : && XEXP (op0, 1) == CONST0_RTX (mode)
7407 : 14949 : && GET_CODE (op2) == NEG
7408 : 40763705 : && rtx_equal_p (XEXP (op0, 0), XEXP (op2, 0)))
7409 : : return op2;
7410 : :
7411 : : /* Convert (!c) != {0,...,0} ? a : b into
7412 : : c != {0,...,0} ? b : a for vector modes. */
7413 : 40763697 : if (VECTOR_MODE_P (GET_MODE (op1))
7414 : 11606 : && GET_CODE (op0) == NE
7415 : 460 : && GET_CODE (XEXP (op0, 0)) == NOT
7416 : 0 : && GET_CODE (XEXP (op0, 1)) == CONST_VECTOR)
7417 : : {
7418 : 0 : rtx cv = XEXP (op0, 1);
7419 : 0 : int nunits;
7420 : 0 : bool ok = true;
7421 : 0 : if (!CONST_VECTOR_NUNITS (cv).is_constant (&nunits))
7422 : : ok = false;
7423 : : else
7424 : 0 : for (int i = 0; i < nunits; ++i)
7425 : 0 : if (CONST_VECTOR_ELT (cv, i) != const0_rtx)
7426 : : {
7427 : : ok = false;
7428 : : break;
7429 : : }
7430 : 0 : if (ok)
7431 : : {
7432 : 0 : rtx new_op0 = gen_rtx_NE (GET_MODE (op0),
7433 : : XEXP (XEXP (op0, 0), 0),
7434 : : XEXP (op0, 1));
7435 : 0 : rtx retval = gen_rtx_IF_THEN_ELSE (mode, new_op0, op2, op1);
7436 : 0 : return retval;
7437 : : }
7438 : : }
7439 : :
7440 : : /* Convert x == 0 ? N : clz (x) into clz (x) when
7441 : : CLZ_DEFINED_VALUE_AT_ZERO is defined to N for the mode of x.
7442 : : Similarly for ctz (x). */
7443 : 40762724 : if (COMPARISON_P (op0) && !side_effects_p (op0)
7444 : 81441280 : && XEXP (op0, 1) == const0_rtx)
7445 : : {
7446 : 31373998 : rtx simplified
7447 : 31373998 : = simplify_cond_clz_ctz (XEXP (op0, 0), GET_CODE (op0),
7448 : : op1, op2);
7449 : 31373998 : if (simplified)
7450 : : return simplified;
7451 : : }
7452 : :
7453 : 40763697 : if (COMPARISON_P (op0) && ! side_effects_p (op0))
7454 : : {
7455 : 81425589 : machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
7456 : 40677583 : ? GET_MODE (XEXP (op0, 1))
7457 : : : GET_MODE (XEXP (op0, 0)));
7458 : 40677583 : rtx temp;
7459 : :
7460 : : /* Look for happy constants in op1 and op2. */
7461 : 40677583 : if (CONST_INT_P (op1) && CONST_INT_P (op2))
7462 : : {
7463 : 221475 : HOST_WIDE_INT t = INTVAL (op1);
7464 : 221475 : HOST_WIDE_INT f = INTVAL (op2);
7465 : :
7466 : 221475 : if (t == STORE_FLAG_VALUE && f == 0)
7467 : 53152 : code = GET_CODE (op0);
7468 : 168323 : else if (t == 0 && f == STORE_FLAG_VALUE)
7469 : : {
7470 : 31799 : enum rtx_code tmp;
7471 : 31799 : tmp = reversed_comparison_code (op0, NULL);
7472 : 31799 : if (tmp == UNKNOWN)
7473 : : break;
7474 : : code = tmp;
7475 : : }
7476 : : else
7477 : : break;
7478 : :
7479 : 79565 : return simplify_gen_relational (code, mode, cmp_mode,
7480 : 79565 : XEXP (op0, 0), XEXP (op0, 1));
7481 : : }
7482 : :
7483 : 40456108 : temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
7484 : : cmp_mode, XEXP (op0, 0),
7485 : : XEXP (op0, 1));
7486 : :
7487 : : /* See if any simplifications were possible. */
7488 : 40456108 : if (temp)
7489 : : {
7490 : 7001 : if (CONST_INT_P (temp))
7491 : 864 : return temp == const0_rtx ? op2 : op1;
7492 : 6178 : else if (temp)
7493 : 6178 : return gen_rtx_IF_THEN_ELSE (mode, temp, op1, op2);
7494 : : }
7495 : : }
7496 : : break;
7497 : :
7498 : 769132 : case VEC_MERGE:
7499 : 769132 : gcc_assert (GET_MODE (op0) == mode);
7500 : 769132 : gcc_assert (GET_MODE (op1) == mode);
7501 : 769132 : gcc_assert (VECTOR_MODE_P (mode));
7502 : 769132 : trueop2 = avoid_constant_pool_reference (op2);
7503 : 769132 : if (CONST_INT_P (trueop2)
7504 : 1218173 : && GET_MODE_NUNITS (mode).is_constant (&n_elts))
7505 : : {
7506 : 449041 : unsigned HOST_WIDE_INT sel = UINTVAL (trueop2);
7507 : 449041 : unsigned HOST_WIDE_INT mask;
7508 : 449041 : if (n_elts == HOST_BITS_PER_WIDE_INT)
7509 : : mask = -1;
7510 : : else
7511 : 446594 : mask = (HOST_WIDE_INT_1U << n_elts) - 1;
7512 : :
7513 : 449041 : if (!(sel & mask) && !side_effects_p (op0))
7514 : : return op1;
7515 : 448604 : if ((sel & mask) == mask && !side_effects_p (op1))
7516 : : return op0;
7517 : :
7518 : 437880 : rtx trueop0 = avoid_constant_pool_reference (op0);
7519 : 437880 : rtx trueop1 = avoid_constant_pool_reference (op1);
7520 : 437880 : if (GET_CODE (trueop0) == CONST_VECTOR
7521 : 8993 : && GET_CODE (trueop1) == CONST_VECTOR)
7522 : : {
7523 : 4745 : rtvec v = rtvec_alloc (n_elts);
7524 : 4745 : unsigned int i;
7525 : :
7526 : 53772 : for (i = 0; i < n_elts; i++)
7527 : 44282 : RTVEC_ELT (v, i) = ((sel & (HOST_WIDE_INT_1U << i))
7528 : 44282 : ? CONST_VECTOR_ELT (trueop0, i)
7529 : 24756 : : CONST_VECTOR_ELT (trueop1, i));
7530 : 4745 : return gen_rtx_CONST_VECTOR (mode, v);
7531 : : }
7532 : :
7533 : 433135 : if (swap_commutative_operands_p (op0, op1)
7534 : : /* Two operands have same precedence, then first bit of mask
7535 : : select first operand. */
7536 : 433135 : || (!swap_commutative_operands_p (op1, op0) && !(sel & 1)))
7537 : 30451 : return simplify_gen_ternary (code, mode, mode, op1, op0,
7538 : 60902 : GEN_INT (~sel & mask));
7539 : :
7540 : : /* Replace (vec_merge (vec_merge a b m) c n) with (vec_merge b c n)
7541 : : if no element from a appears in the result. */
7542 : 402684 : if (GET_CODE (op0) == VEC_MERGE)
7543 : : {
7544 : 17233 : tem = avoid_constant_pool_reference (XEXP (op0, 2));
7545 : 17233 : if (CONST_INT_P (tem))
7546 : : {
7547 : 1372 : unsigned HOST_WIDE_INT sel0 = UINTVAL (tem);
7548 : 1372 : if (!(sel & sel0 & mask) && !side_effects_p (XEXP (op0, 0)))
7549 : 99 : return simplify_gen_ternary (code, mode, mode,
7550 : 99 : XEXP (op0, 1), op1, op2);
7551 : 1273 : if (!(sel & ~sel0 & mask) && !side_effects_p (XEXP (op0, 1)))
7552 : 834 : return simplify_gen_ternary (code, mode, mode,
7553 : 834 : XEXP (op0, 0), op1, op2);
7554 : : }
7555 : : }
7556 : 401751 : if (GET_CODE (op1) == VEC_MERGE)
7557 : : {
7558 : 585 : tem = avoid_constant_pool_reference (XEXP (op1, 2));
7559 : 585 : if (CONST_INT_P (tem))
7560 : : {
7561 : 554 : unsigned HOST_WIDE_INT sel1 = UINTVAL (tem);
7562 : 554 : if (!(~sel & sel1 & mask) && !side_effects_p (XEXP (op1, 0)))
7563 : 523 : return simplify_gen_ternary (code, mode, mode,
7564 : 523 : op0, XEXP (op1, 1), op2);
7565 : 31 : if (!(~sel & ~sel1 & mask) && !side_effects_p (XEXP (op1, 1)))
7566 : 4 : return simplify_gen_ternary (code, mode, mode,
7567 : 4 : op0, XEXP (op1, 0), op2);
7568 : : }
7569 : : }
7570 : :
7571 : : /* Replace (vec_merge (vec_duplicate (vec_select a parallel (i))) a 1 << i)
7572 : : with a. */
7573 : 401224 : if (GET_CODE (op0) == VEC_DUPLICATE
7574 : 133809 : && GET_CODE (XEXP (op0, 0)) == VEC_SELECT
7575 : 632 : && GET_CODE (XEXP (XEXP (op0, 0), 1)) == PARALLEL
7576 : 402488 : && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (op0, 0))), 1))
7577 : : {
7578 : 564 : tem = XVECEXP ((XEXP (XEXP (op0, 0), 1)), 0, 0);
7579 : 564 : if (CONST_INT_P (tem) && CONST_INT_P (op2))
7580 : : {
7581 : 564 : if (XEXP (XEXP (op0, 0), 0) == op1
7582 : 2 : && UINTVAL (op2) == HOST_WIDE_INT_1U << UINTVAL (tem))
7583 : : return op1;
7584 : : }
7585 : : }
7586 : : /* Replace (vec_merge (vec_duplicate (X)) (const_vector [A, B])
7587 : : (const_int N))
7588 : : with (vec_concat (X) (B)) if N == 1 or
7589 : : (vec_concat (A) (X)) if N == 2. */
7590 : 401222 : if (GET_CODE (op0) == VEC_DUPLICATE
7591 : 133807 : && GET_CODE (op1) == CONST_VECTOR
7592 : 142194 : && known_eq (CONST_VECTOR_NUNITS (op1), 2)
7593 : 2080 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7594 : 402262 : && IN_RANGE (sel, 1, 2))
7595 : : {
7596 : 1038 : rtx newop0 = XEXP (op0, 0);
7597 : 1038 : rtx newop1 = CONST_VECTOR_ELT (op1, 2 - sel);
7598 : 1038 : if (sel == 2)
7599 : 123 : std::swap (newop0, newop1);
7600 : 1038 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7601 : : }
7602 : : /* Replace (vec_merge (vec_duplicate x) (vec_concat (y) (z)) (const_int N))
7603 : : with (vec_concat x z) if N == 1, or (vec_concat y x) if N == 2.
7604 : : Only applies for vectors of two elements. */
7605 : 400184 : if (GET_CODE (op0) == VEC_DUPLICATE
7606 : 132769 : && GET_CODE (op1) == VEC_CONCAT
7607 : 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7608 : 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
7609 : 400184 : && IN_RANGE (sel, 1, 2))
7610 : : {
7611 : 0 : rtx newop0 = XEXP (op0, 0);
7612 : 0 : rtx newop1 = XEXP (op1, 2 - sel);
7613 : 0 : rtx otherop = XEXP (op1, sel - 1);
7614 : 0 : if (sel == 2)
7615 : 0 : std::swap (newop0, newop1);
7616 : : /* Don't want to throw away the other part of the vec_concat if
7617 : : it has side-effects. */
7618 : 0 : if (!side_effects_p (otherop))
7619 : 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7620 : : }
7621 : :
7622 : : /* Replace:
7623 : :
7624 : : (vec_merge:outer (vec_duplicate:outer x:inner)
7625 : : (subreg:outer y:inner 0)
7626 : : (const_int N))
7627 : :
7628 : : with (vec_concat:outer x:inner y:inner) if N == 1,
7629 : : or (vec_concat:outer y:inner x:inner) if N == 2.
7630 : :
7631 : : Implicitly, this means we have a paradoxical subreg, but such
7632 : : a check is cheap, so make it anyway.
7633 : :
7634 : : Only applies for vectors of two elements. */
7635 : 400184 : if (GET_CODE (op0) == VEC_DUPLICATE
7636 : 132769 : && GET_CODE (op1) == SUBREG
7637 : 40774 : && GET_MODE (op1) == GET_MODE (op0)
7638 : 40774 : && GET_MODE (SUBREG_REG (op1)) == GET_MODE (XEXP (op0, 0))
7639 : 0 : && paradoxical_subreg_p (op1)
7640 : 0 : && subreg_lowpart_p (op1)
7641 : 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7642 : 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
7643 : 400184 : && IN_RANGE (sel, 1, 2))
7644 : : {
7645 : 0 : rtx newop0 = XEXP (op0, 0);
7646 : 0 : rtx newop1 = SUBREG_REG (op1);
7647 : 0 : if (sel == 2)
7648 : 0 : std::swap (newop0, newop1);
7649 : 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7650 : : }
7651 : :
7652 : : /* Same as above but with switched operands:
7653 : : Replace (vec_merge:outer (subreg:outer x:inner 0)
7654 : : (vec_duplicate:outer y:inner)
7655 : : (const_int N))
7656 : :
7657 : : with (vec_concat:outer x:inner y:inner) if N == 1,
7658 : : or (vec_concat:outer y:inner x:inner) if N == 2. */
7659 : 400184 : if (GET_CODE (op1) == VEC_DUPLICATE
7660 : 27126 : && GET_CODE (op0) == SUBREG
7661 : 24258 : && GET_MODE (op0) == GET_MODE (op1)
7662 : 24258 : && GET_MODE (SUBREG_REG (op0)) == GET_MODE (XEXP (op1, 0))
7663 : 0 : && paradoxical_subreg_p (op0)
7664 : 0 : && subreg_lowpart_p (op0)
7665 : 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
7666 : 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7667 : 400184 : && IN_RANGE (sel, 1, 2))
7668 : : {
7669 : 0 : rtx newop0 = SUBREG_REG (op0);
7670 : 0 : rtx newop1 = XEXP (op1, 0);
7671 : 0 : if (sel == 2)
7672 : 0 : std::swap (newop0, newop1);
7673 : 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7674 : : }
7675 : :
7676 : : /* Replace (vec_merge (vec_duplicate x) (vec_duplicate y)
7677 : : (const_int n))
7678 : : with (vec_concat x y) or (vec_concat y x) depending on value
7679 : : of N. */
7680 : 400184 : if (GET_CODE (op0) == VEC_DUPLICATE
7681 : 132769 : && GET_CODE (op1) == VEC_DUPLICATE
7682 : 198 : && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
7683 : 0 : && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
7684 : 400184 : && IN_RANGE (sel, 1, 2))
7685 : : {
7686 : 0 : rtx newop0 = XEXP (op0, 0);
7687 : 0 : rtx newop1 = XEXP (op1, 0);
7688 : 0 : if (sel == 2)
7689 : 0 : std::swap (newop0, newop1);
7690 : :
7691 : 0 : return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
7692 : : }
7693 : : }
7694 : :
7695 : 720275 : if (rtx_equal_p (op0, op1)
7696 : 720275 : && !side_effects_p (op2) && !side_effects_p (op1))
7697 : : return op0;
7698 : :
7699 : 719988 : if (!side_effects_p (op2))
7700 : : {
7701 : 716899 : rtx top0
7702 : 716899 : = may_trap_p (op0) ? NULL_RTX : simplify_merge_mask (op0, op2, 0);
7703 : 716899 : rtx top1
7704 : 716899 : = may_trap_p (op1) ? NULL_RTX : simplify_merge_mask (op1, op2, 1);
7705 : 716899 : if (top0 || top1)
7706 : 984 : return simplify_gen_ternary (code, mode, mode,
7707 : : top0 ? top0 : op0,
7708 : 812 : top1 ? top1 : op1, op2);
7709 : : }
7710 : :
7711 : : break;
7712 : :
7713 : 0 : default:
7714 : 0 : gcc_unreachable ();
7715 : : }
7716 : :
7717 : : return 0;
7718 : : }
7719 : :
7720 : : /* Try to calculate NUM_BYTES bytes of the target memory image of X,
7721 : : starting at byte FIRST_BYTE. Return true on success and add the
7722 : : bytes to BYTES, such that each byte has BITS_PER_UNIT bits and such
7723 : : that the bytes follow target memory order. Leave BYTES unmodified
7724 : : on failure.
7725 : :
7726 : : MODE is the mode of X. The caller must reserve NUM_BYTES bytes in
7727 : : BYTES before calling this function. */
7728 : :
7729 : : bool
7730 : 14136920 : native_encode_rtx (machine_mode mode, rtx x, vec<target_unit> &bytes,
7731 : : unsigned int first_byte, unsigned int num_bytes)
7732 : : {
7733 : : /* Check the mode is sensible. */
7734 : 14136920 : gcc_assert (GET_MODE (x) == VOIDmode
7735 : : ? is_a <scalar_int_mode> (mode)
7736 : : : mode == GET_MODE (x));
7737 : :
7738 : 14136920 : if (GET_CODE (x) == CONST_VECTOR)
7739 : : {
7740 : : /* CONST_VECTOR_ELT follows target memory order, so no shuffling
7741 : : is necessary. The only complication is that MODE_VECTOR_BOOL
7742 : : vectors can have several elements per byte. */
7743 : 997078 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
7744 : : GET_MODE_NUNITS (mode));
7745 : 498539 : unsigned int elt = first_byte * BITS_PER_UNIT / elt_bits;
7746 : 498539 : if (elt_bits < BITS_PER_UNIT)
7747 : : {
7748 : : /* This is the only case in which elements can be smaller than
7749 : : a byte. */
7750 : 0 : gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
7751 : 0 : auto mask = GET_MODE_MASK (GET_MODE_INNER (mode));
7752 : 0 : for (unsigned int i = 0; i < num_bytes; ++i)
7753 : : {
7754 : 0 : target_unit value = 0;
7755 : 0 : for (unsigned int j = 0; j < BITS_PER_UNIT; j += elt_bits)
7756 : : {
7757 : 0 : if (INTVAL (CONST_VECTOR_ELT (x, elt)))
7758 : 0 : value |= mask << j;
7759 : 0 : elt += 1;
7760 : : }
7761 : 0 : bytes.quick_push (value);
7762 : : }
7763 : : return true;
7764 : : }
7765 : :
7766 : 498539 : unsigned int start = bytes.length ();
7767 : 498539 : unsigned int elt_bytes = GET_MODE_UNIT_SIZE (mode);
7768 : : /* Make FIRST_BYTE relative to ELT. */
7769 : 498539 : first_byte %= elt_bytes;
7770 : 2655560 : while (num_bytes > 0)
7771 : : {
7772 : : /* Work out how many bytes we want from element ELT. */
7773 : 2157021 : unsigned int chunk_bytes = MIN (num_bytes, elt_bytes - first_byte);
7774 : 4314042 : if (!native_encode_rtx (GET_MODE_INNER (mode),
7775 : : CONST_VECTOR_ELT (x, elt), bytes,
7776 : : first_byte, chunk_bytes))
7777 : : {
7778 : 0 : bytes.truncate (start);
7779 : 0 : return false;
7780 : : }
7781 : 2157021 : elt += 1;
7782 : 2157021 : first_byte = 0;
7783 : 2157021 : num_bytes -= chunk_bytes;
7784 : : }
7785 : : return true;
7786 : : }
7787 : :
7788 : : /* All subsequent cases are limited to scalars. */
7789 : 13638381 : scalar_mode smode;
7790 : 13669880 : if (!is_a <scalar_mode> (mode, &smode))
7791 : : return false;
7792 : :
7793 : : /* Make sure that the region is in range. */
7794 : 13638381 : unsigned int end_byte = first_byte + num_bytes;
7795 : 13638381 : unsigned int mode_bytes = GET_MODE_SIZE (smode);
7796 : 13638381 : gcc_assert (end_byte <= mode_bytes);
7797 : :
7798 : 13638381 : if (CONST_SCALAR_INT_P (x))
7799 : : {
7800 : : /* The target memory layout is affected by both BYTES_BIG_ENDIAN
7801 : : and WORDS_BIG_ENDIAN. Use the subreg machinery to get the lsb
7802 : : position of each byte. */
7803 : 12955839 : rtx_mode_t value (x, smode);
7804 : 12955839 : wide_int_ref value_wi (value);
7805 : 54792023 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
7806 : : {
7807 : : /* Always constant because the inputs are. */
7808 : 41836184 : unsigned int lsb
7809 : 41836184 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
7810 : : /* Operate directly on the encoding rather than using
7811 : : wi::extract_uhwi, so that we preserve the sign or zero
7812 : : extension for modes that are not a whole number of bits in
7813 : : size. (Zero extension is only used for the combination of
7814 : : innermode == BImode && STORE_FLAG_VALUE == 1). */
7815 : 41836184 : unsigned int elt = lsb / HOST_BITS_PER_WIDE_INT;
7816 : 41836184 : unsigned int shift = lsb % HOST_BITS_PER_WIDE_INT;
7817 : 41836184 : unsigned HOST_WIDE_INT uhwi = value_wi.elt (elt);
7818 : 41836184 : bytes.quick_push (uhwi >> shift);
7819 : : }
7820 : 12955839 : return true;
7821 : : }
7822 : :
7823 : 682542 : if (CONST_DOUBLE_P (x))
7824 : : {
7825 : : /* real_to_target produces an array of integers in target memory order.
7826 : : All integers before the last one have 32 bits; the last one may
7827 : : have 32 bits or fewer, depending on whether the mode bitsize
7828 : : is divisible by 32. Each of these integers is then laid out
7829 : : in target memory as any other integer would be. */
7830 : 651043 : long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
7831 : 651043 : real_to_target (el32, CONST_DOUBLE_REAL_VALUE (x), smode);
7832 : :
7833 : : /* The (maximum) number of target bytes per element of el32. */
7834 : 651043 : unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
7835 : 651043 : gcc_assert (bytes_per_el32 != 0);
7836 : :
7837 : : /* Build up the integers in a similar way to the CONST_SCALAR_INT_P
7838 : : handling above. */
7839 : 4439006 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
7840 : : {
7841 : 3787963 : unsigned int index = byte / bytes_per_el32;
7842 : 3787963 : unsigned int subbyte = byte % bytes_per_el32;
7843 : 3787963 : unsigned int int_bytes = MIN (bytes_per_el32,
7844 : : mode_bytes - index * bytes_per_el32);
7845 : : /* Always constant because the inputs are. */
7846 : 3787963 : unsigned int lsb
7847 : 3787963 : = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
7848 : 3787963 : bytes.quick_push ((unsigned long) el32[index] >> lsb);
7849 : : }
7850 : 651043 : return true;
7851 : : }
7852 : :
7853 : 31499 : if (GET_CODE (x) == CONST_FIXED)
7854 : : {
7855 : 0 : for (unsigned int byte = first_byte; byte < end_byte; ++byte)
7856 : : {
7857 : : /* Always constant because the inputs are. */
7858 : 0 : unsigned int lsb
7859 : 0 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
7860 : 0 : unsigned HOST_WIDE_INT piece = CONST_FIXED_VALUE_LOW (x);
7861 : 0 : if (lsb >= HOST_BITS_PER_WIDE_INT)
7862 : : {
7863 : 0 : lsb -= HOST_BITS_PER_WIDE_INT;
7864 : 0 : piece = CONST_FIXED_VALUE_HIGH (x);
7865 : : }
7866 : 0 : bytes.quick_push (piece >> lsb);
7867 : : }
7868 : : return true;
7869 : : }
7870 : :
7871 : : return false;
7872 : : }
7873 : :
7874 : : /* Read a vector of mode MODE from the target memory image given by BYTES,
7875 : : starting at byte FIRST_BYTE. The vector is known to be encodable using
7876 : : NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each,
7877 : : and BYTES is known to have enough bytes to supply NPATTERNS *
7878 : : NELTS_PER_PATTERN vector elements. Each element of BYTES contains
7879 : : BITS_PER_UNIT bits and the bytes are in target memory order.
7880 : :
7881 : : Return the vector on success, otherwise return NULL_RTX. */
7882 : :
7883 : : rtx
7884 : 228762 : native_decode_vector_rtx (machine_mode mode, const vec<target_unit> &bytes,
7885 : : unsigned int first_byte, unsigned int npatterns,
7886 : : unsigned int nelts_per_pattern)
7887 : : {
7888 : 228762 : rtx_vector_builder builder (mode, npatterns, nelts_per_pattern);
7889 : :
7890 : 457524 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
7891 : : GET_MODE_NUNITS (mode));
7892 : 228762 : if (elt_bits < BITS_PER_UNIT)
7893 : : {
7894 : : /* This is the only case in which elements can be smaller than a byte.
7895 : : Element 0 is always in the lsb of the containing byte. */
7896 : 0 : gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
7897 : 0 : for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
7898 : : {
7899 : 0 : unsigned int bit_index = first_byte * BITS_PER_UNIT + i * elt_bits;
7900 : 0 : unsigned int byte_index = bit_index / BITS_PER_UNIT;
7901 : 0 : unsigned int lsb = bit_index % BITS_PER_UNIT;
7902 : 0 : unsigned int value = bytes[byte_index] >> lsb;
7903 : 0 : builder.quick_push (gen_int_mode (value, GET_MODE_INNER (mode)));
7904 : : }
7905 : : }
7906 : : else
7907 : : {
7908 : 908316 : for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
7909 : : {
7910 : 1359108 : rtx x = native_decode_rtx (GET_MODE_INNER (mode), bytes, first_byte);
7911 : 679554 : if (!x)
7912 : 0 : return NULL_RTX;
7913 : 679554 : builder.quick_push (x);
7914 : 679554 : first_byte += elt_bits / BITS_PER_UNIT;
7915 : : }
7916 : : }
7917 : 228762 : return builder.build ();
7918 : 228762 : }
7919 : :
7920 : : /* Extract a PRECISION-bit integer from bytes [FIRST_BYTE, FIRST_BYTE + SIZE)
7921 : : of target memory image BYTES. */
7922 : :
7923 : : wide_int
7924 : 11954787 : native_decode_int (const vec<target_unit> &bytes, unsigned int first_byte,
7925 : : unsigned int size, unsigned int precision)
7926 : : {
7927 : : /* Pull the bytes msb first, so that we can use simple
7928 : : shift-and-insert wide_int operations. */
7929 : 11954787 : wide_int result (wi::zero (precision));
7930 : 54163324 : for (unsigned int i = 0; i < size; ++i)
7931 : : {
7932 : 42208537 : unsigned int lsb = (size - i - 1) * BITS_PER_UNIT;
7933 : : /* Always constant because the inputs are. */
7934 : 42208537 : unsigned int subbyte
7935 : 42208537 : = subreg_size_offset_from_lsb (1, size, lsb).to_constant ();
7936 : 42208537 : result <<= BITS_PER_UNIT;
7937 : 42208537 : result |= bytes[first_byte + subbyte];
7938 : : }
7939 : 11954787 : return result;
7940 : : }
7941 : :
7942 : : /* Read an rtx of mode MODE from the target memory image given by BYTES,
7943 : : starting at byte FIRST_BYTE. Each element of BYTES contains BITS_PER_UNIT
7944 : : bits and the bytes are in target memory order. The image has enough
7945 : : values to specify all bytes of MODE.
7946 : :
7947 : : Return the rtx on success, otherwise return NULL_RTX. */
7948 : :
7949 : : rtx
7950 : 12253903 : native_decode_rtx (machine_mode mode, const vec<target_unit> &bytes,
7951 : : unsigned int first_byte)
7952 : : {
7953 : 12253903 : if (VECTOR_MODE_P (mode))
7954 : : {
7955 : : /* If we know at compile time how many elements there are,
7956 : : pull each element directly from BYTES. */
7957 : 59097 : unsigned int nelts;
7958 : 118194 : if (GET_MODE_NUNITS (mode).is_constant (&nelts))
7959 : 59097 : return native_decode_vector_rtx (mode, bytes, first_byte, nelts, 1);
7960 : : return NULL_RTX;
7961 : : }
7962 : :
7963 : 12194806 : scalar_int_mode imode;
7964 : 12194806 : if (is_a <scalar_int_mode> (mode, &imode)
7965 : 11954787 : && GET_MODE_PRECISION (imode) <= MAX_BITSIZE_MODE_ANY_INT)
7966 : : {
7967 : 11954787 : auto result = native_decode_int (bytes, first_byte,
7968 : 11954787 : GET_MODE_SIZE (imode),
7969 : 23909574 : GET_MODE_PRECISION (imode));
7970 : 11954787 : return immed_wide_int_const (result, imode);
7971 : 11954787 : }
7972 : :
7973 : 240019 : scalar_float_mode fmode;
7974 : 240019 : if (is_a <scalar_float_mode> (mode, &fmode))
7975 : : {
7976 : : /* We need to build an array of integers in target memory order.
7977 : : All integers before the last one have 32 bits; the last one may
7978 : : have 32 bits or fewer, depending on whether the mode bitsize
7979 : : is divisible by 32. */
7980 : 239989 : long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
7981 : 239989 : unsigned int num_el32 = CEIL (GET_MODE_BITSIZE (fmode), 32);
7982 : 239989 : memset (el32, 0, num_el32 * sizeof (long));
7983 : :
7984 : : /* The (maximum) number of target bytes per element of el32. */
7985 : 239989 : unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
7986 : 239989 : gcc_assert (bytes_per_el32 != 0);
7987 : :
7988 : 239989 : unsigned int mode_bytes = GET_MODE_SIZE (fmode);
7989 : 1670763 : for (unsigned int byte = 0; byte < mode_bytes; ++byte)
7990 : : {
7991 : 1430774 : unsigned int index = byte / bytes_per_el32;
7992 : 1430774 : unsigned int subbyte = byte % bytes_per_el32;
7993 : 1430774 : unsigned int int_bytes = MIN (bytes_per_el32,
7994 : : mode_bytes - index * bytes_per_el32);
7995 : : /* Always constant because the inputs are. */
7996 : 1430774 : unsigned int lsb
7997 : 1430774 : = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
7998 : 1430774 : el32[index] |= (unsigned long) bytes[first_byte + byte] << lsb;
7999 : : }
8000 : 239989 : REAL_VALUE_TYPE r;
8001 : 239989 : real_from_target (&r, el32, fmode);
8002 : 239989 : return const_double_from_real_value (r, fmode);
8003 : : }
8004 : :
8005 : 30 : if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
8006 : : {
8007 : 0 : scalar_mode smode = as_a <scalar_mode> (mode);
8008 : 0 : FIXED_VALUE_TYPE f;
8009 : 0 : f.data.low = 0;
8010 : 0 : f.data.high = 0;
8011 : 0 : f.mode = smode;
8012 : :
8013 : 0 : unsigned int mode_bytes = GET_MODE_SIZE (smode);
8014 : 0 : for (unsigned int byte = 0; byte < mode_bytes; ++byte)
8015 : : {
8016 : : /* Always constant because the inputs are. */
8017 : 0 : unsigned int lsb
8018 : 0 : = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
8019 : 0 : unsigned HOST_WIDE_INT unit = bytes[first_byte + byte];
8020 : 0 : if (lsb >= HOST_BITS_PER_WIDE_INT)
8021 : 0 : f.data.high |= unit << (lsb - HOST_BITS_PER_WIDE_INT);
8022 : : else
8023 : 0 : f.data.low |= unit << lsb;
8024 : : }
8025 : 0 : return CONST_FIXED_FROM_FIXED_VALUE (f, mode);
8026 : : }
8027 : :
8028 : : return NULL_RTX;
8029 : : }
8030 : :
8031 : : /* Simplify a byte offset BYTE into CONST_VECTOR X. The main purpose
8032 : : is to convert a runtime BYTE value into a constant one. */
8033 : :
8034 : : static poly_uint64
8035 : 285885 : simplify_const_vector_byte_offset (rtx x, poly_uint64 byte)
8036 : : {
8037 : : /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
8038 : 285885 : machine_mode mode = GET_MODE (x);
8039 : 571770 : unsigned int elt_bits = vector_element_size (GET_MODE_PRECISION (mode),
8040 : : GET_MODE_NUNITS (mode));
8041 : : /* The number of bits needed to encode one element from each pattern. */
8042 : 285885 : unsigned int sequence_bits = CONST_VECTOR_NPATTERNS (x) * elt_bits;
8043 : :
8044 : : /* Identify the start point in terms of a sequence number and a byte offset
8045 : : within that sequence. */
8046 : 285885 : poly_uint64 first_sequence;
8047 : 285885 : unsigned HOST_WIDE_INT subbit;
8048 : 285885 : if (can_div_trunc_p (byte * BITS_PER_UNIT, sequence_bits,
8049 : : &first_sequence, &subbit))
8050 : : {
8051 : 285885 : unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
8052 : 285885 : if (nelts_per_pattern == 1)
8053 : : /* This is a duplicated vector, so the value of FIRST_SEQUENCE
8054 : : doesn't matter. */
8055 : 233067 : byte = subbit / BITS_PER_UNIT;
8056 : 52818 : else if (nelts_per_pattern == 2 && known_gt (first_sequence, 0U))
8057 : : {
8058 : : /* The subreg drops the first element from each pattern and
8059 : : only uses the second element. Find the first sequence
8060 : : that starts on a byte boundary. */
8061 : 5568 : subbit += least_common_multiple (sequence_bits, BITS_PER_UNIT);
8062 : 5568 : byte = subbit / BITS_PER_UNIT;
8063 : : }
8064 : : }
8065 : 285885 : return byte;
8066 : : }
8067 : :
8068 : : /* Subroutine of simplify_subreg in which:
8069 : :
8070 : : - X is known to be a CONST_VECTOR
8071 : : - OUTERMODE is known to be a vector mode
8072 : :
8073 : : Try to handle the subreg by operating on the CONST_VECTOR encoding
8074 : : rather than on each individual element of the CONST_VECTOR.
8075 : :
8076 : : Return the simplified subreg on success, otherwise return NULL_RTX. */
8077 : :
8078 : : static rtx
8079 : 177336 : simplify_const_vector_subreg (machine_mode outermode, rtx x,
8080 : : machine_mode innermode, unsigned int first_byte)
8081 : : {
8082 : : /* Paradoxical subregs of vectors have dubious semantics. */
8083 : 177336 : if (paradoxical_subreg_p (outermode, innermode))
8084 : : return NULL_RTX;
8085 : :
8086 : : /* We can only preserve the semantics of a stepped pattern if the new
8087 : : vector element is the same as the original one. */
8088 : 177270 : if (CONST_VECTOR_STEPPED_P (x)
8089 : 197704 : && GET_MODE_INNER (outermode) != GET_MODE_INNER (innermode))
8090 : : return NULL_RTX;
8091 : :
8092 : : /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
8093 : 169665 : unsigned int x_elt_bits
8094 : 169665 : = vector_element_size (GET_MODE_PRECISION (innermode),
8095 : : GET_MODE_NUNITS (innermode));
8096 : 169665 : unsigned int out_elt_bits
8097 : 169665 : = vector_element_size (GET_MODE_PRECISION (outermode),
8098 : : GET_MODE_NUNITS (outermode));
8099 : :
8100 : : /* The number of bits needed to encode one element from every pattern
8101 : : of the original vector. */
8102 : 169665 : unsigned int x_sequence_bits = CONST_VECTOR_NPATTERNS (x) * x_elt_bits;
8103 : :
8104 : : /* The number of bits needed to encode one element from every pattern
8105 : : of the result. */
8106 : 169665 : unsigned int out_sequence_bits
8107 : 169665 : = least_common_multiple (x_sequence_bits, out_elt_bits);
8108 : :
8109 : : /* Work out the number of interleaved patterns in the output vector
8110 : : and the number of encoded elements per pattern. */
8111 : 169665 : unsigned int out_npatterns = out_sequence_bits / out_elt_bits;
8112 : 169665 : unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
8113 : :
8114 : : /* The encoding scheme requires the number of elements to be a multiple
8115 : : of the number of patterns, so that each pattern appears at least once
8116 : : and so that the same number of elements appear from each pattern. */
8117 : 339330 : bool ok_p = multiple_p (GET_MODE_NUNITS (outermode), out_npatterns);
8118 : 169665 : unsigned int const_nunits;
8119 : 339330 : if (GET_MODE_NUNITS (outermode).is_constant (&const_nunits)
8120 : 169665 : && (!ok_p || out_npatterns * nelts_per_pattern > const_nunits))
8121 : : {
8122 : : /* Either the encoding is invalid, or applying it would give us
8123 : : more elements than we need. Just encode each element directly. */
8124 : : out_npatterns = const_nunits;
8125 : : nelts_per_pattern = 1;
8126 : : }
8127 : : else if (!ok_p)
8128 : : return NULL_RTX;
8129 : :
8130 : : /* Get enough bytes of X to form the new encoding. */
8131 : 169665 : unsigned int buffer_bits = out_npatterns * nelts_per_pattern * out_elt_bits;
8132 : 169665 : unsigned int buffer_bytes = CEIL (buffer_bits, BITS_PER_UNIT);
8133 : 169665 : auto_vec<target_unit, 128> buffer (buffer_bytes);
8134 : 169665 : if (!native_encode_rtx (innermode, x, buffer, first_byte, buffer_bytes))
8135 : : return NULL_RTX;
8136 : :
8137 : : /* Reencode the bytes as OUTERMODE. */
8138 : 169665 : return native_decode_vector_rtx (outermode, buffer, 0, out_npatterns,
8139 : 169665 : nelts_per_pattern);
8140 : 169665 : }
8141 : :
8142 : : /* Try to simplify a subreg of a constant by encoding the subreg region
8143 : : as a sequence of target bytes and reading them back in the new mode.
8144 : : Return the new value on success, otherwise return null.
8145 : :
8146 : : The subreg has outer mode OUTERMODE, inner mode INNERMODE, inner value X
8147 : : and byte offset FIRST_BYTE. */
8148 : :
8149 : : static rtx
8150 : 11276096 : simplify_immed_subreg (fixed_size_mode outermode, rtx x,
8151 : : machine_mode innermode, unsigned int first_byte)
8152 : : {
8153 : 11276096 : unsigned int buffer_bytes = GET_MODE_SIZE (outermode);
8154 : 11276096 : auto_vec<target_unit, 128> buffer (buffer_bytes);
8155 : :
8156 : : /* Some ports misuse CCmode. */
8157 : 11276096 : if (GET_MODE_CLASS (outermode) == MODE_CC && CONST_INT_P (x))
8158 : : return x;
8159 : :
8160 : : /* Paradoxical subregs read undefined values for bytes outside of the
8161 : : inner value. However, we have traditionally always sign-extended
8162 : : integer constants and zero-extended others. */
8163 : 11275480 : unsigned int inner_bytes = buffer_bytes;
8164 : 11275480 : if (paradoxical_subreg_p (outermode, innermode))
8165 : : {
8166 : 698262 : if (!GET_MODE_SIZE (innermode).is_constant (&inner_bytes))
8167 : 0 : return NULL_RTX;
8168 : :
8169 : 349131 : target_unit filler = 0;
8170 : 349131 : if (CONST_SCALAR_INT_P (x) && wi::neg_p (rtx_mode_t (x, innermode)))
8171 : 28650 : filler = -1;
8172 : :
8173 : : /* Add any leading bytes due to big-endian layout. The number of
8174 : : bytes must be constant because both modes have constant size. */
8175 : 349131 : unsigned int leading_bytes
8176 : 349131 : = -byte_lowpart_offset (outermode, innermode).to_constant ();
8177 : 349131 : for (unsigned int i = 0; i < leading_bytes; ++i)
8178 : 0 : buffer.quick_push (filler);
8179 : :
8180 : 349131 : if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
8181 : 0 : return NULL_RTX;
8182 : :
8183 : : /* Add any trailing bytes due to little-endian layout. */
8184 : 4266412 : while (buffer.length () < buffer_bytes)
8185 : 1784075 : buffer.quick_push (filler);
8186 : : }
8187 : 10926349 : else if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
8188 : : return NULL_RTX;
8189 : 11275480 : rtx ret = native_decode_rtx (outermode, buffer, 0);
8190 : 11275480 : if (ret && FLOAT_MODE_P (outermode))
8191 : : {
8192 : 126221 : auto_vec<target_unit, 128> buffer2 (buffer_bytes);
8193 : 126221 : if (!native_encode_rtx (outermode, ret, buffer2, 0, buffer_bytes))
8194 : : return NULL_RTX;
8195 : 1394242 : for (unsigned int i = 0; i < buffer_bytes; ++i)
8196 : 1268056 : if (buffer[i] != buffer2[i])
8197 : : return NULL_RTX;
8198 : 126221 : }
8199 : : return ret;
8200 : 11276096 : }
8201 : :
8202 : : /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
8203 : : Return 0 if no simplifications are possible. */
8204 : : rtx
8205 : 70067005 : simplify_context::simplify_subreg (machine_mode outermode, rtx op,
8206 : : machine_mode innermode, poly_uint64 byte)
8207 : : {
8208 : : /* Little bit of sanity checking. */
8209 : 70067005 : gcc_assert (innermode != VOIDmode);
8210 : 70067005 : gcc_assert (outermode != VOIDmode);
8211 : 70067005 : gcc_assert (innermode != BLKmode);
8212 : 70067005 : gcc_assert (outermode != BLKmode);
8213 : :
8214 : 70067005 : gcc_assert (GET_MODE (op) == innermode
8215 : : || GET_MODE (op) == VOIDmode);
8216 : :
8217 : 140134010 : poly_uint64 outersize = GET_MODE_SIZE (outermode);
8218 : 70067005 : if (!multiple_p (byte, outersize))
8219 : : return NULL_RTX;
8220 : :
8221 : 140134002 : poly_uint64 innersize = GET_MODE_SIZE (innermode);
8222 : 70067001 : if (maybe_ge (byte, innersize))
8223 : : return NULL_RTX;
8224 : :
8225 : 70067001 : if (outermode == innermode && known_eq (byte, 0U))
8226 : 4690543 : return op;
8227 : :
8228 : 65376458 : if (GET_CODE (op) == CONST_VECTOR)
8229 : 285885 : byte = simplify_const_vector_byte_offset (op, byte);
8230 : :
8231 : 130752916 : if (multiple_p (byte, GET_MODE_UNIT_SIZE (innermode)))
8232 : : {
8233 : 59434040 : rtx elt;
8234 : :
8235 : 51035886 : if (VECTOR_MODE_P (outermode)
8236 : 25194462 : && GET_MODE_INNER (outermode) == GET_MODE_INNER (innermode)
8237 : 61127345 : && vec_duplicate_p (op, &elt))
8238 : 13926 : return gen_vec_duplicate (outermode, elt);
8239 : :
8240 : 59430278 : if (outermode == GET_MODE_INNER (innermode)
8241 : 59430278 : && vec_duplicate_p (op, &elt))
8242 : 10164 : return elt;
8243 : : }
8244 : :
8245 : 65362532 : if (CONST_SCALAR_INT_P (op)
8246 : 54250905 : || CONST_DOUBLE_AS_FLOAT_P (op)
8247 : 54193934 : || CONST_FIXED_P (op)
8248 : 54193934 : || GET_CODE (op) == CONST_VECTOR)
8249 : : {
8250 : 11445761 : unsigned HOST_WIDE_INT cbyte;
8251 : 11445761 : if (byte.is_constant (&cbyte))
8252 : : {
8253 : 11445761 : if (GET_CODE (op) == CONST_VECTOR && VECTOR_MODE_P (outermode))
8254 : : {
8255 : 177336 : rtx tmp = simplify_const_vector_subreg (outermode, op,
8256 : : innermode, cbyte);
8257 : 177336 : if (tmp)
8258 : 11445761 : return tmp;
8259 : : }
8260 : :
8261 : 11276096 : fixed_size_mode fs_outermode;
8262 : 11276096 : if (is_a <fixed_size_mode> (outermode, &fs_outermode))
8263 : 11276096 : return simplify_immed_subreg (fs_outermode, op, innermode, cbyte);
8264 : : }
8265 : : }
8266 : :
8267 : : /* Changing mode twice with SUBREG => just change it once,
8268 : : or not at all if changing back op starting mode. */
8269 : 53916771 : if (GET_CODE (op) == SUBREG)
8270 : : {
8271 : 1275029 : machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
8272 : 2550058 : poly_uint64 innermostsize = GET_MODE_SIZE (innermostmode);
8273 : 1275029 : rtx newx;
8274 : :
8275 : : /* Make sure that the relationship between the two subregs is
8276 : : known at compile time. */
8277 : 1275029 : if (!ordered_p (outersize, innermostsize))
8278 : : return NULL_RTX;
8279 : :
8280 : 1275029 : if (outermode == innermostmode
8281 : 689378 : && known_eq (byte, subreg_lowpart_offset (outermode, innermode))
8282 : 1964406 : && known_eq (SUBREG_BYTE (op),
8283 : : subreg_lowpart_offset (innermode, innermostmode)))
8284 : 689377 : return SUBREG_REG (op);
8285 : :
8286 : : /* Work out the memory offset of the final OUTERMODE value relative
8287 : : to the inner value of OP. */
8288 : 585652 : poly_int64 mem_offset = subreg_memory_offset (outermode,
8289 : : innermode, byte);
8290 : 585652 : poly_int64 op_mem_offset = subreg_memory_offset (op);
8291 : 585652 : poly_int64 final_offset = mem_offset + op_mem_offset;
8292 : :
8293 : : /* See whether resulting subreg will be paradoxical. */
8294 : 585652 : if (!paradoxical_subreg_p (outermode, innermostmode))
8295 : : {
8296 : : /* Bail out in case resulting subreg would be incorrect. */
8297 : 984684 : if (maybe_lt (final_offset, 0)
8298 : 984679 : || maybe_ge (poly_uint64 (final_offset), innermostsize)
8299 : 984683 : || !multiple_p (final_offset, outersize))
8300 : 5 : return NULL_RTX;
8301 : : }
8302 : : else
8303 : : {
8304 : 93310 : poly_int64 required_offset = subreg_memory_offset (outermode,
8305 : : innermostmode, 0);
8306 : 93310 : if (maybe_ne (final_offset, required_offset))
8307 : 0 : return NULL_RTX;
8308 : : /* Paradoxical subregs always have byte offset 0. */
8309 : 93310 : final_offset = 0;
8310 : : }
8311 : :
8312 : : /* Recurse for further possible simplifications. */
8313 : 585647 : newx = simplify_subreg (outermode, SUBREG_REG (op), innermostmode,
8314 : 585647 : final_offset);
8315 : 585647 : if (newx)
8316 : : return newx;
8317 : 585270 : if (validate_subreg (outermode, innermostmode,
8318 : 585270 : SUBREG_REG (op), final_offset))
8319 : : {
8320 : 531648 : newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
8321 : 531648 : if (SUBREG_PROMOTED_VAR_P (op)
8322 : 321 : && SUBREG_PROMOTED_SIGN (op) >= 0
8323 : 321 : && GET_MODE_CLASS (outermode) == MODE_INT
8324 : 317 : && known_ge (outersize, innersize)
8325 : 292 : && known_le (outersize, innermostsize)
8326 : 531652 : && subreg_lowpart_p (newx))
8327 : : {
8328 : 4 : SUBREG_PROMOTED_VAR_P (newx) = 1;
8329 : 4 : SUBREG_PROMOTED_SET (newx, SUBREG_PROMOTED_GET (op));
8330 : : }
8331 : 531648 : return newx;
8332 : : }
8333 : : return NULL_RTX;
8334 : : }
8335 : :
8336 : : /* SUBREG of a hard register => just change the register number
8337 : : and/or mode. If the hard register is not valid in that mode,
8338 : : suppress this simplification. If the hard register is the stack,
8339 : : frame, or argument pointer, leave this as a SUBREG. */
8340 : :
8341 : 52641742 : if (REG_P (op) && HARD_REGISTER_P (op))
8342 : : {
8343 : 10881119 : unsigned int regno, final_regno;
8344 : :
8345 : 10881119 : regno = REGNO (op);
8346 : 10881119 : final_regno = simplify_subreg_regno (regno, innermode, byte, outermode);
8347 : 10881119 : if (HARD_REGISTER_NUM_P (final_regno))
8348 : : {
8349 : 10857106 : rtx x = gen_rtx_REG_offset (op, outermode, final_regno,
8350 : : subreg_memory_offset (outermode,
8351 : : innermode, byte));
8352 : :
8353 : : /* Propagate original regno. We don't have any way to specify
8354 : : the offset inside original regno, so do so only for lowpart.
8355 : : The information is used only by alias analysis that cannot
8356 : : grog partial register anyway. */
8357 : :
8358 : 10857106 : if (known_eq (subreg_lowpart_offset (outermode, innermode), byte))
8359 : 8156059 : ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op);
8360 : 10857106 : return x;
8361 : : }
8362 : : }
8363 : :
8364 : : /* If we have a SUBREG of a register that we are replacing and we are
8365 : : replacing it with a MEM, make a new MEM and try replacing the
8366 : : SUBREG with it. Don't do this if the MEM has a mode-dependent address
8367 : : or if we would be widening it. */
8368 : :
8369 : 41784636 : if (MEM_P (op)
8370 : 1728100 : && ! mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op))
8371 : : /* Allow splitting of volatile memory references in case we don't
8372 : : have instruction to move the whole thing. */
8373 : 1728097 : && (! MEM_VOLATILE_P (op)
8374 : 44163 : || ! have_insn_for (SET, innermode))
8375 : : && !(STRICT_ALIGNMENT && MEM_ALIGN (op) < GET_MODE_ALIGNMENT (outermode))
8376 : 43468570 : && known_le (outersize, innersize))
8377 : 824922 : return adjust_address_nv (op, outermode, byte);
8378 : :
8379 : : /* Handle complex or vector values represented as CONCAT or VEC_CONCAT
8380 : : of two parts. */
8381 : 40959714 : if (GET_CODE (op) == CONCAT
8382 : 40959714 : || GET_CODE (op) == VEC_CONCAT)
8383 : : {
8384 : 192267 : poly_uint64 final_offset;
8385 : 192267 : rtx part, res;
8386 : :
8387 : 192267 : machine_mode part_mode = GET_MODE (XEXP (op, 0));
8388 : 192267 : if (part_mode == VOIDmode)
8389 : 11 : part_mode = GET_MODE_INNER (GET_MODE (op));
8390 : 384534 : poly_uint64 part_size = GET_MODE_SIZE (part_mode);
8391 : 192267 : if (known_lt (byte, part_size))
8392 : : {
8393 : 190521 : part = XEXP (op, 0);
8394 : 190521 : final_offset = byte;
8395 : : }
8396 : 1746 : else if (known_ge (byte, part_size))
8397 : : {
8398 : 1746 : part = XEXP (op, 1);
8399 : 1746 : final_offset = byte - part_size;
8400 : : }
8401 : : else
8402 : : return NULL_RTX;
8403 : :
8404 : 192267 : if (maybe_gt (final_offset + outersize, part_size))
8405 : : return NULL_RTX;
8406 : :
8407 : 129778 : part_mode = GET_MODE (part);
8408 : 129778 : if (part_mode == VOIDmode)
8409 : 0 : part_mode = GET_MODE_INNER (GET_MODE (op));
8410 : 129778 : res = simplify_subreg (outermode, part, part_mode, final_offset);
8411 : 129778 : if (res)
8412 : : return res;
8413 : 293 : if (validate_subreg (outermode, part_mode, part, final_offset))
8414 : 293 : return gen_rtx_SUBREG (outermode, part, final_offset);
8415 : : return NULL_RTX;
8416 : : }
8417 : :
8418 : : /* Simplify
8419 : : (subreg (vec_merge (X)
8420 : : (vector)
8421 : : (const_int ((1 << N) | M)))
8422 : : (N * sizeof (outermode)))
8423 : : to
8424 : : (subreg (X) (N * sizeof (outermode)))
8425 : : */
8426 : 40767447 : unsigned int idx;
8427 : 81534894 : if (constant_multiple_p (byte, GET_MODE_SIZE (outermode), &idx)
8428 : 40767447 : && idx < HOST_BITS_PER_WIDE_INT
8429 : 40767447 : && GET_CODE (op) == VEC_MERGE
8430 : 612392 : && GET_MODE_INNER (innermode) == outermode
8431 : 4840 : && CONST_INT_P (XEXP (op, 2))
8432 : 40771705 : && (UINTVAL (XEXP (op, 2)) & (HOST_WIDE_INT_1U << idx)) != 0)
8433 : 4249 : return simplify_gen_subreg (outermode, XEXP (op, 0), innermode, byte);
8434 : :
8435 : : /* A SUBREG resulting from a zero extension may fold to zero if
8436 : : it extracts higher bits that the ZERO_EXTEND's source bits. */
8437 : 40763198 : if (GET_CODE (op) == ZERO_EXTEND && SCALAR_INT_MODE_P (innermode))
8438 : : {
8439 : 223243 : poly_uint64 bitpos = subreg_lsb_1 (outermode, innermode, byte);
8440 : 223243 : if (known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (XEXP (op, 0)))))
8441 : 55843 : return CONST0_RTX (outermode);
8442 : : }
8443 : :
8444 : : /* Optimize SUBREGS of scalar integral ASHIFT by a valid constant. */
8445 : 40707355 : if (GET_CODE (op) == ASHIFT
8446 : 740667 : && SCALAR_INT_MODE_P (innermode)
8447 : 713685 : && CONST_INT_P (XEXP (op, 1))
8448 : 638664 : && INTVAL (XEXP (op, 1)) > 0
8449 : 42086636 : && known_gt (GET_MODE_BITSIZE (innermode), INTVAL (XEXP (op, 1))))
8450 : : {
8451 : 638614 : HOST_WIDE_INT val = INTVAL (XEXP (op, 1));
8452 : : /* A lowpart SUBREG of a ASHIFT by a constant may fold to zero. */
8453 : 638614 : if (known_eq (subreg_lowpart_offset (outermode, innermode), byte)
8454 : 1238937 : && known_le (GET_MODE_BITSIZE (outermode), val))
8455 : 208376 : return CONST0_RTX (outermode);
8456 : : /* Optimize the highpart SUBREG of a suitable ASHIFT (ZERO_EXTEND). */
8457 : 466406 : if (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
8458 : 36799 : && GET_MODE (XEXP (XEXP (op, 0), 0)) == outermode
8459 : 73382 : && known_eq (GET_MODE_BITSIZE (outermode), val)
8460 : 72336 : && known_eq (GET_MODE_BITSIZE (innermode), 2 * val)
8461 : 503205 : && known_eq (subreg_highpart_offset (outermode, innermode), byte))
8462 : 36168 : return XEXP (XEXP (op, 0), 0);
8463 : : }
8464 : :
8465 : 42011372 : auto distribute_subreg = [&](rtx op)
8466 : : {
8467 : 1512393 : return simplify_subreg (outermode, op, innermode, byte);
8468 : 40498979 : };
8469 : :
8470 : : /* Try distributing the subreg through logic operations, if that
8471 : : leads to all subexpressions being simplified. For example,
8472 : : distributing the outer subreg in:
8473 : :
8474 : : (subreg:SI (not:QI (subreg:QI (reg:SI X) <lowpart>)) 0)
8475 : :
8476 : : gives:
8477 : :
8478 : : (not:SI (reg:SI X))
8479 : :
8480 : : This should be a win if the outermode is word_mode, since logical
8481 : : operations on word_mode should (a) be no more expensive than logical
8482 : : operations on subword modes and (b) are likely to be cheaper than
8483 : : logical operations on multiword modes.
8484 : :
8485 : : Otherwise, handle the case where the subreg is non-narrowing and does
8486 : : not change the number of words. The non-narrowing condition ensures
8487 : : that we don't convert word_mode operations to subword operations. */
8488 : 40498979 : scalar_int_mode int_outermode, int_innermode;
8489 : 40498979 : if (is_a <scalar_int_mode> (outermode, &int_outermode)
8490 : 33858016 : && is_a <scalar_int_mode> (innermode, &int_innermode)
8491 : 73252853 : && (outermode == word_mode
8492 : 18325107 : || ((GET_MODE_PRECISION (int_outermode)
8493 : 18325107 : >= GET_MODE_PRECISION (int_innermode))
8494 : 4672920 : && (CEIL (GET_MODE_SIZE (int_outermode), UNITS_PER_WORD)
8495 : 4592726 : <= CEIL (GET_MODE_SIZE (int_innermode), UNITS_PER_WORD)))))
8496 : 18960413 : switch (GET_CODE (op))
8497 : : {
8498 : 33722 : case NOT:
8499 : 33722 : if (rtx op0 = distribute_subreg (XEXP (op, 0)))
8500 : 1382 : return simplify_gen_unary (GET_CODE (op), outermode, op0, outermode);
8501 : : break;
8502 : :
8503 : 480192 : case AND:
8504 : 480192 : case IOR:
8505 : 480192 : case XOR:
8506 : 480192 : if (rtx op0 = distribute_subreg (XEXP (op, 0)))
8507 : 218751 : if (rtx op1 = distribute_subreg (XEXP (op, 1)))
8508 : 214676 : return simplify_gen_binary (GET_CODE (op), outermode, op0, op1);
8509 : : break;
8510 : :
8511 : : default:
8512 : : break;
8513 : : }
8514 : :
8515 : 40282921 : if (is_a <scalar_int_mode> (outermode, &int_outermode)
8516 : 33641958 : && is_a <scalar_int_mode> (innermode, &int_innermode)
8517 : 73924879 : && known_eq (byte, subreg_lowpart_offset (int_outermode, int_innermode)))
8518 : : {
8519 : : /* Handle polynomial integers. The upper bits of a paradoxical
8520 : : subreg are undefined, so this is safe regardless of whether
8521 : : we're truncating or extending. */
8522 : 30282307 : if (CONST_POLY_INT_P (op))
8523 : : {
8524 : : poly_wide_int val
8525 : : = poly_wide_int::from (const_poly_int_value (op),
8526 : : GET_MODE_PRECISION (int_outermode),
8527 : : SIGNED);
8528 : : return immed_wide_int_const (val, int_outermode);
8529 : : }
8530 : :
8531 : 30282307 : if (GET_MODE_PRECISION (int_outermode)
8532 : 30282307 : < GET_MODE_PRECISION (int_innermode))
8533 : : {
8534 : 17168884 : rtx tem = simplify_truncation (int_outermode, op, int_innermode);
8535 : 17168884 : if (tem)
8536 : : return tem;
8537 : : }
8538 : : }
8539 : :
8540 : : /* If the outer mode is not integral, try taking a subreg with the equivalent
8541 : : integer outer mode and then bitcasting the result.
8542 : : Other simplifications rely on integer to integer subregs and we'd
8543 : : potentially miss out on optimizations otherwise. */
8544 : 78592130 : if (known_gt (GET_MODE_SIZE (innermode),
8545 : : GET_MODE_SIZE (outermode))
8546 : 19591256 : && SCALAR_INT_MODE_P (innermode)
8547 : 18524564 : && !SCALAR_INT_MODE_P (outermode)
8548 : 59061375 : && int_mode_for_size (GET_MODE_BITSIZE (outermode),
8549 : 87027 : 0).exists (&int_outermode))
8550 : : {
8551 : 87027 : rtx tem = simplify_subreg (int_outermode, op, innermode, byte);
8552 : 87027 : if (tem)
8553 : 1958 : return lowpart_subreg (outermode, tem, int_outermode);
8554 : : }
8555 : :
8556 : : /* If OP is a vector comparison and the subreg is not changing the
8557 : : number of elements or the size of the elements, change the result
8558 : : of the comparison to the new mode. */
8559 : 39294107 : if (COMPARISON_P (op)
8560 : 247315 : && VECTOR_MODE_P (outermode)
8561 : 187799 : && VECTOR_MODE_P (innermode)
8562 : 563373 : && known_eq (GET_MODE_NUNITS (outermode), GET_MODE_NUNITS (innermode))
8563 : 39655013 : && known_eq (GET_MODE_UNIT_SIZE (outermode),
8564 : : GET_MODE_UNIT_SIZE (innermode)))
8565 : 119958 : return simplify_gen_relational (GET_CODE (op), outermode, innermode,
8566 : 119958 : XEXP (op, 0), XEXP (op, 1));
8567 : :
8568 : : /* Distribute non-paradoxical subregs through logic ops in cases where
8569 : : one term disappears.
8570 : :
8571 : : (subreg:M1 (and:M2 X C1)) -> (subreg:M1 X)
8572 : : (subreg:M1 (ior:M2 X C1)) -> (subreg:M1 C1)
8573 : : (subreg:M1 (xor:M2 X C1)) -> (subreg:M1 (not:M2 X))
8574 : :
8575 : : if M2 is no smaller than M1 and (subreg:M1 C1) is all-ones.
8576 : :
8577 : : (subreg:M1 (and:M2 X C2)) -> (subreg:M1 C2)
8578 : : (subreg:M1 (ior/xor:M2 X C2)) -> (subreg:M1 X)
8579 : :
8580 : : if M2 is no smaller than M1 and (subreg:M1 C2) is zero. */
8581 : 39174149 : if (known_ge (innersize, outersize)
8582 : 25595479 : && GET_MODE_CLASS (outermode) == GET_MODE_CLASS (innermode)
8583 : 23655588 : && (GET_CODE (op) == AND || GET_CODE (op) == IOR || GET_CODE (op) == XOR)
8584 : 40725307 : && CONSTANT_P (XEXP (op, 1)))
8585 : : {
8586 : 772994 : rtx op1_subreg = distribute_subreg (XEXP (op, 1));
8587 : 772994 : if (op1_subreg == CONSTM1_RTX (outermode))
8588 : : {
8589 : 122554 : if (GET_CODE (op) == IOR)
8590 : : return op1_subreg;
8591 : 122320 : rtx op0 = XEXP (op, 0);
8592 : 122320 : if (GET_CODE (op) == XOR)
8593 : 777 : op0 = simplify_gen_unary (NOT, innermode, op0, innermode);
8594 : 122320 : return simplify_gen_subreg (outermode, op0, innermode, byte);
8595 : : }
8596 : :
8597 : 650440 : if (op1_subreg == CONST0_RTX (outermode))
8598 : 12627 : return (GET_CODE (op) == AND
8599 : 12627 : ? op1_subreg
8600 : 6734 : : distribute_subreg (XEXP (op, 0)));
8601 : : }
8602 : :
8603 : : return NULL_RTX;
8604 : : }
8605 : :
8606 : : /* Make a SUBREG operation or equivalent if it folds. */
8607 : :
8608 : : rtx
8609 : 44601128 : simplify_context::simplify_gen_subreg (machine_mode outermode, rtx op,
8610 : : machine_mode innermode,
8611 : : poly_uint64 byte)
8612 : : {
8613 : 44601128 : rtx newx;
8614 : :
8615 : 44601128 : newx = simplify_subreg (outermode, op, innermode, byte);
8616 : 44601128 : if (newx)
8617 : : return newx;
8618 : :
8619 : 20768075 : if (GET_CODE (op) == SUBREG
8620 : 20768075 : || GET_CODE (op) == CONCAT
8621 : 20738226 : || CONST_SCALAR_INT_P (op)
8622 : 20738200 : || CONST_DOUBLE_AS_FLOAT_P (op)
8623 : 20738200 : || CONST_FIXED_P (op)
8624 : 20738200 : || GET_CODE (op) == CONST_VECTOR)
8625 : : return NULL_RTX;
8626 : :
8627 : 20738190 : if (validate_subreg (outermode, innermode, op, byte))
8628 : 20705981 : return gen_rtx_SUBREG (outermode, op, byte);
8629 : :
8630 : : return NULL_RTX;
8631 : : }
8632 : :
8633 : : /* Generates a subreg to get the least significant part of EXPR (in mode
8634 : : INNER_MODE) to OUTER_MODE. */
8635 : :
8636 : : rtx
8637 : 33417389 : simplify_context::lowpart_subreg (machine_mode outer_mode, rtx expr,
8638 : : machine_mode inner_mode)
8639 : : {
8640 : 33417389 : return simplify_gen_subreg (outer_mode, expr, inner_mode,
8641 : 33417389 : subreg_lowpart_offset (outer_mode, inner_mode));
8642 : : }
8643 : :
8644 : : /* Generate RTX to select element at INDEX out of vector OP. */
8645 : :
8646 : : rtx
8647 : 674422 : simplify_context::simplify_gen_vec_select (rtx op, unsigned int index)
8648 : : {
8649 : 674422 : gcc_assert (VECTOR_MODE_P (GET_MODE (op)));
8650 : :
8651 : 674422 : scalar_mode imode = GET_MODE_INNER (GET_MODE (op));
8652 : :
8653 : 1348844 : if (known_eq (index * GET_MODE_SIZE (imode),
8654 : : subreg_lowpart_offset (imode, GET_MODE (op))))
8655 : : {
8656 : 674272 : rtx res = lowpart_subreg (imode, op, GET_MODE (op));
8657 : 674272 : if (res)
8658 : : return res;
8659 : : }
8660 : :
8661 : 215 : rtx tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, GEN_INT (index)));
8662 : 215 : return gen_rtx_VEC_SELECT (imode, op, tmp);
8663 : : }
8664 : :
8665 : :
8666 : : /* Simplify X, an rtx expression.
8667 : :
8668 : : Return the simplified expression or NULL if no simplifications
8669 : : were possible.
8670 : :
8671 : : This is the preferred entry point into the simplification routines;
8672 : : however, we still allow passes to call the more specific routines.
8673 : :
8674 : : Right now GCC has three (yes, three) major bodies of RTL simplification
8675 : : code that need to be unified.
8676 : :
8677 : : 1. fold_rtx in cse.cc. This code uses various CSE specific
8678 : : information to aid in RTL simplification.
8679 : :
8680 : : 2. simplify_rtx in combine.cc. Similar to fold_rtx, except that
8681 : : it uses combine specific information to aid in RTL
8682 : : simplification.
8683 : :
8684 : : 3. The routines in this file.
8685 : :
8686 : :
8687 : : Long term we want to only have one body of simplification code; to
8688 : : get to that state I recommend the following steps:
8689 : :
8690 : : 1. Pour over fold_rtx & simplify_rtx and move any simplifications
8691 : : which are not pass dependent state into these routines.
8692 : :
8693 : : 2. As code is moved by #1, change fold_rtx & simplify_rtx to
8694 : : use this routine whenever possible.
8695 : :
8696 : : 3. Allow for pass dependent state to be provided to these
8697 : : routines and add simplifications based on the pass dependent
8698 : : state. Remove code from cse.cc & combine.cc that becomes
8699 : : redundant/dead.
8700 : :
8701 : : It will take time, but ultimately the compiler will be easier to
8702 : : maintain and improve. It's totally silly that when we add a
8703 : : simplification that it needs to be added to 4 places (3 for RTL
8704 : : simplification and 1 for tree simplification. */
8705 : :
8706 : : rtx
8707 : 47436912 : simplify_rtx (const_rtx x)
8708 : : {
8709 : 47436912 : const enum rtx_code code = GET_CODE (x);
8710 : 47436912 : const machine_mode mode = GET_MODE (x);
8711 : :
8712 : 47436912 : switch (GET_RTX_CLASS (code))
8713 : : {
8714 : 900469 : case RTX_UNARY:
8715 : 1800938 : return simplify_unary_operation (code, mode,
8716 : 900469 : XEXP (x, 0), GET_MODE (XEXP (x, 0)));
8717 : 27155605 : case RTX_COMM_ARITH:
8718 : 27155605 : if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
8719 : 527816 : return simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
8720 : :
8721 : : /* Fall through. */
8722 : :
8723 : 33166002 : case RTX_BIN_ARITH:
8724 : 33166002 : return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
8725 : :
8726 : 64437 : case RTX_TERNARY:
8727 : 64437 : case RTX_BITFIELD_OPS:
8728 : 64437 : return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
8729 : 64437 : XEXP (x, 0), XEXP (x, 1),
8730 : 64437 : XEXP (x, 2));
8731 : :
8732 : 174848 : case RTX_COMPARE:
8733 : 174848 : case RTX_COMM_COMPARE:
8734 : 174848 : return simplify_relational_operation (code, mode,
8735 : 174848 : ((GET_MODE (XEXP (x, 0))
8736 : : != VOIDmode)
8737 : : ? GET_MODE (XEXP (x, 0))
8738 : 485 : : GET_MODE (XEXP (x, 1))),
8739 : 174848 : XEXP (x, 0),
8740 : 349696 : XEXP (x, 1));
8741 : :
8742 : 229379 : case RTX_EXTRA:
8743 : 229379 : if (code == SUBREG)
8744 : 2452 : return simplify_subreg (mode, SUBREG_REG (x),
8745 : 2452 : GET_MODE (SUBREG_REG (x)),
8746 : 2452 : SUBREG_BYTE (x));
8747 : : break;
8748 : :
8749 : 6654629 : case RTX_OBJ:
8750 : 6654629 : if (code == LO_SUM)
8751 : : {
8752 : : /* Convert (lo_sum (high FOO) FOO) to FOO. */
8753 : 0 : if (GET_CODE (XEXP (x, 0)) == HIGH
8754 : 0 : && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
8755 : 0 : return XEXP (x, 1);
8756 : : }
8757 : : break;
8758 : :
8759 : : default:
8760 : : break;
8761 : : }
8762 : : return NULL;
8763 : : }
8764 : :
8765 : : #if CHECKING_P
8766 : :
8767 : : namespace selftest {
8768 : :
8769 : : /* Make a unique pseudo REG of mode MODE for use by selftests. */
8770 : :
8771 : : static rtx
8772 : 2672 : make_test_reg (machine_mode mode)
8773 : : {
8774 : 2672 : static int test_reg_num = LAST_VIRTUAL_REGISTER + 1;
8775 : :
8776 : 2672 : return gen_rtx_REG (mode, test_reg_num++);
8777 : : }
8778 : :
8779 : : static void
8780 : 40 : test_scalar_int_ops (machine_mode mode)
8781 : : {
8782 : 40 : rtx op0 = make_test_reg (mode);
8783 : 40 : rtx op1 = make_test_reg (mode);
8784 : 40 : rtx six = GEN_INT (6);
8785 : :
8786 : 40 : rtx neg_op0 = simplify_gen_unary (NEG, mode, op0, mode);
8787 : 40 : rtx not_op0 = simplify_gen_unary (NOT, mode, op0, mode);
8788 : 40 : rtx bswap_op0 = simplify_gen_unary (BSWAP, mode, op0, mode);
8789 : :
8790 : 40 : rtx and_op0_op1 = simplify_gen_binary (AND, mode, op0, op1);
8791 : 40 : rtx ior_op0_op1 = simplify_gen_binary (IOR, mode, op0, op1);
8792 : 40 : rtx xor_op0_op1 = simplify_gen_binary (XOR, mode, op0, op1);
8793 : :
8794 : 40 : rtx and_op0_6 = simplify_gen_binary (AND, mode, op0, six);
8795 : 40 : rtx and_op1_6 = simplify_gen_binary (AND, mode, op1, six);
8796 : :
8797 : : /* Test some binary identities. */
8798 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, op0, const0_rtx));
8799 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (PLUS, mode, const0_rtx, op0));
8800 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MINUS, mode, op0, const0_rtx));
8801 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, op0, const1_rtx));
8802 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (MULT, mode, const1_rtx, op0));
8803 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (DIV, mode, op0, const1_rtx));
8804 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, constm1_rtx));
8805 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, constm1_rtx, op0));
8806 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, const0_rtx));
8807 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, const0_rtx, op0));
8808 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, op0, const0_rtx));
8809 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (XOR, mode, const0_rtx, op0));
8810 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFT, mode, op0, const0_rtx));
8811 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATE, mode, op0, const0_rtx));
8812 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ASHIFTRT, mode, op0, const0_rtx));
8813 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (LSHIFTRT, mode, op0, const0_rtx));
8814 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (ROTATERT, mode, op0, const0_rtx));
8815 : :
8816 : : /* Test some self-inverse operations. */
8817 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (NEG, mode, neg_op0, mode));
8818 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (NOT, mode, not_op0, mode));
8819 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (BSWAP, mode, bswap_op0, mode));
8820 : :
8821 : : /* Test some reflexive operations. */
8822 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (AND, mode, op0, op0));
8823 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (IOR, mode, op0, op0));
8824 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (SMIN, mode, op0, op0));
8825 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (SMAX, mode, op0, op0));
8826 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (UMIN, mode, op0, op0));
8827 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_binary (UMAX, mode, op0, op0));
8828 : :
8829 : 40 : ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (MINUS, mode, op0, op0));
8830 : 40 : ASSERT_RTX_EQ (const0_rtx, simplify_gen_binary (XOR, mode, op0, op0));
8831 : :
8832 : : /* Test simplify_distributive_operation. */
8833 : 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, xor_op0_op1, six),
8834 : : simplify_gen_binary (XOR, mode, and_op0_6, and_op1_6));
8835 : 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, ior_op0_op1, six),
8836 : : simplify_gen_binary (IOR, mode, and_op0_6, and_op1_6));
8837 : 40 : ASSERT_RTX_EQ (simplify_gen_binary (AND, mode, and_op0_op1, six),
8838 : : simplify_gen_binary (AND, mode, and_op0_6, and_op1_6));
8839 : :
8840 : : /* Test useless extensions are eliminated. */
8841 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (TRUNCATE, mode, op0, mode));
8842 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (ZERO_EXTEND, mode, op0, mode));
8843 : 40 : ASSERT_RTX_EQ (op0, simplify_gen_unary (SIGN_EXTEND, mode, op0, mode));
8844 : 40 : ASSERT_RTX_EQ (op0, lowpart_subreg (mode, op0, mode));
8845 : 40 : }
8846 : :
8847 : : /* Verify some simplifications of integer extension/truncation.
8848 : : Machine mode BMODE is the guaranteed wider than SMODE. */
8849 : :
8850 : : static void
8851 : 24 : test_scalar_int_ext_ops (machine_mode bmode, machine_mode smode)
8852 : : {
8853 : 24 : rtx sreg = make_test_reg (smode);
8854 : :
8855 : : /* Check truncation of extension. */
8856 : 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
8857 : : simplify_gen_unary (ZERO_EXTEND, bmode,
8858 : : sreg, smode),
8859 : : bmode),
8860 : : sreg);
8861 : 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
8862 : : simplify_gen_unary (SIGN_EXTEND, bmode,
8863 : : sreg, smode),
8864 : : bmode),
8865 : : sreg);
8866 : 24 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
8867 : : lowpart_subreg (bmode, sreg, smode),
8868 : : bmode),
8869 : : sreg);
8870 : :
8871 : : /* Test extensions, followed by logic ops, followed by truncations. */
8872 : 24 : rtx bsubreg = lowpart_subreg (bmode, sreg, smode);
8873 : 24 : rtx smask = gen_int_mode (GET_MODE_MASK (smode), bmode);
8874 : 24 : rtx inv_smask = gen_int_mode (~GET_MODE_MASK (smode), bmode);
8875 : 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
8876 : : simplify_gen_binary (AND, bmode,
8877 : : bsubreg, smask),
8878 : : bmode),
8879 : : sreg);
8880 : 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
8881 : : simplify_gen_binary (AND, bmode,
8882 : : bsubreg, inv_smask),
8883 : : bmode),
8884 : : const0_rtx);
8885 : 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
8886 : : simplify_gen_binary (IOR, bmode,
8887 : : bsubreg, smask),
8888 : : bmode),
8889 : : constm1_rtx);
8890 : 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
8891 : : simplify_gen_binary (IOR, bmode,
8892 : : bsubreg, inv_smask),
8893 : : bmode),
8894 : : sreg);
8895 : 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
8896 : : simplify_gen_binary (XOR, bmode,
8897 : : bsubreg, smask),
8898 : : bmode),
8899 : : lowpart_subreg (smode,
8900 : : gen_rtx_NOT (bmode, bsubreg),
8901 : : bmode));
8902 : 24 : ASSERT_RTX_EQ (lowpart_subreg (smode,
8903 : : simplify_gen_binary (XOR, bmode,
8904 : : bsubreg, inv_smask),
8905 : : bmode),
8906 : : sreg);
8907 : :
8908 : 24 : if (known_le (GET_MODE_PRECISION (bmode), BITS_PER_WORD))
8909 : : {
8910 : 24 : rtx breg1 = make_test_reg (bmode);
8911 : 24 : rtx breg2 = make_test_reg (bmode);
8912 : 24 : rtx ssubreg1 = lowpart_subreg (smode, breg1, bmode);
8913 : 24 : rtx ssubreg2 = lowpart_subreg (smode, breg2, bmode);
8914 : 24 : rtx not_1 = simplify_gen_unary (NOT, smode, ssubreg1, smode);
8915 : 24 : rtx and_12 = simplify_gen_binary (AND, smode, ssubreg1, ssubreg2);
8916 : 24 : rtx ior_12 = simplify_gen_binary (IOR, smode, ssubreg1, ssubreg2);
8917 : 24 : rtx xor_12 = simplify_gen_binary (XOR, smode, ssubreg1, ssubreg2);
8918 : 24 : rtx and_n12 = simplify_gen_binary (AND, smode, not_1, ssubreg2);
8919 : 24 : rtx ior_n12 = simplify_gen_binary (IOR, smode, not_1, ssubreg2);
8920 : 24 : rtx xor_12_c = simplify_gen_binary (XOR, smode, xor_12, const1_rtx);
8921 : 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, not_1, smode),
8922 : : gen_rtx_NOT (bmode, breg1));
8923 : 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, and_12, smode),
8924 : : gen_rtx_AND (bmode, breg1, breg2));
8925 : 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, ior_12, smode),
8926 : : gen_rtx_IOR (bmode, breg1, breg2));
8927 : 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, xor_12, smode),
8928 : : gen_rtx_XOR (bmode, breg1, breg2));
8929 : 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, and_n12, smode),
8930 : : gen_rtx_AND (bmode, gen_rtx_NOT (bmode, breg1), breg2));
8931 : 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, ior_n12, smode),
8932 : : gen_rtx_IOR (bmode, gen_rtx_NOT (bmode, breg1), breg2));
8933 : 24 : ASSERT_RTX_EQ (lowpart_subreg (bmode, xor_12_c, smode),
8934 : : gen_rtx_XOR (bmode,
8935 : : gen_rtx_XOR (bmode, breg1, breg2),
8936 : : const1_rtx));
8937 : : }
8938 : 24 : }
8939 : :
8940 : : /* Verify more simplifications of integer extension/truncation.
8941 : : BMODE is wider than MMODE which is wider than SMODE. */
8942 : :
8943 : : static void
8944 : 16 : test_scalar_int_ext_ops2 (machine_mode bmode, machine_mode mmode,
8945 : : machine_mode smode)
8946 : : {
8947 : 16 : rtx breg = make_test_reg (bmode);
8948 : 16 : rtx mreg = make_test_reg (mmode);
8949 : 16 : rtx sreg = make_test_reg (smode);
8950 : :
8951 : : /* Check truncate of truncate. */
8952 : 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
8953 : : simplify_gen_unary (TRUNCATE, mmode,
8954 : : breg, bmode),
8955 : : mmode),
8956 : : simplify_gen_unary (TRUNCATE, smode, breg, bmode));
8957 : :
8958 : : /* Check extension of extension. */
8959 : 16 : ASSERT_RTX_EQ (simplify_gen_unary (ZERO_EXTEND, bmode,
8960 : : simplify_gen_unary (ZERO_EXTEND, mmode,
8961 : : sreg, smode),
8962 : : mmode),
8963 : : simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
8964 : 16 : ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
8965 : : simplify_gen_unary (SIGN_EXTEND, mmode,
8966 : : sreg, smode),
8967 : : mmode),
8968 : : simplify_gen_unary (SIGN_EXTEND, bmode, sreg, smode));
8969 : 16 : ASSERT_RTX_EQ (simplify_gen_unary (SIGN_EXTEND, bmode,
8970 : : simplify_gen_unary (ZERO_EXTEND, mmode,
8971 : : sreg, smode),
8972 : : mmode),
8973 : : simplify_gen_unary (ZERO_EXTEND, bmode, sreg, smode));
8974 : :
8975 : : /* Check truncation of extension. */
8976 : 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
8977 : : simplify_gen_unary (ZERO_EXTEND, bmode,
8978 : : mreg, mmode),
8979 : : bmode),
8980 : : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
8981 : 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
8982 : : simplify_gen_unary (SIGN_EXTEND, bmode,
8983 : : mreg, mmode),
8984 : : bmode),
8985 : : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
8986 : 16 : ASSERT_RTX_EQ (simplify_gen_unary (TRUNCATE, smode,
8987 : : lowpart_subreg (bmode, mreg, mmode),
8988 : : bmode),
8989 : : simplify_gen_unary (TRUNCATE, smode, mreg, mmode));
8990 : 16 : }
8991 : :
8992 : : /* Test comparisons of comparisons, with the inner comparisons being
8993 : : between values of mode MODE2 and producing results of mode MODE1,
8994 : : and with the outer comparisons producing results of mode MODE0. */
8995 : :
8996 : : static void
8997 : 4 : test_comparisons (machine_mode mode0, machine_mode mode1, machine_mode mode2)
8998 : : {
8999 : 4 : rtx reg0 = make_test_reg (mode2);
9000 : 4 : rtx reg1 = make_test_reg (mode2);
9001 : :
9002 : 4 : static const rtx_code codes[] = {
9003 : : EQ, NE, LT, LTU, LE, LEU, GE, GEU, GT, GTU
9004 : : };
9005 : 4 : constexpr auto num_codes = ARRAY_SIZE (codes);
9006 : 4 : rtx cmps[num_codes];
9007 : 4 : rtx vals[] = { constm1_rtx, const0_rtx, const1_rtx };
9008 : :
9009 : 44 : for (unsigned int i = 0; i < num_codes; ++i)
9010 : 40 : cmps[i] = gen_rtx_fmt_ee (codes[i], mode1, reg0, reg1);
9011 : :
9012 : 44 : for (auto code : codes)
9013 : 440 : for (unsigned int i0 = 0; i0 < num_codes; ++i0)
9014 : 4400 : for (unsigned int i1 = 0; i1 < num_codes; ++i1)
9015 : : {
9016 : 4000 : rtx cmp_res = simplify_relational_operation (code, mode0, mode1,
9017 : : cmps[i0], cmps[i1]);
9018 : 4000 : if (i0 >= 2 && i1 >= 2 && (i0 ^ i1) & 1)
9019 : 1280 : ASSERT_TRUE (cmp_res == NULL_RTX);
9020 : : else
9021 : : {
9022 : 2720 : ASSERT_TRUE (cmp_res != NULL_RTX
9023 : : && (CONSTANT_P (cmp_res)
9024 : : || (COMPARISON_P (cmp_res)
9025 : : && GET_MODE (cmp_res) == mode0
9026 : : && REG_P (XEXP (cmp_res, 0))
9027 : : && REG_P (XEXP (cmp_res, 1)))));
9028 : 10880 : for (rtx reg0_val : vals)
9029 : 32640 : for (rtx reg1_val : vals)
9030 : : {
9031 : 24480 : rtx val0 = simplify_const_relational_operation
9032 : 24480 : (codes[i0], mode1, reg0_val, reg1_val);
9033 : 24480 : rtx val1 = simplify_const_relational_operation
9034 : 24480 : (codes[i1], mode1, reg0_val, reg1_val);
9035 : 24480 : rtx val = simplify_const_relational_operation
9036 : 24480 : (code, mode0, val0, val1);
9037 : 24480 : rtx folded = cmp_res;
9038 : 24480 : if (COMPARISON_P (cmp_res))
9039 : 16704 : folded = simplify_const_relational_operation
9040 : 16704 : (GET_CODE (cmp_res), mode0,
9041 : 16704 : XEXP (cmp_res, 0) == reg0 ? reg0_val : reg1_val,
9042 : 16704 : XEXP (cmp_res, 1) == reg0 ? reg0_val : reg1_val);
9043 : 24480 : ASSERT_RTX_EQ (val, folded);
9044 : : }
9045 : : }
9046 : : }
9047 : 4 : }
9048 : :
9049 : :
9050 : : /* Verify some simplifications involving scalar expressions. */
9051 : :
9052 : : static void
9053 : 4 : test_scalar_ops ()
9054 : : {
9055 : 500 : for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
9056 : : {
9057 : 496 : machine_mode mode = (machine_mode) i;
9058 : 496 : if (SCALAR_INT_MODE_P (mode) && mode != BImode)
9059 : 40 : test_scalar_int_ops (mode);
9060 : : }
9061 : :
9062 : 4 : test_scalar_int_ext_ops (HImode, QImode);
9063 : 4 : test_scalar_int_ext_ops (SImode, QImode);
9064 : 4 : test_scalar_int_ext_ops (SImode, HImode);
9065 : 4 : test_scalar_int_ext_ops (DImode, QImode);
9066 : 4 : test_scalar_int_ext_ops (DImode, HImode);
9067 : 4 : test_scalar_int_ext_ops (DImode, SImode);
9068 : :
9069 : 4 : test_scalar_int_ext_ops2 (SImode, HImode, QImode);
9070 : 4 : test_scalar_int_ext_ops2 (DImode, HImode, QImode);
9071 : 4 : test_scalar_int_ext_ops2 (DImode, SImode, QImode);
9072 : 4 : test_scalar_int_ext_ops2 (DImode, SImode, HImode);
9073 : :
9074 : 4 : test_comparisons (QImode, HImode, SImode);
9075 : 4 : }
9076 : :
9077 : : /* Test vector simplifications involving VEC_DUPLICATE in which the
9078 : : operands and result have vector mode MODE. SCALAR_REG is a pseudo
9079 : : register that holds one element of MODE. */
9080 : :
9081 : : static void
9082 : 224 : test_vector_ops_duplicate (machine_mode mode, rtx scalar_reg)
9083 : : {
9084 : 224 : scalar_mode inner_mode = GET_MODE_INNER (mode);
9085 : 224 : rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
9086 : 448 : poly_uint64 nunits = GET_MODE_NUNITS (mode);
9087 : 224 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
9088 : : {
9089 : : /* Test some simple unary cases with VEC_DUPLICATE arguments. */
9090 : 124 : rtx not_scalar_reg = gen_rtx_NOT (inner_mode, scalar_reg);
9091 : 124 : rtx duplicate_not = gen_rtx_VEC_DUPLICATE (mode, not_scalar_reg);
9092 : 124 : ASSERT_RTX_EQ (duplicate,
9093 : : simplify_unary_operation (NOT, mode,
9094 : : duplicate_not, mode));
9095 : :
9096 : 124 : rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
9097 : 124 : rtx duplicate_neg = gen_rtx_VEC_DUPLICATE (mode, neg_scalar_reg);
9098 : 124 : ASSERT_RTX_EQ (duplicate,
9099 : : simplify_unary_operation (NEG, mode,
9100 : : duplicate_neg, mode));
9101 : :
9102 : : /* Test some simple binary cases with VEC_DUPLICATE arguments. */
9103 : 124 : ASSERT_RTX_EQ (duplicate,
9104 : : simplify_binary_operation (PLUS, mode, duplicate,
9105 : : CONST0_RTX (mode)));
9106 : :
9107 : 124 : ASSERT_RTX_EQ (duplicate,
9108 : : simplify_binary_operation (MINUS, mode, duplicate,
9109 : : CONST0_RTX (mode)));
9110 : :
9111 : 124 : ASSERT_RTX_PTR_EQ (CONST0_RTX (mode),
9112 : : simplify_binary_operation (MINUS, mode, duplicate,
9113 : : duplicate));
9114 : : }
9115 : :
9116 : : /* Test a scalar VEC_SELECT of a VEC_DUPLICATE. */
9117 : 224 : rtx zero_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const0_rtx));
9118 : 224 : ASSERT_RTX_PTR_EQ (scalar_reg,
9119 : : simplify_binary_operation (VEC_SELECT, inner_mode,
9120 : : duplicate, zero_par));
9121 : :
9122 : 224 : unsigned HOST_WIDE_INT const_nunits;
9123 : 224 : if (nunits.is_constant (&const_nunits))
9124 : : {
9125 : : /* And again with the final element. */
9126 : 224 : rtx last_index = gen_int_mode (const_nunits - 1, word_mode);
9127 : 224 : rtx last_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, last_index));
9128 : 224 : ASSERT_RTX_PTR_EQ (scalar_reg,
9129 : : simplify_binary_operation (VEC_SELECT, inner_mode,
9130 : : duplicate, last_par));
9131 : :
9132 : : /* Test a scalar subreg of a VEC_MERGE of a VEC_DUPLICATE. */
9133 : : /* Skip this test for vectors of booleans, because offset is in bytes,
9134 : : while vec_merge indices are in elements (usually bits). */
9135 : 224 : if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL)
9136 : : {
9137 : 224 : rtx vector_reg = make_test_reg (mode);
9138 : 3508 : for (unsigned HOST_WIDE_INT i = 0; i < const_nunits; i++)
9139 : : {
9140 : 3288 : if (i >= HOST_BITS_PER_WIDE_INT)
9141 : : break;
9142 : 3284 : rtx mask = GEN_INT ((HOST_WIDE_INT_1U << i) | (i + 1));
9143 : 3284 : rtx vm = gen_rtx_VEC_MERGE (mode, duplicate, vector_reg, mask);
9144 : 6568 : poly_uint64 offset = i * GET_MODE_SIZE (inner_mode);
9145 : :
9146 : 3284 : ASSERT_RTX_EQ (scalar_reg,
9147 : : simplify_gen_subreg (inner_mode, vm,
9148 : : mode, offset));
9149 : : }
9150 : : }
9151 : : }
9152 : :
9153 : : /* Test a scalar subreg of a VEC_DUPLICATE. */
9154 : 224 : poly_uint64 offset = subreg_lowpart_offset (inner_mode, mode);
9155 : 224 : ASSERT_RTX_EQ (scalar_reg,
9156 : : simplify_gen_subreg (inner_mode, duplicate,
9157 : : mode, offset));
9158 : :
9159 : 224 : machine_mode narrower_mode;
9160 : 224 : if (maybe_ne (nunits, 2U)
9161 : 184 : && multiple_p (nunits, 2)
9162 : 396 : && mode_for_vector (inner_mode, 2).exists (&narrower_mode)
9163 : 396 : && VECTOR_MODE_P (narrower_mode))
9164 : : {
9165 : : /* Test VEC_DUPLICATE of a vector. */
9166 : 172 : rtx_vector_builder nbuilder (narrower_mode, 2, 1);
9167 : 172 : nbuilder.quick_push (const0_rtx);
9168 : 172 : nbuilder.quick_push (const1_rtx);
9169 : 172 : rtx_vector_builder builder (mode, 2, 1);
9170 : 172 : builder.quick_push (const0_rtx);
9171 : 172 : builder.quick_push (const1_rtx);
9172 : 172 : ASSERT_RTX_EQ (builder.build (),
9173 : : simplify_unary_operation (VEC_DUPLICATE, mode,
9174 : : nbuilder.build (),
9175 : : narrower_mode));
9176 : :
9177 : : /* Test VEC_SELECT of a vector. */
9178 : 172 : rtx vec_par
9179 : 172 : = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, const1_rtx, const0_rtx));
9180 : 172 : rtx narrower_duplicate
9181 : 172 : = gen_rtx_VEC_DUPLICATE (narrower_mode, scalar_reg);
9182 : 172 : ASSERT_RTX_EQ (narrower_duplicate,
9183 : : simplify_binary_operation (VEC_SELECT, narrower_mode,
9184 : : duplicate, vec_par));
9185 : :
9186 : : /* Test a vector subreg of a VEC_DUPLICATE. */
9187 : 172 : poly_uint64 offset = subreg_lowpart_offset (narrower_mode, mode);
9188 : 172 : ASSERT_RTX_EQ (narrower_duplicate,
9189 : : simplify_gen_subreg (narrower_mode, duplicate,
9190 : : mode, offset));
9191 : 172 : }
9192 : 224 : }
9193 : :
9194 : : /* Test vector simplifications involving VEC_SERIES in which the
9195 : : operands and result have vector mode MODE. SCALAR_REG is a pseudo
9196 : : register that holds one element of MODE. */
9197 : :
9198 : : static void
9199 : 92 : test_vector_ops_series (machine_mode mode, rtx scalar_reg)
9200 : : {
9201 : : /* Test unary cases with VEC_SERIES arguments. */
9202 : 92 : scalar_mode inner_mode = GET_MODE_INNER (mode);
9203 : 92 : rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
9204 : 92 : rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
9205 : 92 : rtx series_0_r = gen_rtx_VEC_SERIES (mode, const0_rtx, scalar_reg);
9206 : 92 : rtx series_0_nr = gen_rtx_VEC_SERIES (mode, const0_rtx, neg_scalar_reg);
9207 : 92 : rtx series_nr_1 = gen_rtx_VEC_SERIES (mode, neg_scalar_reg, const1_rtx);
9208 : 92 : rtx series_r_m1 = gen_rtx_VEC_SERIES (mode, scalar_reg, constm1_rtx);
9209 : 92 : rtx series_r_r = gen_rtx_VEC_SERIES (mode, scalar_reg, scalar_reg);
9210 : 92 : rtx series_nr_nr = gen_rtx_VEC_SERIES (mode, neg_scalar_reg,
9211 : : neg_scalar_reg);
9212 : 92 : ASSERT_RTX_EQ (series_0_r,
9213 : : simplify_unary_operation (NEG, mode, series_0_nr, mode));
9214 : 92 : ASSERT_RTX_EQ (series_r_m1,
9215 : : simplify_unary_operation (NEG, mode, series_nr_1, mode));
9216 : 92 : ASSERT_RTX_EQ (series_r_r,
9217 : : simplify_unary_operation (NEG, mode, series_nr_nr, mode));
9218 : :
9219 : : /* Test that a VEC_SERIES with a zero step is simplified away. */
9220 : 92 : ASSERT_RTX_EQ (duplicate,
9221 : : simplify_binary_operation (VEC_SERIES, mode,
9222 : : scalar_reg, const0_rtx));
9223 : :
9224 : : /* Test PLUS and MINUS with VEC_SERIES. */
9225 : 92 : rtx series_0_1 = gen_const_vec_series (mode, const0_rtx, const1_rtx);
9226 : 92 : rtx series_0_m1 = gen_const_vec_series (mode, const0_rtx, constm1_rtx);
9227 : 92 : rtx series_r_1 = gen_rtx_VEC_SERIES (mode, scalar_reg, const1_rtx);
9228 : 92 : ASSERT_RTX_EQ (series_r_r,
9229 : : simplify_binary_operation (PLUS, mode, series_0_r,
9230 : : duplicate));
9231 : 92 : ASSERT_RTX_EQ (series_r_1,
9232 : : simplify_binary_operation (PLUS, mode, duplicate,
9233 : : series_0_1));
9234 : 92 : ASSERT_RTX_EQ (series_r_m1,
9235 : : simplify_binary_operation (PLUS, mode, duplicate,
9236 : : series_0_m1));
9237 : 92 : ASSERT_RTX_EQ (series_0_r,
9238 : : simplify_binary_operation (MINUS, mode, series_r_r,
9239 : : duplicate));
9240 : 92 : ASSERT_RTX_EQ (series_r_m1,
9241 : : simplify_binary_operation (MINUS, mode, duplicate,
9242 : : series_0_1));
9243 : 92 : ASSERT_RTX_EQ (series_r_1,
9244 : : simplify_binary_operation (MINUS, mode, duplicate,
9245 : : series_0_m1));
9246 : 92 : ASSERT_RTX_EQ (series_0_m1,
9247 : : simplify_binary_operation (VEC_SERIES, mode, const0_rtx,
9248 : : constm1_rtx));
9249 : :
9250 : : /* Test NEG on constant vector series. */
9251 : 92 : ASSERT_RTX_EQ (series_0_m1,
9252 : : simplify_unary_operation (NEG, mode, series_0_1, mode));
9253 : 92 : ASSERT_RTX_EQ (series_0_1,
9254 : : simplify_unary_operation (NEG, mode, series_0_m1, mode));
9255 : :
9256 : : /* Test PLUS and MINUS on constant vector series. */
9257 : 92 : rtx scalar2 = gen_int_mode (2, inner_mode);
9258 : 92 : rtx scalar3 = gen_int_mode (3, inner_mode);
9259 : 92 : rtx series_1_1 = gen_const_vec_series (mode, const1_rtx, const1_rtx);
9260 : 92 : rtx series_0_2 = gen_const_vec_series (mode, const0_rtx, scalar2);
9261 : 92 : rtx series_1_3 = gen_const_vec_series (mode, const1_rtx, scalar3);
9262 : 92 : ASSERT_RTX_EQ (series_1_1,
9263 : : simplify_binary_operation (PLUS, mode, series_0_1,
9264 : : CONST1_RTX (mode)));
9265 : 92 : ASSERT_RTX_EQ (series_0_m1,
9266 : : simplify_binary_operation (PLUS, mode, CONST0_RTX (mode),
9267 : : series_0_m1));
9268 : 92 : ASSERT_RTX_EQ (series_1_3,
9269 : : simplify_binary_operation (PLUS, mode, series_1_1,
9270 : : series_0_2));
9271 : 92 : ASSERT_RTX_EQ (series_0_1,
9272 : : simplify_binary_operation (MINUS, mode, series_1_1,
9273 : : CONST1_RTX (mode)));
9274 : 92 : ASSERT_RTX_EQ (series_1_1,
9275 : : simplify_binary_operation (MINUS, mode, CONST1_RTX (mode),
9276 : : series_0_m1));
9277 : 92 : ASSERT_RTX_EQ (series_1_1,
9278 : : simplify_binary_operation (MINUS, mode, series_1_3,
9279 : : series_0_2));
9280 : :
9281 : : /* Test MULT between constant vectors. */
9282 : 92 : rtx vec2 = gen_const_vec_duplicate (mode, scalar2);
9283 : 92 : rtx vec3 = gen_const_vec_duplicate (mode, scalar3);
9284 : 92 : rtx scalar9 = gen_int_mode (9, inner_mode);
9285 : 92 : rtx series_3_9 = gen_const_vec_series (mode, scalar3, scalar9);
9286 : 92 : ASSERT_RTX_EQ (series_0_2,
9287 : : simplify_binary_operation (MULT, mode, series_0_1, vec2));
9288 : 92 : ASSERT_RTX_EQ (series_3_9,
9289 : : simplify_binary_operation (MULT, mode, vec3, series_1_3));
9290 : 92 : if (!GET_MODE_NUNITS (mode).is_constant ())
9291 : : ASSERT_FALSE (simplify_binary_operation (MULT, mode, series_0_1,
9292 : : series_0_1));
9293 : :
9294 : : /* Test ASHIFT between constant vectors. */
9295 : 92 : ASSERT_RTX_EQ (series_0_2,
9296 : : simplify_binary_operation (ASHIFT, mode, series_0_1,
9297 : : CONST1_RTX (mode)));
9298 : 92 : if (!GET_MODE_NUNITS (mode).is_constant ())
9299 : : ASSERT_FALSE (simplify_binary_operation (ASHIFT, mode, CONST1_RTX (mode),
9300 : : series_0_1));
9301 : 92 : }
9302 : :
9303 : : static rtx
9304 : 3136 : simplify_merge_mask (rtx x, rtx mask, int op)
9305 : : {
9306 : 0 : return simplify_context ().simplify_merge_mask (x, mask, op);
9307 : : }
9308 : :
9309 : : /* Verify simplify_merge_mask works correctly. */
9310 : :
9311 : : static void
9312 : 224 : test_vec_merge (machine_mode mode)
9313 : : {
9314 : 224 : rtx op0 = make_test_reg (mode);
9315 : 224 : rtx op1 = make_test_reg (mode);
9316 : 224 : rtx op2 = make_test_reg (mode);
9317 : 224 : rtx op3 = make_test_reg (mode);
9318 : 224 : rtx op4 = make_test_reg (mode);
9319 : 224 : rtx op5 = make_test_reg (mode);
9320 : 224 : rtx mask1 = make_test_reg (SImode);
9321 : 224 : rtx mask2 = make_test_reg (SImode);
9322 : 224 : rtx vm1 = gen_rtx_VEC_MERGE (mode, op0, op1, mask1);
9323 : 224 : rtx vm2 = gen_rtx_VEC_MERGE (mode, op2, op3, mask1);
9324 : 224 : rtx vm3 = gen_rtx_VEC_MERGE (mode, op4, op5, mask1);
9325 : :
9326 : : /* Simple vec_merge. */
9327 : 224 : ASSERT_EQ (op0, simplify_merge_mask (vm1, mask1, 0));
9328 : 224 : ASSERT_EQ (op1, simplify_merge_mask (vm1, mask1, 1));
9329 : 224 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 0));
9330 : 224 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 1));
9331 : :
9332 : : /* Nested vec_merge.
9333 : : It's tempting to make this simplify right down to opN, but we don't
9334 : : because all the simplify_* functions assume that the operands have
9335 : : already been simplified. */
9336 : 224 : rtx nvm = gen_rtx_VEC_MERGE (mode, vm1, vm2, mask1);
9337 : 224 : ASSERT_EQ (vm1, simplify_merge_mask (nvm, mask1, 0));
9338 : 224 : ASSERT_EQ (vm2, simplify_merge_mask (nvm, mask1, 1));
9339 : :
9340 : : /* Intermediate unary op. */
9341 : 224 : rtx unop = gen_rtx_NOT (mode, vm1);
9342 : 224 : ASSERT_RTX_EQ (gen_rtx_NOT (mode, op0),
9343 : : simplify_merge_mask (unop, mask1, 0));
9344 : 224 : ASSERT_RTX_EQ (gen_rtx_NOT (mode, op1),
9345 : : simplify_merge_mask (unop, mask1, 1));
9346 : :
9347 : : /* Intermediate binary op. */
9348 : 224 : rtx binop = gen_rtx_PLUS (mode, vm1, vm2);
9349 : 224 : ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op0, op2),
9350 : : simplify_merge_mask (binop, mask1, 0));
9351 : 224 : ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op1, op3),
9352 : : simplify_merge_mask (binop, mask1, 1));
9353 : :
9354 : : /* Intermediate ternary op. */
9355 : 224 : rtx tenop = gen_rtx_FMA (mode, vm1, vm2, vm3);
9356 : 224 : ASSERT_RTX_EQ (gen_rtx_FMA (mode, op0, op2, op4),
9357 : : simplify_merge_mask (tenop, mask1, 0));
9358 : 224 : ASSERT_RTX_EQ (gen_rtx_FMA (mode, op1, op3, op5),
9359 : : simplify_merge_mask (tenop, mask1, 1));
9360 : :
9361 : : /* Side effects. */
9362 : 224 : rtx badop0 = gen_rtx_PRE_INC (mode, op0);
9363 : 224 : rtx badvm = gen_rtx_VEC_MERGE (mode, badop0, op1, mask1);
9364 : 224 : ASSERT_EQ (badop0, simplify_merge_mask (badvm, mask1, 0));
9365 : 224 : ASSERT_EQ (NULL_RTX, simplify_merge_mask (badvm, mask1, 1));
9366 : :
9367 : : /* Called indirectly. */
9368 : 224 : ASSERT_RTX_EQ (gen_rtx_VEC_MERGE (mode, op0, op3, mask1),
9369 : : simplify_rtx (nvm));
9370 : 224 : }
9371 : :
9372 : : /* Test that vector rotate formation works at RTL level. Try various
9373 : : combinations of (REG << C) [|,^,+] (REG >> (<bitwidth> - C)). */
9374 : :
9375 : : static void
9376 : 92 : test_vector_rotate (rtx reg)
9377 : : {
9378 : 92 : machine_mode mode = GET_MODE (reg);
9379 : 92 : unsigned bitwidth = GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT;
9380 : 92 : rtx plus_rtx = gen_rtx_PLUS (mode, reg, reg);
9381 : 92 : rtx lshftrt_amnt = GEN_INT (bitwidth - 1);
9382 : 92 : lshftrt_amnt = gen_const_vec_duplicate (mode, lshftrt_amnt);
9383 : 92 : rtx lshiftrt_rtx = gen_rtx_LSHIFTRT (mode, reg, lshftrt_amnt);
9384 : 92 : rtx rotate_rtx = gen_rtx_ROTATE (mode, reg, CONST1_RTX (mode));
9385 : : /* Test explicitly the case where ASHIFT (x, 1) is a PLUS (x, x). */
9386 : 92 : ASSERT_RTX_EQ (rotate_rtx,
9387 : : simplify_rtx (gen_rtx_IOR (mode, plus_rtx, lshiftrt_rtx)));
9388 : 92 : ASSERT_RTX_EQ (rotate_rtx,
9389 : : simplify_rtx (gen_rtx_XOR (mode, plus_rtx, lshiftrt_rtx)));
9390 : 92 : ASSERT_RTX_EQ (rotate_rtx,
9391 : : simplify_rtx (gen_rtx_PLUS (mode, plus_rtx, lshiftrt_rtx)));
9392 : :
9393 : : /* Don't go through every possible rotate amount to save execution time.
9394 : : Multiple of BITS_PER_UNIT amounts could conceivably be simplified to
9395 : : other bswap operations sometimes. Go through just the odd amounts. */
9396 : 1380 : for (unsigned i = 3; i < bitwidth - 2; i += 2)
9397 : : {
9398 : 1288 : rtx rot_amnt = gen_const_vec_duplicate (mode, GEN_INT (i));
9399 : 1288 : rtx ashift_rtx = gen_rtx_ASHIFT (mode, reg, rot_amnt);
9400 : 1288 : lshftrt_amnt = gen_const_vec_duplicate (mode, GEN_INT (bitwidth - i));
9401 : 1288 : lshiftrt_rtx = gen_rtx_LSHIFTRT (mode, reg, lshftrt_amnt);
9402 : 1288 : rotate_rtx = gen_rtx_ROTATE (mode, reg, rot_amnt);
9403 : 1288 : ASSERT_RTX_EQ (rotate_rtx,
9404 : : simplify_rtx (gen_rtx_IOR (mode, ashift_rtx, lshiftrt_rtx)));
9405 : 1288 : ASSERT_RTX_EQ (rotate_rtx,
9406 : : simplify_rtx (gen_rtx_XOR (mode, ashift_rtx, lshiftrt_rtx)));
9407 : 1288 : ASSERT_RTX_EQ (rotate_rtx,
9408 : : simplify_rtx (gen_rtx_PLUS (mode, ashift_rtx, lshiftrt_rtx)));
9409 : : }
9410 : 92 : }
9411 : :
9412 : : /* Test subregs of integer vector constant X, trying elements in
9413 : : the range [ELT_BIAS, ELT_BIAS + constant_lower_bound (NELTS)),
9414 : : where NELTS is the number of elements in X. Subregs involving
9415 : : elements [ELT_BIAS, ELT_BIAS + FIRST_VALID) are expected to fail. */
9416 : :
9417 : : static void
9418 : 276 : test_vector_subregs_modes (rtx x, poly_uint64 elt_bias = 0,
9419 : : unsigned int first_valid = 0)
9420 : : {
9421 : 276 : machine_mode inner_mode = GET_MODE (x);
9422 : 276 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9423 : :
9424 : 34500 : for (unsigned int modei = 0; modei < NUM_MACHINE_MODES; ++modei)
9425 : : {
9426 : 34224 : machine_mode outer_mode = (machine_mode) modei;
9427 : 34224 : if (!VECTOR_MODE_P (outer_mode))
9428 : 18768 : continue;
9429 : :
9430 : 15456 : unsigned int outer_nunits;
9431 : 15456 : if (GET_MODE_INNER (outer_mode) == int_mode
9432 : 1932 : && GET_MODE_NUNITS (outer_mode).is_constant (&outer_nunits)
9433 : 20412 : && multiple_p (GET_MODE_NUNITS (inner_mode), outer_nunits))
9434 : : {
9435 : : /* Test subregs in which the outer mode is a smaller,
9436 : : constant-sized vector of the same element type. */
9437 : 1092 : unsigned int limit
9438 : 1092 : = constant_lower_bound (GET_MODE_NUNITS (inner_mode));
9439 : 8028 : for (unsigned int elt = 0; elt < limit; elt += outer_nunits)
9440 : : {
9441 : 6936 : rtx expected = NULL_RTX;
9442 : 6936 : if (elt >= first_valid)
9443 : : {
9444 : 6936 : rtx_vector_builder builder (outer_mode, outer_nunits, 1);
9445 : 39768 : for (unsigned int i = 0; i < outer_nunits; ++i)
9446 : 32832 : builder.quick_push (CONST_VECTOR_ELT (x, elt + i));
9447 : 6936 : expected = builder.build ();
9448 : 6936 : }
9449 : 13872 : poly_uint64 byte = (elt_bias + elt) * GET_MODE_SIZE (int_mode);
9450 : 6936 : ASSERT_RTX_EQ (expected,
9451 : : simplify_subreg (outer_mode, x,
9452 : : inner_mode, byte));
9453 : : }
9454 : : }
9455 : 28728 : else if (known_eq (GET_MODE_SIZE (outer_mode),
9456 : : GET_MODE_SIZE (inner_mode))
9457 : 2040 : && known_eq (elt_bias, 0U)
9458 : 2040 : && (GET_MODE_CLASS (outer_mode) != MODE_VECTOR_BOOL
9459 : 0 : || known_eq (GET_MODE_BITSIZE (outer_mode),
9460 : : GET_MODE_NUNITS (outer_mode)))
9461 : 2040 : && (!FLOAT_MODE_P (outer_mode)
9462 : 15876 : || (FLOAT_MODE_FORMAT (outer_mode)->ieee_bits
9463 : 1104 : == GET_MODE_UNIT_PRECISION (outer_mode)))
9464 : 14364 : && (GET_MODE_SIZE (inner_mode).is_constant ()
9465 : : || !CONST_VECTOR_STEPPED_P (x)))
9466 : : {
9467 : : /* Try converting to OUTER_MODE and back. */
9468 : 1800 : rtx outer_x = simplify_subreg (outer_mode, x, inner_mode, 0);
9469 : 1800 : ASSERT_TRUE (outer_x != NULL_RTX);
9470 : 1800 : ASSERT_RTX_EQ (x, simplify_subreg (inner_mode, outer_x,
9471 : : outer_mode, 0));
9472 : : }
9473 : : }
9474 : :
9475 : 276 : if (BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
9476 : : {
9477 : : /* Test each byte in the element range. */
9478 : 276 : unsigned int limit
9479 : 276 : = constant_lower_bound (GET_MODE_SIZE (inner_mode));
9480 : 14604 : for (unsigned int i = 0; i < limit; ++i)
9481 : : {
9482 : 14328 : unsigned int elt = i / GET_MODE_SIZE (int_mode);
9483 : 14328 : rtx expected = NULL_RTX;
9484 : 14328 : if (elt >= first_valid)
9485 : : {
9486 : 14328 : unsigned int byte_shift = i % GET_MODE_SIZE (int_mode);
9487 : 14328 : if (BYTES_BIG_ENDIAN)
9488 : : byte_shift = GET_MODE_SIZE (int_mode) - byte_shift - 1;
9489 : 14328 : rtx_mode_t vec_elt (CONST_VECTOR_ELT (x, elt), int_mode);
9490 : 14328 : wide_int shifted_elt
9491 : 14328 : = wi::lrshift (vec_elt, byte_shift * BITS_PER_UNIT);
9492 : 14328 : expected = immed_wide_int_const (shifted_elt, QImode);
9493 : 14328 : }
9494 : 28656 : poly_uint64 byte = elt_bias * GET_MODE_SIZE (int_mode) + i;
9495 : 14328 : ASSERT_RTX_EQ (expected,
9496 : : simplify_subreg (QImode, x, inner_mode, byte));
9497 : : }
9498 : : }
9499 : 276 : }
9500 : :
9501 : : /* Test constant subregs of integer vector mode INNER_MODE, using 1
9502 : : element per pattern. */
9503 : :
9504 : : static void
9505 : 92 : test_vector_subregs_repeating (machine_mode inner_mode)
9506 : : {
9507 : 184 : poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
9508 : 92 : unsigned int min_nunits = constant_lower_bound (nunits);
9509 : 92 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9510 : 92 : unsigned int count = gcd (min_nunits, 8);
9511 : :
9512 : 92 : rtx_vector_builder builder (inner_mode, count, 1);
9513 : 684 : for (unsigned int i = 0; i < count; ++i)
9514 : 592 : builder.quick_push (gen_int_mode (8 - i, int_mode));
9515 : 92 : rtx x = builder.build ();
9516 : :
9517 : 92 : test_vector_subregs_modes (x);
9518 : 92 : if (!nunits.is_constant ())
9519 : : test_vector_subregs_modes (x, nunits - min_nunits);
9520 : 92 : }
9521 : :
9522 : : /* Test constant subregs of integer vector mode INNER_MODE, using 2
9523 : : elements per pattern. */
9524 : :
9525 : : static void
9526 : 92 : test_vector_subregs_fore_back (machine_mode inner_mode)
9527 : : {
9528 : 184 : poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
9529 : 92 : unsigned int min_nunits = constant_lower_bound (nunits);
9530 : 92 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9531 : 92 : unsigned int count = gcd (min_nunits, 4);
9532 : :
9533 : 92 : rtx_vector_builder builder (inner_mode, count, 2);
9534 : 444 : for (unsigned int i = 0; i < count; ++i)
9535 : 352 : builder.quick_push (gen_int_mode (i, int_mode));
9536 : 444 : for (unsigned int i = 0; i < count; ++i)
9537 : 352 : builder.quick_push (gen_int_mode (-1 - (int) i, int_mode));
9538 : 92 : rtx x = builder.build ();
9539 : :
9540 : 92 : test_vector_subregs_modes (x);
9541 : 92 : if (!nunits.is_constant ())
9542 : : test_vector_subregs_modes (x, nunits - min_nunits, count);
9543 : 92 : }
9544 : :
9545 : : /* Test constant subregs of integer vector mode INNER_MODE, using 3
9546 : : elements per pattern. */
9547 : :
9548 : : static void
9549 : 92 : test_vector_subregs_stepped (machine_mode inner_mode)
9550 : : {
9551 : : /* Build { 0, 1, 2, 3, ... }. */
9552 : 92 : scalar_mode int_mode = GET_MODE_INNER (inner_mode);
9553 : 92 : rtx_vector_builder builder (inner_mode, 1, 3);
9554 : 368 : for (unsigned int i = 0; i < 3; ++i)
9555 : 276 : builder.quick_push (gen_int_mode (i, int_mode));
9556 : 92 : rtx x = builder.build ();
9557 : :
9558 : 92 : test_vector_subregs_modes (x);
9559 : 92 : }
9560 : :
9561 : : /* Test constant subregs of integer vector mode INNER_MODE. */
9562 : :
9563 : : static void
9564 : 92 : test_vector_subregs (machine_mode inner_mode)
9565 : : {
9566 : 92 : test_vector_subregs_repeating (inner_mode);
9567 : 92 : test_vector_subregs_fore_back (inner_mode);
9568 : 92 : test_vector_subregs_stepped (inner_mode);
9569 : 92 : }
9570 : :
9571 : : /* Verify some simplifications involving vectors. */
9572 : :
9573 : : static void
9574 : 4 : test_vector_ops ()
9575 : : {
9576 : 500 : for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
9577 : : {
9578 : 496 : machine_mode mode = (machine_mode) i;
9579 : 496 : if (VECTOR_MODE_P (mode))
9580 : : {
9581 : 448 : rtx scalar_reg = make_test_reg (GET_MODE_INNER (mode));
9582 : 224 : test_vector_ops_duplicate (mode, scalar_reg);
9583 : 224 : rtx vector_reg = make_test_reg (mode);
9584 : 224 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
9585 : 348 : && maybe_gt (GET_MODE_NUNITS (mode), 2))
9586 : : {
9587 : 92 : test_vector_ops_series (mode, scalar_reg);
9588 : 92 : test_vector_subregs (mode);
9589 : 92 : test_vector_rotate (vector_reg);
9590 : : }
9591 : 224 : test_vec_merge (mode);
9592 : : }
9593 : : }
9594 : 4 : }
9595 : :
9596 : : template<unsigned int N>
9597 : : struct simplify_const_poly_int_tests
9598 : : {
9599 : : static void run ();
9600 : : };
9601 : :
9602 : : template<>
9603 : : struct simplify_const_poly_int_tests<1>
9604 : : {
9605 : : static void run () {}
9606 : : };
9607 : :
9608 : : /* Test various CONST_POLY_INT properties. */
9609 : :
9610 : : template<unsigned int N>
9611 : : void
9612 : : simplify_const_poly_int_tests<N>::run ()
9613 : : {
9614 : : using poly_int64 = poly_int<N, HOST_WIDE_INT>;
9615 : : rtx x1 = gen_int_mode (poly_int64 (1, 1), QImode);
9616 : : rtx x2 = gen_int_mode (poly_int64 (-80, 127), QImode);
9617 : : rtx x3 = gen_int_mode (poly_int64 (-79, -128), QImode);
9618 : : rtx x4 = gen_int_mode (poly_int64 (5, 4), QImode);
9619 : : rtx x5 = gen_int_mode (poly_int64 (30, 24), QImode);
9620 : : rtx x6 = gen_int_mode (poly_int64 (20, 16), QImode);
9621 : : rtx x7 = gen_int_mode (poly_int64 (7, 4), QImode);
9622 : : rtx x8 = gen_int_mode (poly_int64 (30, 24), HImode);
9623 : : rtx x9 = gen_int_mode (poly_int64 (-30, -24), HImode);
9624 : : rtx x10 = gen_int_mode (poly_int64 (-31, -24), HImode);
9625 : : rtx two = GEN_INT (2);
9626 : : rtx six = GEN_INT (6);
9627 : : poly_uint64 offset = subreg_lowpart_offset (QImode, HImode);
9628 : :
9629 : : /* These tests only try limited operation combinations. Fuller arithmetic
9630 : : testing is done directly on poly_ints. */
9631 : : ASSERT_EQ (simplify_unary_operation (NEG, HImode, x8, HImode), x9);
9632 : : ASSERT_EQ (simplify_unary_operation (NOT, HImode, x8, HImode), x10);
9633 : : ASSERT_EQ (simplify_unary_operation (TRUNCATE, QImode, x8, HImode), x5);
9634 : : ASSERT_EQ (simplify_binary_operation (PLUS, QImode, x1, x2), x3);
9635 : : ASSERT_EQ (simplify_binary_operation (MINUS, QImode, x3, x1), x2);
9636 : : ASSERT_EQ (simplify_binary_operation (MULT, QImode, x4, six), x5);
9637 : : ASSERT_EQ (simplify_binary_operation (MULT, QImode, six, x4), x5);
9638 : : ASSERT_EQ (simplify_binary_operation (ASHIFT, QImode, x4, two), x6);
9639 : : ASSERT_EQ (simplify_binary_operation (IOR, QImode, x4, two), x7);
9640 : : ASSERT_EQ (simplify_subreg (HImode, x5, QImode, 0), x8);
9641 : : ASSERT_EQ (simplify_subreg (QImode, x8, HImode, offset), x5);
9642 : : }
9643 : :
9644 : : /* Run all of the selftests within this file. */
9645 : :
9646 : : void
9647 : 4 : simplify_rtx_cc_tests ()
9648 : : {
9649 : 4 : test_scalar_ops ();
9650 : 4 : test_vector_ops ();
9651 : 4 : simplify_const_poly_int_tests<NUM_POLY_INT_COEFFS>::run ();
9652 : 4 : }
9653 : :
9654 : : } // namespace selftest
9655 : :
9656 : : #endif /* CHECKING_P */
|