1 /* RTL simplification functions for GNU compiler.
2 Copyright (C) 1987-2020 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
40 /* Simplification and canonicalization of RTL. */
41
42 /* Much code operates on (low, high) pairs; the low value is an
43 unsigned wide int, the high value a signed wide int. We
44 occasionally need to sign extend from low to high as if low were a
45 signed wide int. */
46 #define HWI_SIGN_EXTEND(low) \
47 ((((HOST_WIDE_INT) low) < 0) ? HOST_WIDE_INT_M1 : HOST_WIDE_INT_0)
48
49 static bool plus_minus_operand_p (const_rtx);
50 static rtx simplify_plus_minus (enum rtx_code, machine_mode, rtx, rtx);
51 static rtx simplify_associative_operation (enum rtx_code, machine_mode,
52 rtx, rtx);
53 static rtx simplify_relational_operation_1 (enum rtx_code, machine_mode,
54 machine_mode, rtx, rtx);
55 static rtx simplify_unary_operation_1 (enum rtx_code, machine_mode, rtx);
56 static rtx simplify_binary_operation_1 (enum rtx_code, machine_mode,
57 rtx, rtx, rtx, rtx);
58
59 /* Negate I, which satisfies poly_int_rtx_p. MODE is the mode of I. */
60
61 static rtx
neg_poly_int_rtx(machine_mode mode,const_rtx i)62 neg_poly_int_rtx (machine_mode mode, const_rtx i)
63 {
64 return immed_wide_int_const (-wi::to_poly_wide (i, mode), mode);
65 }
66
67 /* Test whether expression, X, is an immediate constant that represents
68 the most significant bit of machine mode MODE. */
69
70 bool
mode_signbit_p(machine_mode mode,const_rtx x)71 mode_signbit_p (machine_mode mode, const_rtx x)
72 {
73 unsigned HOST_WIDE_INT val;
74 unsigned int width;
75 scalar_int_mode int_mode;
76
77 if (!is_int_mode (mode, &int_mode))
78 return false;
79
80 width = GET_MODE_PRECISION (int_mode);
81 if (width == 0)
82 return false;
83
84 if (width <= HOST_BITS_PER_WIDE_INT
85 && CONST_INT_P (x))
86 val = INTVAL (x);
87 #if TARGET_SUPPORTS_WIDE_INT
88 else if (CONST_WIDE_INT_P (x))
89 {
90 unsigned int i;
91 unsigned int elts = CONST_WIDE_INT_NUNITS (x);
92 if (elts != (width + HOST_BITS_PER_WIDE_INT - 1) / HOST_BITS_PER_WIDE_INT)
93 return false;
94 for (i = 0; i < elts - 1; i++)
95 if (CONST_WIDE_INT_ELT (x, i) != 0)
96 return false;
97 val = CONST_WIDE_INT_ELT (x, elts - 1);
98 width %= HOST_BITS_PER_WIDE_INT;
99 if (width == 0)
100 width = HOST_BITS_PER_WIDE_INT;
101 }
102 #else
103 else if (width <= HOST_BITS_PER_DOUBLE_INT
104 && CONST_DOUBLE_AS_INT_P (x)
105 && CONST_DOUBLE_LOW (x) == 0)
106 {
107 val = CONST_DOUBLE_HIGH (x);
108 width -= HOST_BITS_PER_WIDE_INT;
109 }
110 #endif
111 else
112 /* X is not an integer constant. */
113 return false;
114
115 if (width < HOST_BITS_PER_WIDE_INT)
116 val &= (HOST_WIDE_INT_1U << width) - 1;
117 return val == (HOST_WIDE_INT_1U << (width - 1));
118 }
119
120 /* Test whether VAL is equal to the most significant bit of mode MODE
121 (after masking with the mode mask of MODE). Returns false if the
122 precision of MODE is too large to handle. */
123
124 bool
val_signbit_p(machine_mode mode,unsigned HOST_WIDE_INT val)125 val_signbit_p (machine_mode mode, unsigned HOST_WIDE_INT val)
126 {
127 unsigned int width;
128 scalar_int_mode int_mode;
129
130 if (!is_int_mode (mode, &int_mode))
131 return false;
132
133 width = GET_MODE_PRECISION (int_mode);
134 if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
135 return false;
136
137 val &= GET_MODE_MASK (int_mode);
138 return val == (HOST_WIDE_INT_1U << (width - 1));
139 }
140
141 /* Test whether the most significant bit of mode MODE is set in VAL.
142 Returns false if the precision of MODE is too large to handle. */
143 bool
val_signbit_known_set_p(machine_mode mode,unsigned HOST_WIDE_INT val)144 val_signbit_known_set_p (machine_mode mode, unsigned HOST_WIDE_INT val)
145 {
146 unsigned int width;
147
148 scalar_int_mode int_mode;
149 if (!is_int_mode (mode, &int_mode))
150 return false;
151
152 width = GET_MODE_PRECISION (int_mode);
153 if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
154 return false;
155
156 val &= HOST_WIDE_INT_1U << (width - 1);
157 return val != 0;
158 }
159
160 /* Test whether the most significant bit of mode MODE is clear in VAL.
161 Returns false if the precision of MODE is too large to handle. */
162 bool
val_signbit_known_clear_p(machine_mode mode,unsigned HOST_WIDE_INT val)163 val_signbit_known_clear_p (machine_mode mode, unsigned HOST_WIDE_INT val)
164 {
165 unsigned int width;
166
167 scalar_int_mode int_mode;
168 if (!is_int_mode (mode, &int_mode))
169 return false;
170
171 width = GET_MODE_PRECISION (int_mode);
172 if (width == 0 || width > HOST_BITS_PER_WIDE_INT)
173 return false;
174
175 val &= HOST_WIDE_INT_1U << (width - 1);
176 return val == 0;
177 }
178
179 /* Make a binary operation by properly ordering the operands and
180 seeing if the expression folds. */
181
182 rtx
simplify_gen_binary(enum rtx_code code,machine_mode mode,rtx op0,rtx op1)183 simplify_gen_binary (enum rtx_code code, machine_mode mode, rtx op0,
184 rtx op1)
185 {
186 rtx tem;
187
188 /* If this simplifies, do it. */
189 tem = simplify_binary_operation (code, mode, op0, op1);
190 if (tem)
191 return tem;
192
193 /* Put complex operands first and constants second if commutative. */
194 if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
195 && swap_commutative_operands_p (op0, op1))
196 std::swap (op0, op1);
197
198 return gen_rtx_fmt_ee (code, mode, op0, op1);
199 }
200
201 /* If X is a MEM referencing the constant pool, return the real value.
202 Otherwise return X. */
203 rtx
avoid_constant_pool_reference(rtx x)204 avoid_constant_pool_reference (rtx x)
205 {
206 rtx c, tmp, addr;
207 machine_mode cmode;
208 poly_int64 offset = 0;
209
210 switch (GET_CODE (x))
211 {
212 case MEM:
213 break;
214
215 case FLOAT_EXTEND:
216 /* Handle float extensions of constant pool references. */
217 tmp = XEXP (x, 0);
218 c = avoid_constant_pool_reference (tmp);
219 if (c != tmp && CONST_DOUBLE_AS_FLOAT_P (c))
220 return const_double_from_real_value (*CONST_DOUBLE_REAL_VALUE (c),
221 GET_MODE (x));
222 return x;
223
224 default:
225 return x;
226 }
227
228 if (GET_MODE (x) == BLKmode)
229 return x;
230
231 addr = XEXP (x, 0);
232
233 /* Call target hook to avoid the effects of -fpic etc.... */
234 addr = targetm.delegitimize_address (addr);
235
236 /* Split the address into a base and integer offset. */
237 addr = strip_offset (addr, &offset);
238
239 if (GET_CODE (addr) == LO_SUM)
240 addr = XEXP (addr, 1);
241
242 /* If this is a constant pool reference, we can turn it into its
243 constant and hope that simplifications happen. */
244 if (GET_CODE (addr) == SYMBOL_REF
245 && CONSTANT_POOL_ADDRESS_P (addr))
246 {
247 c = get_pool_constant (addr);
248 cmode = get_pool_mode (addr);
249
250 /* If we're accessing the constant in a different mode than it was
251 originally stored, attempt to fix that up via subreg simplifications.
252 If that fails we have no choice but to return the original memory. */
253 if (known_eq (offset, 0) && cmode == GET_MODE (x))
254 return c;
255 else if (known_in_range_p (offset, 0, GET_MODE_SIZE (cmode)))
256 {
257 rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset);
258 if (tem && CONSTANT_P (tem))
259 return tem;
260 }
261 }
262
263 return x;
264 }
265
266 /* Simplify a MEM based on its attributes. This is the default
267 delegitimize_address target hook, and it's recommended that every
268 overrider call it. */
269
270 rtx
delegitimize_mem_from_attrs(rtx x)271 delegitimize_mem_from_attrs (rtx x)
272 {
273 /* MEMs without MEM_OFFSETs may have been offset, so we can't just
274 use their base addresses as equivalent. */
275 if (MEM_P (x)
276 && MEM_EXPR (x)
277 && MEM_OFFSET_KNOWN_P (x))
278 {
279 tree decl = MEM_EXPR (x);
280 machine_mode mode = GET_MODE (x);
281 poly_int64 offset = 0;
282
283 switch (TREE_CODE (decl))
284 {
285 default:
286 decl = NULL;
287 break;
288
289 case VAR_DECL:
290 break;
291
292 case ARRAY_REF:
293 case ARRAY_RANGE_REF:
294 case COMPONENT_REF:
295 case BIT_FIELD_REF:
296 case REALPART_EXPR:
297 case IMAGPART_EXPR:
298 case VIEW_CONVERT_EXPR:
299 {
300 poly_int64 bitsize, bitpos, bytepos, toffset_val = 0;
301 tree toffset;
302 int unsignedp, reversep, volatilep = 0;
303
304 decl
305 = get_inner_reference (decl, &bitsize, &bitpos, &toffset, &mode,
306 &unsignedp, &reversep, &volatilep);
307 if (maybe_ne (bitsize, GET_MODE_BITSIZE (mode))
308 || !multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
309 || (toffset && !poly_int_tree_p (toffset, &toffset_val)))
310 decl = NULL;
311 else
312 offset += bytepos + toffset_val;
313 break;
314 }
315 }
316
317 if (decl
318 && mode == GET_MODE (x)
319 && VAR_P (decl)
320 && (TREE_STATIC (decl)
321 || DECL_THREAD_LOCAL_P (decl))
322 && DECL_RTL_SET_P (decl)
323 && MEM_P (DECL_RTL (decl)))
324 {
325 rtx newx;
326
327 offset += MEM_OFFSET (x);
328
329 newx = DECL_RTL (decl);
330
331 if (MEM_P (newx))
332 {
333 rtx n = XEXP (newx, 0), o = XEXP (x, 0);
334 poly_int64 n_offset, o_offset;
335
336 /* Avoid creating a new MEM needlessly if we already had
337 the same address. We do if there's no OFFSET and the
338 old address X is identical to NEWX, or if X is of the
339 form (plus NEWX OFFSET), or the NEWX is of the form
340 (plus Y (const_int Z)) and X is that with the offset
341 added: (plus Y (const_int Z+OFFSET)). */
342 n = strip_offset (n, &n_offset);
343 o = strip_offset (o, &o_offset);
344 if (!(known_eq (o_offset, n_offset + offset)
345 && rtx_equal_p (o, n)))
346 x = adjust_address_nv (newx, mode, offset);
347 }
348 else if (GET_MODE (x) == GET_MODE (newx)
349 && known_eq (offset, 0))
350 x = newx;
351 }
352 }
353
354 return x;
355 }
356
357 /* Make a unary operation by first seeing if it folds and otherwise making
358 the specified operation. */
359
360 rtx
simplify_gen_unary(enum rtx_code code,machine_mode mode,rtx op,machine_mode op_mode)361 simplify_gen_unary (enum rtx_code code, machine_mode mode, rtx op,
362 machine_mode op_mode)
363 {
364 rtx tem;
365
366 /* If this simplifies, use it. */
367 if ((tem = simplify_unary_operation (code, mode, op, op_mode)) != 0)
368 return tem;
369
370 return gen_rtx_fmt_e (code, mode, op);
371 }
372
373 /* Likewise for ternary operations. */
374
375 rtx
simplify_gen_ternary(enum rtx_code code,machine_mode mode,machine_mode op0_mode,rtx op0,rtx op1,rtx op2)376 simplify_gen_ternary (enum rtx_code code, machine_mode mode,
377 machine_mode op0_mode, rtx op0, rtx op1, rtx op2)
378 {
379 rtx tem;
380
381 /* If this simplifies, use it. */
382 if ((tem = simplify_ternary_operation (code, mode, op0_mode,
383 op0, op1, op2)) != 0)
384 return tem;
385
386 return gen_rtx_fmt_eee (code, mode, op0, op1, op2);
387 }
388
389 /* Likewise, for relational operations.
390 CMP_MODE specifies mode comparison is done in. */
391
392 rtx
simplify_gen_relational(enum rtx_code code,machine_mode mode,machine_mode cmp_mode,rtx op0,rtx op1)393 simplify_gen_relational (enum rtx_code code, machine_mode mode,
394 machine_mode cmp_mode, rtx op0, rtx op1)
395 {
396 rtx tem;
397
398 if ((tem = simplify_relational_operation (code, mode, cmp_mode,
399 op0, op1)) != 0)
400 return tem;
401
402 return gen_rtx_fmt_ee (code, mode, op0, op1);
403 }
404
405 /* If FN is NULL, replace all occurrences of OLD_RTX in X with copy_rtx (DATA)
406 and simplify the result. If FN is non-NULL, call this callback on each
407 X, if it returns non-NULL, replace X with its return value and simplify the
408 result. */
409
410 rtx
simplify_replace_fn_rtx(rtx x,const_rtx old_rtx,rtx (* fn)(rtx,const_rtx,void *),void * data)411 simplify_replace_fn_rtx (rtx x, const_rtx old_rtx,
412 rtx (*fn) (rtx, const_rtx, void *), void *data)
413 {
414 enum rtx_code code = GET_CODE (x);
415 machine_mode mode = GET_MODE (x);
416 machine_mode op_mode;
417 const char *fmt;
418 rtx op0, op1, op2, newx, op;
419 rtvec vec, newvec;
420 int i, j;
421
422 if (__builtin_expect (fn != NULL, 0))
423 {
424 newx = fn (x, old_rtx, data);
425 if (newx)
426 return newx;
427 }
428 else if (rtx_equal_p (x, old_rtx))
429 return copy_rtx ((rtx) data);
430
431 switch (GET_RTX_CLASS (code))
432 {
433 case RTX_UNARY:
434 op0 = XEXP (x, 0);
435 op_mode = GET_MODE (op0);
436 op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
437 if (op0 == XEXP (x, 0))
438 return x;
439 return simplify_gen_unary (code, mode, op0, op_mode);
440
441 case RTX_BIN_ARITH:
442 case RTX_COMM_ARITH:
443 op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
444 op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
445 if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
446 return x;
447 return simplify_gen_binary (code, mode, op0, op1);
448
449 case RTX_COMPARE:
450 case RTX_COMM_COMPARE:
451 op0 = XEXP (x, 0);
452 op1 = XEXP (x, 1);
453 op_mode = GET_MODE (op0) != VOIDmode ? GET_MODE (op0) : GET_MODE (op1);
454 op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
455 op1 = simplify_replace_fn_rtx (op1, old_rtx, fn, data);
456 if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
457 return x;
458 return simplify_gen_relational (code, mode, op_mode, op0, op1);
459
460 case RTX_TERNARY:
461 case RTX_BITFIELD_OPS:
462 op0 = XEXP (x, 0);
463 op_mode = GET_MODE (op0);
464 op0 = simplify_replace_fn_rtx (op0, old_rtx, fn, data);
465 op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
466 op2 = simplify_replace_fn_rtx (XEXP (x, 2), old_rtx, fn, data);
467 if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1) && op2 == XEXP (x, 2))
468 return x;
469 if (op_mode == VOIDmode)
470 op_mode = GET_MODE (op0);
471 return simplify_gen_ternary (code, mode, op_mode, op0, op1, op2);
472
473 case RTX_EXTRA:
474 if (code == SUBREG)
475 {
476 op0 = simplify_replace_fn_rtx (SUBREG_REG (x), old_rtx, fn, data);
477 if (op0 == SUBREG_REG (x))
478 return x;
479 op0 = simplify_gen_subreg (GET_MODE (x), op0,
480 GET_MODE (SUBREG_REG (x)),
481 SUBREG_BYTE (x));
482 return op0 ? op0 : x;
483 }
484 break;
485
486 case RTX_OBJ:
487 if (code == MEM)
488 {
489 op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
490 if (op0 == XEXP (x, 0))
491 return x;
492 return replace_equiv_address_nv (x, op0);
493 }
494 else if (code == LO_SUM)
495 {
496 op0 = simplify_replace_fn_rtx (XEXP (x, 0), old_rtx, fn, data);
497 op1 = simplify_replace_fn_rtx (XEXP (x, 1), old_rtx, fn, data);
498
499 /* (lo_sum (high x) y) -> y where x and y have the same base. */
500 if (GET_CODE (op0) == HIGH)
501 {
502 rtx base0, base1, offset0, offset1;
503 split_const (XEXP (op0, 0), &base0, &offset0);
504 split_const (op1, &base1, &offset1);
505 if (rtx_equal_p (base0, base1))
506 return op1;
507 }
508
509 if (op0 == XEXP (x, 0) && op1 == XEXP (x, 1))
510 return x;
511 return gen_rtx_LO_SUM (mode, op0, op1);
512 }
513 break;
514
515 default:
516 break;
517 }
518
519 newx = x;
520 fmt = GET_RTX_FORMAT (code);
521 for (i = 0; fmt[i]; i++)
522 switch (fmt[i])
523 {
524 case 'E':
525 vec = XVEC (x, i);
526 newvec = XVEC (newx, i);
527 for (j = 0; j < GET_NUM_ELEM (vec); j++)
528 {
529 op = simplify_replace_fn_rtx (RTVEC_ELT (vec, j),
530 old_rtx, fn, data);
531 if (op != RTVEC_ELT (vec, j))
532 {
533 if (newvec == vec)
534 {
535 newvec = shallow_copy_rtvec (vec);
536 if (x == newx)
537 newx = shallow_copy_rtx (x);
538 XVEC (newx, i) = newvec;
539 }
540 RTVEC_ELT (newvec, j) = op;
541 }
542 }
543 break;
544
545 case 'e':
546 if (XEXP (x, i))
547 {
548 op = simplify_replace_fn_rtx (XEXP (x, i), old_rtx, fn, data);
549 if (op != XEXP (x, i))
550 {
551 if (x == newx)
552 newx = shallow_copy_rtx (x);
553 XEXP (newx, i) = op;
554 }
555 }
556 break;
557 }
558 return newx;
559 }
560
561 /* Replace all occurrences of OLD_RTX in X with NEW_RTX and try to simplify the
562 resulting RTX. Return a new RTX which is as simplified as possible. */
563
564 rtx
simplify_replace_rtx(rtx x,const_rtx old_rtx,rtx new_rtx)565 simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx)
566 {
567 return simplify_replace_fn_rtx (x, old_rtx, 0, new_rtx);
568 }
569
570 /* Try to simplify a MODE truncation of OP, which has OP_MODE.
571 Only handle cases where the truncated value is inherently an rvalue.
572
573 RTL provides two ways of truncating a value:
574
575 1. a lowpart subreg. This form is only a truncation when both
576 the outer and inner modes (here MODE and OP_MODE respectively)
577 are scalar integers, and only then when the subreg is used as
578 an rvalue.
579
580 It is only valid to form such truncating subregs if the
581 truncation requires no action by the target. The onus for
582 proving this is on the creator of the subreg -- e.g. the
583 caller to simplify_subreg or simplify_gen_subreg -- and typically
584 involves either TRULY_NOOP_TRUNCATION_MODES_P or truncated_to_mode.
585
586 2. a TRUNCATE. This form handles both scalar and compound integers.
587
588 The first form is preferred where valid. However, the TRUNCATE
589 handling in simplify_unary_operation turns the second form into the
590 first form when TRULY_NOOP_TRUNCATION_MODES_P or truncated_to_mode allow,
591 so it is generally safe to form rvalue truncations using:
592
593 simplify_gen_unary (TRUNCATE, ...)
594
595 and leave simplify_unary_operation to work out which representation
596 should be used.
597
598 Because of the proof requirements on (1), simplify_truncation must
599 also use simplify_gen_unary (TRUNCATE, ...) to truncate parts of OP,
600 regardless of whether the outer truncation came from a SUBREG or a
601 TRUNCATE. For example, if the caller has proven that an SImode
602 truncation of:
603
604 (and:DI X Y)
605
606 is a no-op and can be represented as a subreg, it does not follow
607 that SImode truncations of X and Y are also no-ops. On a target
608 like 64-bit MIPS that requires SImode values to be stored in
609 sign-extended form, an SImode truncation of:
610
611 (and:DI (reg:DI X) (const_int 63))
612
613 is trivially a no-op because only the lower 6 bits can be set.
614 However, X is still an arbitrary 64-bit number and so we cannot
615 assume that truncating it too is a no-op. */
616
617 static rtx
simplify_truncation(machine_mode mode,rtx op,machine_mode op_mode)618 simplify_truncation (machine_mode mode, rtx op,
619 machine_mode op_mode)
620 {
621 unsigned int precision = GET_MODE_UNIT_PRECISION (mode);
622 unsigned int op_precision = GET_MODE_UNIT_PRECISION (op_mode);
623 scalar_int_mode int_mode, int_op_mode, subreg_mode;
624
625 gcc_assert (precision <= op_precision);
626
627 /* Optimize truncations of zero and sign extended values. */
628 if (GET_CODE (op) == ZERO_EXTEND
629 || GET_CODE (op) == SIGN_EXTEND)
630 {
631 /* There are three possibilities. If MODE is the same as the
632 origmode, we can omit both the extension and the subreg.
633 If MODE is not larger than the origmode, we can apply the
634 truncation without the extension. Finally, if the outermode
635 is larger than the origmode, we can just extend to the appropriate
636 mode. */
637 machine_mode origmode = GET_MODE (XEXP (op, 0));
638 if (mode == origmode)
639 return XEXP (op, 0);
640 else if (precision <= GET_MODE_UNIT_PRECISION (origmode))
641 return simplify_gen_unary (TRUNCATE, mode,
642 XEXP (op, 0), origmode);
643 else
644 return simplify_gen_unary (GET_CODE (op), mode,
645 XEXP (op, 0), origmode);
646 }
647
648 /* If the machine can perform operations in the truncated mode, distribute
649 the truncation, i.e. simplify (truncate:QI (op:SI (x:SI) (y:SI))) into
650 (op:QI (truncate:QI (x:SI)) (truncate:QI (y:SI))). */
651 if (1
652 && (!WORD_REGISTER_OPERATIONS || precision >= BITS_PER_WORD)
653 && (GET_CODE (op) == PLUS
654 || GET_CODE (op) == MINUS
655 || GET_CODE (op) == MULT))
656 {
657 rtx op0 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0), op_mode);
658 if (op0)
659 {
660 rtx op1 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 1), op_mode);
661 if (op1)
662 return simplify_gen_binary (GET_CODE (op), mode, op0, op1);
663 }
664 }
665
666 /* Simplify (truncate:QI (lshiftrt:SI (sign_extend:SI (x:QI)) C)) into
667 to (ashiftrt:QI (x:QI) C), where C is a suitable small constant and
668 the outer subreg is effectively a truncation to the original mode. */
669 if ((GET_CODE (op) == LSHIFTRT
670 || GET_CODE (op) == ASHIFTRT)
671 /* Ensure that OP_MODE is at least twice as wide as MODE
672 to avoid the possibility that an outer LSHIFTRT shifts by more
673 than the sign extension's sign_bit_copies and introduces zeros
674 into the high bits of the result. */
675 && 2 * precision <= op_precision
676 && CONST_INT_P (XEXP (op, 1))
677 && GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
678 && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
679 && UINTVAL (XEXP (op, 1)) < precision)
680 return simplify_gen_binary (ASHIFTRT, mode,
681 XEXP (XEXP (op, 0), 0), XEXP (op, 1));
682
683 /* Likewise (truncate:QI (lshiftrt:SI (zero_extend:SI (x:QI)) C)) into
684 to (lshiftrt:QI (x:QI) C), where C is a suitable small constant and
685 the outer subreg is effectively a truncation to the original mode. */
686 if ((GET_CODE (op) == LSHIFTRT
687 || GET_CODE (op) == ASHIFTRT)
688 && CONST_INT_P (XEXP (op, 1))
689 && GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
690 && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
691 && UINTVAL (XEXP (op, 1)) < precision)
692 return simplify_gen_binary (LSHIFTRT, mode,
693 XEXP (XEXP (op, 0), 0), XEXP (op, 1));
694
695 /* Likewise (truncate:QI (ashift:SI (zero_extend:SI (x:QI)) C)) into
696 to (ashift:QI (x:QI) C), where C is a suitable small constant and
697 the outer subreg is effectively a truncation to the original mode. */
698 if (GET_CODE (op) == ASHIFT
699 && CONST_INT_P (XEXP (op, 1))
700 && (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
701 || GET_CODE (XEXP (op, 0)) == SIGN_EXTEND)
702 && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
703 && UINTVAL (XEXP (op, 1)) < precision)
704 return simplify_gen_binary (ASHIFT, mode,
705 XEXP (XEXP (op, 0), 0), XEXP (op, 1));
706
707 /* Likewise (truncate:QI (and:SI (lshiftrt:SI (x:SI) C) C2)) into
708 (and:QI (lshiftrt:QI (truncate:QI (x:SI)) C) C2) for suitable C
709 and C2. */
710 if (GET_CODE (op) == AND
711 && (GET_CODE (XEXP (op, 0)) == LSHIFTRT
712 || GET_CODE (XEXP (op, 0)) == ASHIFTRT)
713 && CONST_INT_P (XEXP (XEXP (op, 0), 1))
714 && CONST_INT_P (XEXP (op, 1)))
715 {
716 rtx op0 = (XEXP (XEXP (op, 0), 0));
717 rtx shift_op = XEXP (XEXP (op, 0), 1);
718 rtx mask_op = XEXP (op, 1);
719 unsigned HOST_WIDE_INT shift = UINTVAL (shift_op);
720 unsigned HOST_WIDE_INT mask = UINTVAL (mask_op);
721
722 if (shift < precision
723 /* If doing this transform works for an X with all bits set,
724 it works for any X. */
725 && ((GET_MODE_MASK (mode) >> shift) & mask)
726 == ((GET_MODE_MASK (op_mode) >> shift) & mask)
727 && (op0 = simplify_gen_unary (TRUNCATE, mode, op0, op_mode))
728 && (op0 = simplify_gen_binary (LSHIFTRT, mode, op0, shift_op)))
729 {
730 mask_op = GEN_INT (trunc_int_for_mode (mask, mode));
731 return simplify_gen_binary (AND, mode, op0, mask_op);
732 }
733 }
734
735 /* Turn (truncate:M1 (*_extract:M2 (reg:M2) (len) (pos))) into
736 (*_extract:M1 (truncate:M1 (reg:M2)) (len) (pos')) if possible without
737 changing len. */
738 if ((GET_CODE (op) == ZERO_EXTRACT || GET_CODE (op) == SIGN_EXTRACT)
739 && REG_P (XEXP (op, 0))
740 && GET_MODE (XEXP (op, 0)) == GET_MODE (op)
741 && CONST_INT_P (XEXP (op, 1))
742 && CONST_INT_P (XEXP (op, 2)))
743 {
744 rtx op0 = XEXP (op, 0);
745 unsigned HOST_WIDE_INT len = UINTVAL (XEXP (op, 1));
746 unsigned HOST_WIDE_INT pos = UINTVAL (XEXP (op, 2));
747 if (BITS_BIG_ENDIAN && pos >= op_precision - precision)
748 {
749 op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
750 if (op0)
751 {
752 pos -= op_precision - precision;
753 return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
754 XEXP (op, 1), GEN_INT (pos));
755 }
756 }
757 else if (!BITS_BIG_ENDIAN && precision >= len + pos)
758 {
759 op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
760 if (op0)
761 return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
762 XEXP (op, 1), XEXP (op, 2));
763 }
764 }
765
766 /* Recognize a word extraction from a multi-word subreg. */
767 if ((GET_CODE (op) == LSHIFTRT
768 || GET_CODE (op) == ASHIFTRT)
769 && SCALAR_INT_MODE_P (mode)
770 && SCALAR_INT_MODE_P (op_mode)
771 && precision >= BITS_PER_WORD
772 && 2 * precision <= op_precision
773 && CONST_INT_P (XEXP (op, 1))
774 && (INTVAL (XEXP (op, 1)) & (precision - 1)) == 0
775 && UINTVAL (XEXP (op, 1)) < op_precision)
776 {
777 poly_int64 byte = subreg_lowpart_offset (mode, op_mode);
778 int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
779 return simplify_gen_subreg (mode, XEXP (op, 0), op_mode,
780 (WORDS_BIG_ENDIAN
781 ? byte - shifted_bytes
782 : byte + shifted_bytes));
783 }
784
785 /* If we have a TRUNCATE of a right shift of MEM, make a new MEM
786 and try replacing the TRUNCATE and shift with it. Don't do this
787 if the MEM has a mode-dependent address. */
788 if ((GET_CODE (op) == LSHIFTRT
789 || GET_CODE (op) == ASHIFTRT)
790 && is_a <scalar_int_mode> (mode, &int_mode)
791 && is_a <scalar_int_mode> (op_mode, &int_op_mode)
792 && MEM_P (XEXP (op, 0))
793 && CONST_INT_P (XEXP (op, 1))
794 && INTVAL (XEXP (op, 1)) % GET_MODE_BITSIZE (int_mode) == 0
795 && INTVAL (XEXP (op, 1)) > 0
796 && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (int_op_mode)
797 && ! mode_dependent_address_p (XEXP (XEXP (op, 0), 0),
798 MEM_ADDR_SPACE (XEXP (op, 0)))
799 && ! MEM_VOLATILE_P (XEXP (op, 0))
800 && (GET_MODE_SIZE (int_mode) >= UNITS_PER_WORD
801 || WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN))
802 {
803 poly_int64 byte = subreg_lowpart_offset (int_mode, int_op_mode);
804 int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
805 return adjust_address_nv (XEXP (op, 0), int_mode,
806 (WORDS_BIG_ENDIAN
807 ? byte - shifted_bytes
808 : byte + shifted_bytes));
809 }
810
811 /* (truncate:SI (OP:DI ({sign,zero}_extend:DI foo:SI))) is
812 (OP:SI foo:SI) if OP is NEG or ABS. */
813 if ((GET_CODE (op) == ABS
814 || GET_CODE (op) == NEG)
815 && (GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
816 || GET_CODE (XEXP (op, 0)) == ZERO_EXTEND)
817 && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
818 return simplify_gen_unary (GET_CODE (op), mode,
819 XEXP (XEXP (op, 0), 0), mode);
820
821 /* (truncate:A (subreg:B (truncate:C X) 0)) is
822 (truncate:A X). */
823 if (GET_CODE (op) == SUBREG
824 && is_a <scalar_int_mode> (mode, &int_mode)
825 && SCALAR_INT_MODE_P (op_mode)
826 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &subreg_mode)
827 && GET_CODE (SUBREG_REG (op)) == TRUNCATE
828 && subreg_lowpart_p (op))
829 {
830 rtx inner = XEXP (SUBREG_REG (op), 0);
831 if (GET_MODE_PRECISION (int_mode) <= GET_MODE_PRECISION (subreg_mode))
832 return simplify_gen_unary (TRUNCATE, int_mode, inner,
833 GET_MODE (inner));
834 else
835 /* If subreg above is paradoxical and C is narrower
836 than A, return (subreg:A (truncate:C X) 0). */
837 return simplify_gen_subreg (int_mode, SUBREG_REG (op), subreg_mode, 0);
838 }
839
840 /* (truncate:A (truncate:B X)) is (truncate:A X). */
841 if (GET_CODE (op) == TRUNCATE)
842 return simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0),
843 GET_MODE (XEXP (op, 0)));
844
845 /* (truncate:A (ior X C)) is (const_int -1) if C is equal to that already,
846 in mode A. */
847 if (GET_CODE (op) == IOR
848 && SCALAR_INT_MODE_P (mode)
849 && SCALAR_INT_MODE_P (op_mode)
850 && CONST_INT_P (XEXP (op, 1))
851 && trunc_int_for_mode (INTVAL (XEXP (op, 1)), mode) == -1)
852 return constm1_rtx;
853
854 return NULL_RTX;
855 }
856
857 /* Try to simplify a unary operation CODE whose output mode is to be
858 MODE with input operand OP whose mode was originally OP_MODE.
859 Return zero if no simplification can be made. */
860 rtx
simplify_unary_operation(enum rtx_code code,machine_mode mode,rtx op,machine_mode op_mode)861 simplify_unary_operation (enum rtx_code code, machine_mode mode,
862 rtx op, machine_mode op_mode)
863 {
864 rtx trueop, tem;
865
866 trueop = avoid_constant_pool_reference (op);
867
868 tem = simplify_const_unary_operation (code, mode, trueop, op_mode);
869 if (tem)
870 return tem;
871
872 return simplify_unary_operation_1 (code, mode, op);
873 }
874
875 /* Return true if FLOAT or UNSIGNED_FLOAT operation OP is known
876 to be exact. */
877
878 static bool
exact_int_to_float_conversion_p(const_rtx op)879 exact_int_to_float_conversion_p (const_rtx op)
880 {
881 int out_bits = significand_size (GET_MODE_INNER (GET_MODE (op)));
882 machine_mode op0_mode = GET_MODE (XEXP (op, 0));
883 /* Constants shouldn't reach here. */
884 gcc_assert (op0_mode != VOIDmode);
885 int in_prec = GET_MODE_UNIT_PRECISION (op0_mode);
886 int in_bits = in_prec;
887 if (HWI_COMPUTABLE_MODE_P (op0_mode))
888 {
889 unsigned HOST_WIDE_INT nonzero = nonzero_bits (XEXP (op, 0), op0_mode);
890 if (GET_CODE (op) == FLOAT)
891 in_bits -= num_sign_bit_copies (XEXP (op, 0), op0_mode);
892 else if (GET_CODE (op) == UNSIGNED_FLOAT)
893 in_bits = wi::min_precision (wi::uhwi (nonzero, in_prec), UNSIGNED);
894 else
895 gcc_unreachable ();
896 in_bits -= wi::ctz (wi::uhwi (nonzero, in_prec));
897 }
898 return in_bits <= out_bits;
899 }
900
901 /* Perform some simplifications we can do even if the operands
902 aren't constant. */
903 static rtx
simplify_unary_operation_1(enum rtx_code code,machine_mode mode,rtx op)904 simplify_unary_operation_1 (enum rtx_code code, machine_mode mode, rtx op)
905 {
906 enum rtx_code reversed;
907 rtx temp, elt, base, step;
908 scalar_int_mode inner, int_mode, op_mode, op0_mode;
909
910 switch (code)
911 {
912 case NOT:
913 /* (not (not X)) == X. */
914 if (GET_CODE (op) == NOT)
915 return XEXP (op, 0);
916
917 /* (not (eq X Y)) == (ne X Y), etc. if BImode or the result of the
918 comparison is all ones. */
919 if (COMPARISON_P (op)
920 && (mode == BImode || STORE_FLAG_VALUE == -1)
921 && ((reversed = reversed_comparison_code (op, NULL)) != UNKNOWN))
922 return simplify_gen_relational (reversed, mode, VOIDmode,
923 XEXP (op, 0), XEXP (op, 1));
924
925 /* (not (plus X -1)) can become (neg X). */
926 if (GET_CODE (op) == PLUS
927 && XEXP (op, 1) == constm1_rtx)
928 return simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
929
930 /* Similarly, (not (neg X)) is (plus X -1). Only do this for
931 modes that have CONSTM1_RTX, i.e. MODE_INT, MODE_PARTIAL_INT
932 and MODE_VECTOR_INT. */
933 if (GET_CODE (op) == NEG && CONSTM1_RTX (mode))
934 return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
935 CONSTM1_RTX (mode));
936
937 /* (not (xor X C)) for C constant is (xor X D) with D = ~C. */
938 if (GET_CODE (op) == XOR
939 && CONST_INT_P (XEXP (op, 1))
940 && (temp = simplify_unary_operation (NOT, mode,
941 XEXP (op, 1), mode)) != 0)
942 return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
943
944 /* (not (plus X C)) for signbit C is (xor X D) with D = ~C. */
945 if (GET_CODE (op) == PLUS
946 && CONST_INT_P (XEXP (op, 1))
947 && mode_signbit_p (mode, XEXP (op, 1))
948 && (temp = simplify_unary_operation (NOT, mode,
949 XEXP (op, 1), mode)) != 0)
950 return simplify_gen_binary (XOR, mode, XEXP (op, 0), temp);
951
952
953 /* (not (ashift 1 X)) is (rotate ~1 X). We used to do this for
954 operands other than 1, but that is not valid. We could do a
955 similar simplification for (not (lshiftrt C X)) where C is
956 just the sign bit, but this doesn't seem common enough to
957 bother with. */
958 if (GET_CODE (op) == ASHIFT
959 && XEXP (op, 0) == const1_rtx)
960 {
961 temp = simplify_gen_unary (NOT, mode, const1_rtx, mode);
962 return simplify_gen_binary (ROTATE, mode, temp, XEXP (op, 1));
963 }
964
965 /* (not (ashiftrt foo C)) where C is the number of bits in FOO
966 minus 1 is (ge foo (const_int 0)) if STORE_FLAG_VALUE is -1,
967 so we can perform the above simplification. */
968 if (STORE_FLAG_VALUE == -1
969 && is_a <scalar_int_mode> (mode, &int_mode)
970 && GET_CODE (op) == ASHIFTRT
971 && CONST_INT_P (XEXP (op, 1))
972 && INTVAL (XEXP (op, 1)) == GET_MODE_PRECISION (int_mode) - 1)
973 return simplify_gen_relational (GE, int_mode, VOIDmode,
974 XEXP (op, 0), const0_rtx);
975
976
977 if (partial_subreg_p (op)
978 && subreg_lowpart_p (op)
979 && GET_CODE (SUBREG_REG (op)) == ASHIFT
980 && XEXP (SUBREG_REG (op), 0) == const1_rtx)
981 {
982 machine_mode inner_mode = GET_MODE (SUBREG_REG (op));
983 rtx x;
984
985 x = gen_rtx_ROTATE (inner_mode,
986 simplify_gen_unary (NOT, inner_mode, const1_rtx,
987 inner_mode),
988 XEXP (SUBREG_REG (op), 1));
989 temp = rtl_hooks.gen_lowpart_no_emit (mode, x);
990 if (temp)
991 return temp;
992 }
993
994 /* Apply De Morgan's laws to reduce number of patterns for machines
995 with negating logical insns (and-not, nand, etc.). If result has
996 only one NOT, put it first, since that is how the patterns are
997 coded. */
998 if (GET_CODE (op) == IOR || GET_CODE (op) == AND)
999 {
1000 rtx in1 = XEXP (op, 0), in2 = XEXP (op, 1);
1001 machine_mode op_mode;
1002
1003 op_mode = GET_MODE (in1);
1004 in1 = simplify_gen_unary (NOT, op_mode, in1, op_mode);
1005
1006 op_mode = GET_MODE (in2);
1007 if (op_mode == VOIDmode)
1008 op_mode = mode;
1009 in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode);
1010
1011 if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT)
1012 std::swap (in1, in2);
1013
1014 return gen_rtx_fmt_ee (GET_CODE (op) == IOR ? AND : IOR,
1015 mode, in1, in2);
1016 }
1017
1018 /* (not (bswap x)) -> (bswap (not x)). */
1019 if (GET_CODE (op) == BSWAP)
1020 {
1021 rtx x = simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1022 return simplify_gen_unary (BSWAP, mode, x, mode);
1023 }
1024 break;
1025
1026 case NEG:
1027 /* (neg (neg X)) == X. */
1028 if (GET_CODE (op) == NEG)
1029 return XEXP (op, 0);
1030
1031 /* (neg (x ? (neg y) : y)) == !x ? (neg y) : y.
1032 If comparison is not reversible use
1033 x ? y : (neg y). */
1034 if (GET_CODE (op) == IF_THEN_ELSE)
1035 {
1036 rtx cond = XEXP (op, 0);
1037 rtx true_rtx = XEXP (op, 1);
1038 rtx false_rtx = XEXP (op, 2);
1039
1040 if ((GET_CODE (true_rtx) == NEG
1041 && rtx_equal_p (XEXP (true_rtx, 0), false_rtx))
1042 || (GET_CODE (false_rtx) == NEG
1043 && rtx_equal_p (XEXP (false_rtx, 0), true_rtx)))
1044 {
1045 if (reversed_comparison_code (cond, NULL) != UNKNOWN)
1046 temp = reversed_comparison (cond, mode);
1047 else
1048 {
1049 temp = cond;
1050 std::swap (true_rtx, false_rtx);
1051 }
1052 return simplify_gen_ternary (IF_THEN_ELSE, mode,
1053 mode, temp, true_rtx, false_rtx);
1054 }
1055 }
1056
1057 /* (neg (plus X 1)) can become (not X). */
1058 if (GET_CODE (op) == PLUS
1059 && XEXP (op, 1) == const1_rtx)
1060 return simplify_gen_unary (NOT, mode, XEXP (op, 0), mode);
1061
1062 /* Similarly, (neg (not X)) is (plus X 1). */
1063 if (GET_CODE (op) == NOT)
1064 return simplify_gen_binary (PLUS, mode, XEXP (op, 0),
1065 CONST1_RTX (mode));
1066
1067 /* (neg (minus X Y)) can become (minus Y X). This transformation
1068 isn't safe for modes with signed zeros, since if X and Y are
1069 both +0, (minus Y X) is the same as (minus X Y). If the
1070 rounding mode is towards +infinity (or -infinity) then the two
1071 expressions will be rounded differently. */
1072 if (GET_CODE (op) == MINUS
1073 && !HONOR_SIGNED_ZEROS (mode)
1074 && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1075 return simplify_gen_binary (MINUS, mode, XEXP (op, 1), XEXP (op, 0));
1076
1077 if (GET_CODE (op) == PLUS
1078 && !HONOR_SIGNED_ZEROS (mode)
1079 && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1080 {
1081 /* (neg (plus A C)) is simplified to (minus -C A). */
1082 if (CONST_SCALAR_INT_P (XEXP (op, 1))
1083 || CONST_DOUBLE_AS_FLOAT_P (XEXP (op, 1)))
1084 {
1085 temp = simplify_unary_operation (NEG, mode, XEXP (op, 1), mode);
1086 if (temp)
1087 return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 0));
1088 }
1089
1090 /* (neg (plus A B)) is canonicalized to (minus (neg A) B). */
1091 temp = simplify_gen_unary (NEG, mode, XEXP (op, 0), mode);
1092 return simplify_gen_binary (MINUS, mode, temp, XEXP (op, 1));
1093 }
1094
1095 /* (neg (mult A B)) becomes (mult A (neg B)).
1096 This works even for floating-point values. */
1097 if (GET_CODE (op) == MULT
1098 && !HONOR_SIGN_DEPENDENT_ROUNDING (mode))
1099 {
1100 temp = simplify_gen_unary (NEG, mode, XEXP (op, 1), mode);
1101 return simplify_gen_binary (MULT, mode, XEXP (op, 0), temp);
1102 }
1103
1104 /* NEG commutes with ASHIFT since it is multiplication. Only do
1105 this if we can then eliminate the NEG (e.g., if the operand
1106 is a constant). */
1107 if (GET_CODE (op) == ASHIFT)
1108 {
1109 temp = simplify_unary_operation (NEG, mode, XEXP (op, 0), mode);
1110 if (temp)
1111 return simplify_gen_binary (ASHIFT, mode, temp, XEXP (op, 1));
1112 }
1113
1114 /* (neg (ashiftrt X C)) can be replaced by (lshiftrt X C) when
1115 C is equal to the width of MODE minus 1. */
1116 if (GET_CODE (op) == ASHIFTRT
1117 && CONST_INT_P (XEXP (op, 1))
1118 && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1119 return simplify_gen_binary (LSHIFTRT, mode,
1120 XEXP (op, 0), XEXP (op, 1));
1121
1122 /* (neg (lshiftrt X C)) can be replaced by (ashiftrt X C) when
1123 C is equal to the width of MODE minus 1. */
1124 if (GET_CODE (op) == LSHIFTRT
1125 && CONST_INT_P (XEXP (op, 1))
1126 && INTVAL (XEXP (op, 1)) == GET_MODE_UNIT_PRECISION (mode) - 1)
1127 return simplify_gen_binary (ASHIFTRT, mode,
1128 XEXP (op, 0), XEXP (op, 1));
1129
1130 /* (neg (xor A 1)) is (plus A -1) if A is known to be either 0 or 1. */
1131 if (GET_CODE (op) == XOR
1132 && XEXP (op, 1) == const1_rtx
1133 && nonzero_bits (XEXP (op, 0), mode) == 1)
1134 return plus_constant (mode, XEXP (op, 0), -1);
1135
1136 /* (neg (lt x 0)) is (ashiftrt X C) if STORE_FLAG_VALUE is 1. */
1137 /* (neg (lt x 0)) is (lshiftrt X C) if STORE_FLAG_VALUE is -1. */
1138 if (GET_CODE (op) == LT
1139 && XEXP (op, 1) == const0_rtx
1140 && is_a <scalar_int_mode> (GET_MODE (XEXP (op, 0)), &inner))
1141 {
1142 int_mode = as_a <scalar_int_mode> (mode);
1143 int isize = GET_MODE_PRECISION (inner);
1144 if (STORE_FLAG_VALUE == 1)
1145 {
1146 temp = simplify_gen_binary (ASHIFTRT, inner, XEXP (op, 0),
1147 gen_int_shift_amount (inner,
1148 isize - 1));
1149 if (int_mode == inner)
1150 return temp;
1151 if (GET_MODE_PRECISION (int_mode) > isize)
1152 return simplify_gen_unary (SIGN_EXTEND, int_mode, temp, inner);
1153 return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1154 }
1155 else if (STORE_FLAG_VALUE == -1)
1156 {
1157 temp = simplify_gen_binary (LSHIFTRT, inner, XEXP (op, 0),
1158 gen_int_shift_amount (inner,
1159 isize - 1));
1160 if (int_mode == inner)
1161 return temp;
1162 if (GET_MODE_PRECISION (int_mode) > isize)
1163 return simplify_gen_unary (ZERO_EXTEND, int_mode, temp, inner);
1164 return simplify_gen_unary (TRUNCATE, int_mode, temp, inner);
1165 }
1166 }
1167
1168 if (vec_series_p (op, &base, &step))
1169 {
1170 /* Only create a new series if we can simplify both parts. In other
1171 cases this isn't really a simplification, and it's not necessarily
1172 a win to replace a vector operation with a scalar operation. */
1173 scalar_mode inner_mode = GET_MODE_INNER (mode);
1174 base = simplify_unary_operation (NEG, inner_mode, base, inner_mode);
1175 if (base)
1176 {
1177 step = simplify_unary_operation (NEG, inner_mode,
1178 step, inner_mode);
1179 if (step)
1180 return gen_vec_series (mode, base, step);
1181 }
1182 }
1183 break;
1184
1185 case TRUNCATE:
1186 /* Don't optimize (lshiftrt (mult ...)) as it would interfere
1187 with the umulXi3_highpart patterns. */
1188 if (GET_CODE (op) == LSHIFTRT
1189 && GET_CODE (XEXP (op, 0)) == MULT)
1190 break;
1191
1192 if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
1193 {
1194 if (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
1195 {
1196 temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1197 if (temp)
1198 return temp;
1199 }
1200 /* We can't handle truncation to a partial integer mode here
1201 because we don't know the real bitsize of the partial
1202 integer mode. */
1203 break;
1204 }
1205
1206 if (GET_MODE (op) != VOIDmode)
1207 {
1208 temp = simplify_truncation (mode, op, GET_MODE (op));
1209 if (temp)
1210 return temp;
1211 }
1212
1213 /* If we know that the value is already truncated, we can
1214 replace the TRUNCATE with a SUBREG. */
1215 if (known_eq (GET_MODE_NUNITS (mode), 1)
1216 && (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op))
1217 || truncated_to_mode (mode, op)))
1218 {
1219 temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1220 if (temp)
1221 return temp;
1222 }
1223
1224 /* A truncate of a comparison can be replaced with a subreg if
1225 STORE_FLAG_VALUE permits. This is like the previous test,
1226 but it works even if the comparison is done in a mode larger
1227 than HOST_BITS_PER_WIDE_INT. */
1228 if (HWI_COMPUTABLE_MODE_P (mode)
1229 && COMPARISON_P (op)
1230 && (STORE_FLAG_VALUE & ~GET_MODE_MASK (mode)) == 0)
1231 {
1232 temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1233 if (temp)
1234 return temp;
1235 }
1236
1237 /* A truncate of a memory is just loading the low part of the memory
1238 if we are not changing the meaning of the address. */
1239 if (GET_CODE (op) == MEM
1240 && !VECTOR_MODE_P (mode)
1241 && !MEM_VOLATILE_P (op)
1242 && !mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op)))
1243 {
1244 temp = rtl_hooks.gen_lowpart_no_emit (mode, op);
1245 if (temp)
1246 return temp;
1247 }
1248
1249 break;
1250
1251 case FLOAT_TRUNCATE:
1252 if (DECIMAL_FLOAT_MODE_P (mode))
1253 break;
1254
1255 /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF. */
1256 if (GET_CODE (op) == FLOAT_EXTEND
1257 && GET_MODE (XEXP (op, 0)) == mode)
1258 return XEXP (op, 0);
1259
1260 /* (float_truncate:SF (float_truncate:DF foo:XF))
1261 = (float_truncate:SF foo:XF).
1262 This may eliminate double rounding, so it is unsafe.
1263
1264 (float_truncate:SF (float_extend:XF foo:DF))
1265 = (float_truncate:SF foo:DF).
1266
1267 (float_truncate:DF (float_extend:XF foo:SF))
1268 = (float_extend:DF foo:SF). */
1269 if ((GET_CODE (op) == FLOAT_TRUNCATE
1270 && flag_unsafe_math_optimizations)
1271 || GET_CODE (op) == FLOAT_EXTEND)
1272 return simplify_gen_unary (GET_MODE_UNIT_SIZE (GET_MODE (XEXP (op, 0)))
1273 > GET_MODE_UNIT_SIZE (mode)
1274 ? FLOAT_TRUNCATE : FLOAT_EXTEND,
1275 mode,
1276 XEXP (op, 0), mode);
1277
1278 /* (float_truncate (float x)) is (float x) */
1279 if ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1280 && (flag_unsafe_math_optimizations
1281 || exact_int_to_float_conversion_p (op)))
1282 return simplify_gen_unary (GET_CODE (op), mode,
1283 XEXP (op, 0),
1284 GET_MODE (XEXP (op, 0)));
1285
1286 /* (float_truncate:SF (OP:DF (float_extend:DF foo:sf))) is
1287 (OP:SF foo:SF) if OP is NEG or ABS. */
1288 if ((GET_CODE (op) == ABS
1289 || GET_CODE (op) == NEG)
1290 && GET_CODE (XEXP (op, 0)) == FLOAT_EXTEND
1291 && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
1292 return simplify_gen_unary (GET_CODE (op), mode,
1293 XEXP (XEXP (op, 0), 0), mode);
1294
1295 /* (float_truncate:SF (subreg:DF (float_truncate:SF X) 0))
1296 is (float_truncate:SF x). */
1297 if (GET_CODE (op) == SUBREG
1298 && subreg_lowpart_p (op)
1299 && GET_CODE (SUBREG_REG (op)) == FLOAT_TRUNCATE)
1300 return SUBREG_REG (op);
1301 break;
1302
1303 case FLOAT_EXTEND:
1304 if (DECIMAL_FLOAT_MODE_P (mode))
1305 break;
1306
1307 /* (float_extend (float_extend x)) is (float_extend x)
1308
1309 (float_extend (float x)) is (float x) assuming that double
1310 rounding can't happen.
1311 */
1312 if (GET_CODE (op) == FLOAT_EXTEND
1313 || ((GET_CODE (op) == FLOAT || GET_CODE (op) == UNSIGNED_FLOAT)
1314 && exact_int_to_float_conversion_p (op)))
1315 return simplify_gen_unary (GET_CODE (op), mode,
1316 XEXP (op, 0),
1317 GET_MODE (XEXP (op, 0)));
1318
1319 break;
1320
1321 case ABS:
1322 /* (abs (neg <foo>)) -> (abs <foo>) */
1323 if (GET_CODE (op) == NEG)
1324 return simplify_gen_unary (ABS, mode, XEXP (op, 0),
1325 GET_MODE (XEXP (op, 0)));
1326
1327 /* If the mode of the operand is VOIDmode (i.e. if it is ASM_OPERANDS),
1328 do nothing. */
1329 if (GET_MODE (op) == VOIDmode)
1330 break;
1331
1332 /* If operand is something known to be positive, ignore the ABS. */
1333 if (GET_CODE (op) == FFS || GET_CODE (op) == ABS
1334 || val_signbit_known_clear_p (GET_MODE (op),
1335 nonzero_bits (op, GET_MODE (op))))
1336 return op;
1337
1338 /* If operand is known to be only -1 or 0, convert ABS to NEG. */
1339 if (is_a <scalar_int_mode> (mode, &int_mode)
1340 && (num_sign_bit_copies (op, int_mode)
1341 == GET_MODE_PRECISION (int_mode)))
1342 return gen_rtx_NEG (int_mode, op);
1343
1344 break;
1345
1346 case FFS:
1347 /* (ffs (*_extend <X>)) = (ffs <X>) */
1348 if (GET_CODE (op) == SIGN_EXTEND
1349 || GET_CODE (op) == ZERO_EXTEND)
1350 return simplify_gen_unary (FFS, mode, XEXP (op, 0),
1351 GET_MODE (XEXP (op, 0)));
1352 break;
1353
1354 case POPCOUNT:
1355 switch (GET_CODE (op))
1356 {
1357 case BSWAP:
1358 case ZERO_EXTEND:
1359 /* (popcount (zero_extend <X>)) = (popcount <X>) */
1360 return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1361 GET_MODE (XEXP (op, 0)));
1362
1363 case ROTATE:
1364 case ROTATERT:
1365 /* Rotations don't affect popcount. */
1366 if (!side_effects_p (XEXP (op, 1)))
1367 return simplify_gen_unary (POPCOUNT, mode, XEXP (op, 0),
1368 GET_MODE (XEXP (op, 0)));
1369 break;
1370
1371 default:
1372 break;
1373 }
1374 break;
1375
1376 case PARITY:
1377 switch (GET_CODE (op))
1378 {
1379 case NOT:
1380 case BSWAP:
1381 case ZERO_EXTEND:
1382 case SIGN_EXTEND:
1383 return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1384 GET_MODE (XEXP (op, 0)));
1385
1386 case ROTATE:
1387 case ROTATERT:
1388 /* Rotations don't affect parity. */
1389 if (!side_effects_p (XEXP (op, 1)))
1390 return simplify_gen_unary (PARITY, mode, XEXP (op, 0),
1391 GET_MODE (XEXP (op, 0)));
1392 break;
1393
1394 default:
1395 break;
1396 }
1397 break;
1398
1399 case BSWAP:
1400 /* (bswap (bswap x)) -> x. */
1401 if (GET_CODE (op) == BSWAP)
1402 return XEXP (op, 0);
1403 break;
1404
1405 case FLOAT:
1406 /* (float (sign_extend <X>)) = (float <X>). */
1407 if (GET_CODE (op) == SIGN_EXTEND)
1408 return simplify_gen_unary (FLOAT, mode, XEXP (op, 0),
1409 GET_MODE (XEXP (op, 0)));
1410 break;
1411
1412 case SIGN_EXTEND:
1413 /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
1414 becomes just the MINUS if its mode is MODE. This allows
1415 folding switch statements on machines using casesi (such as
1416 the VAX). */
1417 if (GET_CODE (op) == TRUNCATE
1418 && GET_MODE (XEXP (op, 0)) == mode
1419 && GET_CODE (XEXP (op, 0)) == MINUS
1420 && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
1421 && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
1422 return XEXP (op, 0);
1423
1424 /* Extending a widening multiplication should be canonicalized to
1425 a wider widening multiplication. */
1426 if (GET_CODE (op) == MULT)
1427 {
1428 rtx lhs = XEXP (op, 0);
1429 rtx rhs = XEXP (op, 1);
1430 enum rtx_code lcode = GET_CODE (lhs);
1431 enum rtx_code rcode = GET_CODE (rhs);
1432
1433 /* Widening multiplies usually extend both operands, but sometimes
1434 they use a shift to extract a portion of a register. */
1435 if ((lcode == SIGN_EXTEND
1436 || (lcode == ASHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1437 && (rcode == SIGN_EXTEND
1438 || (rcode == ASHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1439 {
1440 machine_mode lmode = GET_MODE (lhs);
1441 machine_mode rmode = GET_MODE (rhs);
1442 int bits;
1443
1444 if (lcode == ASHIFTRT)
1445 /* Number of bits not shifted off the end. */
1446 bits = (GET_MODE_UNIT_PRECISION (lmode)
1447 - INTVAL (XEXP (lhs, 1)));
1448 else /* lcode == SIGN_EXTEND */
1449 /* Size of inner mode. */
1450 bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1451
1452 if (rcode == ASHIFTRT)
1453 bits += (GET_MODE_UNIT_PRECISION (rmode)
1454 - INTVAL (XEXP (rhs, 1)));
1455 else /* rcode == SIGN_EXTEND */
1456 bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1457
1458 /* We can only widen multiplies if the result is mathematiclly
1459 equivalent. I.e. if overflow was impossible. */
1460 if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1461 return simplify_gen_binary
1462 (MULT, mode,
1463 simplify_gen_unary (SIGN_EXTEND, mode, lhs, lmode),
1464 simplify_gen_unary (SIGN_EXTEND, mode, rhs, rmode));
1465 }
1466 }
1467
1468 /* Check for a sign extension of a subreg of a promoted
1469 variable, where the promotion is sign-extended, and the
1470 target mode is the same as the variable's promotion. */
1471 if (GET_CODE (op) == SUBREG
1472 && SUBREG_PROMOTED_VAR_P (op)
1473 && SUBREG_PROMOTED_SIGNED_P (op)
1474 && !paradoxical_subreg_p (mode, GET_MODE (SUBREG_REG (op))))
1475 {
1476 temp = rtl_hooks.gen_lowpart_no_emit (mode, SUBREG_REG (op));
1477 if (temp)
1478 return temp;
1479 }
1480
1481 /* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
1482 (sign_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1483 if (GET_CODE (op) == SIGN_EXTEND || GET_CODE (op) == ZERO_EXTEND)
1484 {
1485 gcc_assert (GET_MODE_UNIT_PRECISION (mode)
1486 > GET_MODE_UNIT_PRECISION (GET_MODE (op)));
1487 return simplify_gen_unary (GET_CODE (op), mode, XEXP (op, 0),
1488 GET_MODE (XEXP (op, 0)));
1489 }
1490
1491 /* (sign_extend:M (ashiftrt:N (ashift <X> (const_int I)) (const_int I)))
1492 is (sign_extend:M (subreg:O <X>)) if there is mode with
1493 GET_MODE_BITSIZE (N) - I bits.
1494 (sign_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1495 is similarly (zero_extend:M (subreg:O <X>)). */
1496 if ((GET_CODE (op) == ASHIFTRT || GET_CODE (op) == LSHIFTRT)
1497 && GET_CODE (XEXP (op, 0)) == ASHIFT
1498 && is_a <scalar_int_mode> (mode, &int_mode)
1499 && CONST_INT_P (XEXP (op, 1))
1500 && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1501 && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1502 GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1503 {
1504 scalar_int_mode tmode;
1505 gcc_assert (GET_MODE_PRECISION (int_mode)
1506 > GET_MODE_PRECISION (op_mode));
1507 if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1508 - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1509 {
1510 rtx inner =
1511 rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1512 if (inner)
1513 return simplify_gen_unary (GET_CODE (op) == ASHIFTRT
1514 ? SIGN_EXTEND : ZERO_EXTEND,
1515 int_mode, inner, tmode);
1516 }
1517 }
1518
1519 /* (sign_extend:M (lshiftrt:N <X> (const_int I))) is better as
1520 (zero_extend:M (lshiftrt:N <X> (const_int I))) if I is not 0. */
1521 if (GET_CODE (op) == LSHIFTRT
1522 && CONST_INT_P (XEXP (op, 1))
1523 && XEXP (op, 1) != const0_rtx)
1524 return simplify_gen_unary (ZERO_EXTEND, mode, op, GET_MODE (op));
1525
1526 #if defined(POINTERS_EXTEND_UNSIGNED)
1527 /* As we do not know which address space the pointer is referring to,
1528 we can do this only if the target does not support different pointer
1529 or address modes depending on the address space. */
1530 if (target_default_pointer_address_modes_p ()
1531 && ! POINTERS_EXTEND_UNSIGNED
1532 && mode == Pmode && GET_MODE (op) == ptr_mode
1533 && (CONSTANT_P (op)
1534 || (GET_CODE (op) == SUBREG
1535 && REG_P (SUBREG_REG (op))
1536 && REG_POINTER (SUBREG_REG (op))
1537 && GET_MODE (SUBREG_REG (op)) == Pmode))
1538 && !targetm.have_ptr_extend ())
1539 {
1540 temp
1541 = convert_memory_address_addr_space_1 (Pmode, op,
1542 ADDR_SPACE_GENERIC, false,
1543 true);
1544 if (temp)
1545 return temp;
1546 }
1547 #endif
1548 break;
1549
1550 case ZERO_EXTEND:
1551 /* Check for a zero extension of a subreg of a promoted
1552 variable, where the promotion is zero-extended, and the
1553 target mode is the same as the variable's promotion. */
1554 if (GET_CODE (op) == SUBREG
1555 && SUBREG_PROMOTED_VAR_P (op)
1556 && SUBREG_PROMOTED_UNSIGNED_P (op)
1557 && !paradoxical_subreg_p (mode, GET_MODE (SUBREG_REG (op))))
1558 {
1559 temp = rtl_hooks.gen_lowpart_no_emit (mode, SUBREG_REG (op));
1560 if (temp)
1561 return temp;
1562 }
1563
1564 /* Extending a widening multiplication should be canonicalized to
1565 a wider widening multiplication. */
1566 if (GET_CODE (op) == MULT)
1567 {
1568 rtx lhs = XEXP (op, 0);
1569 rtx rhs = XEXP (op, 1);
1570 enum rtx_code lcode = GET_CODE (lhs);
1571 enum rtx_code rcode = GET_CODE (rhs);
1572
1573 /* Widening multiplies usually extend both operands, but sometimes
1574 they use a shift to extract a portion of a register. */
1575 if ((lcode == ZERO_EXTEND
1576 || (lcode == LSHIFTRT && CONST_INT_P (XEXP (lhs, 1))))
1577 && (rcode == ZERO_EXTEND
1578 || (rcode == LSHIFTRT && CONST_INT_P (XEXP (rhs, 1)))))
1579 {
1580 machine_mode lmode = GET_MODE (lhs);
1581 machine_mode rmode = GET_MODE (rhs);
1582 int bits;
1583
1584 if (lcode == LSHIFTRT)
1585 /* Number of bits not shifted off the end. */
1586 bits = (GET_MODE_UNIT_PRECISION (lmode)
1587 - INTVAL (XEXP (lhs, 1)));
1588 else /* lcode == ZERO_EXTEND */
1589 /* Size of inner mode. */
1590 bits = GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (lhs, 0)));
1591
1592 if (rcode == LSHIFTRT)
1593 bits += (GET_MODE_UNIT_PRECISION (rmode)
1594 - INTVAL (XEXP (rhs, 1)));
1595 else /* rcode == ZERO_EXTEND */
1596 bits += GET_MODE_UNIT_PRECISION (GET_MODE (XEXP (rhs, 0)));
1597
1598 /* We can only widen multiplies if the result is mathematiclly
1599 equivalent. I.e. if overflow was impossible. */
1600 if (bits <= GET_MODE_UNIT_PRECISION (GET_MODE (op)))
1601 return simplify_gen_binary
1602 (MULT, mode,
1603 simplify_gen_unary (ZERO_EXTEND, mode, lhs, lmode),
1604 simplify_gen_unary (ZERO_EXTEND, mode, rhs, rmode));
1605 }
1606 }
1607
1608 /* (zero_extend:M (zero_extend:N <X>)) is (zero_extend:M <X>). */
1609 if (GET_CODE (op) == ZERO_EXTEND)
1610 return simplify_gen_unary (ZERO_EXTEND, mode, XEXP (op, 0),
1611 GET_MODE (XEXP (op, 0)));
1612
1613 /* (zero_extend:M (lshiftrt:N (ashift <X> (const_int I)) (const_int I)))
1614 is (zero_extend:M (subreg:O <X>)) if there is mode with
1615 GET_MODE_PRECISION (N) - I bits. */
1616 if (GET_CODE (op) == LSHIFTRT
1617 && GET_CODE (XEXP (op, 0)) == ASHIFT
1618 && is_a <scalar_int_mode> (mode, &int_mode)
1619 && CONST_INT_P (XEXP (op, 1))
1620 && XEXP (XEXP (op, 0), 1) == XEXP (op, 1)
1621 && (op_mode = as_a <scalar_int_mode> (GET_MODE (op)),
1622 GET_MODE_PRECISION (op_mode) > INTVAL (XEXP (op, 1))))
1623 {
1624 scalar_int_mode tmode;
1625 if (int_mode_for_size (GET_MODE_PRECISION (op_mode)
1626 - INTVAL (XEXP (op, 1)), 1).exists (&tmode))
1627 {
1628 rtx inner =
1629 rtl_hooks.gen_lowpart_no_emit (tmode, XEXP (XEXP (op, 0), 0));
1630 if (inner)
1631 return simplify_gen_unary (ZERO_EXTEND, int_mode,
1632 inner, tmode);
1633 }
1634 }
1635
1636 /* (zero_extend:M (subreg:N <X:O>)) is <X:O> (for M == O) or
1637 (zero_extend:M <X:O>), if X doesn't have any non-zero bits outside
1638 of mode N. E.g.
1639 (zero_extend:SI (subreg:QI (and:SI (reg:SI) (const_int 63)) 0)) is
1640 (and:SI (reg:SI) (const_int 63)). */
1641 if (partial_subreg_p (op)
1642 && is_a <scalar_int_mode> (mode, &int_mode)
1643 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op)), &op0_mode)
1644 && GET_MODE_PRECISION (op0_mode) <= HOST_BITS_PER_WIDE_INT
1645 && GET_MODE_PRECISION (int_mode) >= GET_MODE_PRECISION (op0_mode)
1646 && subreg_lowpart_p (op)
1647 && (nonzero_bits (SUBREG_REG (op), op0_mode)
1648 & ~GET_MODE_MASK (GET_MODE (op))) == 0)
1649 {
1650 if (GET_MODE_PRECISION (int_mode) == GET_MODE_PRECISION (op0_mode))
1651 return SUBREG_REG (op);
1652 return simplify_gen_unary (ZERO_EXTEND, int_mode, SUBREG_REG (op),
1653 op0_mode);
1654 }
1655
1656 #if defined(POINTERS_EXTEND_UNSIGNED)
1657 /* As we do not know which address space the pointer is referring to,
1658 we can do this only if the target does not support different pointer
1659 or address modes depending on the address space. */
1660 if (target_default_pointer_address_modes_p ()
1661 && POINTERS_EXTEND_UNSIGNED > 0
1662 && mode == Pmode && GET_MODE (op) == ptr_mode
1663 && (CONSTANT_P (op)
1664 || (GET_CODE (op) == SUBREG
1665 && REG_P (SUBREG_REG (op))
1666 && REG_POINTER (SUBREG_REG (op))
1667 && GET_MODE (SUBREG_REG (op)) == Pmode))
1668 && !targetm.have_ptr_extend ())
1669 {
1670 temp
1671 = convert_memory_address_addr_space_1 (Pmode, op,
1672 ADDR_SPACE_GENERIC, false,
1673 true);
1674 if (temp)
1675 return temp;
1676 }
1677 #endif
1678 break;
1679
1680 default:
1681 break;
1682 }
1683
1684 if (VECTOR_MODE_P (mode)
1685 && vec_duplicate_p (op, &elt)
1686 && code != VEC_DUPLICATE)
1687 {
1688 /* Try applying the operator to ELT and see if that simplifies.
1689 We can duplicate the result if so.
1690
1691 The reason we don't use simplify_gen_unary is that it isn't
1692 necessarily a win to convert things like:
1693
1694 (neg:V (vec_duplicate:V (reg:S R)))
1695
1696 to:
1697
1698 (vec_duplicate:V (neg:S (reg:S R)))
1699
1700 The first might be done entirely in vector registers while the
1701 second might need a move between register files. */
1702 temp = simplify_unary_operation (code, GET_MODE_INNER (mode),
1703 elt, GET_MODE_INNER (GET_MODE (op)));
1704 if (temp)
1705 return gen_vec_duplicate (mode, temp);
1706 }
1707
1708 return 0;
1709 }
1710
1711 /* Try to compute the value of a unary operation CODE whose output mode is to
1712 be MODE with input operand OP whose mode was originally OP_MODE.
1713 Return zero if the value cannot be computed. */
1714 rtx
simplify_const_unary_operation(enum rtx_code code,machine_mode mode,rtx op,machine_mode op_mode)1715 simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
1716 rtx op, machine_mode op_mode)
1717 {
1718 scalar_int_mode result_mode;
1719
1720 if (code == VEC_DUPLICATE)
1721 {
1722 gcc_assert (VECTOR_MODE_P (mode));
1723 if (GET_MODE (op) != VOIDmode)
1724 {
1725 if (!VECTOR_MODE_P (GET_MODE (op)))
1726 gcc_assert (GET_MODE_INNER (mode) == GET_MODE (op));
1727 else
1728 gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER
1729 (GET_MODE (op)));
1730 }
1731 if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op))
1732 return gen_const_vec_duplicate (mode, op);
1733 if (GET_CODE (op) == CONST_VECTOR
1734 && (CONST_VECTOR_DUPLICATE_P (op)
1735 || CONST_VECTOR_NUNITS (op).is_constant ()))
1736 {
1737 unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op)
1738 ? CONST_VECTOR_NPATTERNS (op)
1739 : CONST_VECTOR_NUNITS (op).to_constant ());
1740 gcc_assert (multiple_p (GET_MODE_NUNITS (mode), npatterns));
1741 rtx_vector_builder builder (mode, npatterns, 1);
1742 for (unsigned i = 0; i < npatterns; i++)
1743 builder.quick_push (CONST_VECTOR_ELT (op, i));
1744 return builder.build ();
1745 }
1746 }
1747
1748 if (VECTOR_MODE_P (mode)
1749 && GET_CODE (op) == CONST_VECTOR
1750 && known_eq (GET_MODE_NUNITS (mode), CONST_VECTOR_NUNITS (op)))
1751 {
1752 gcc_assert (GET_MODE (op) == op_mode);
1753
1754 rtx_vector_builder builder;
1755 if (!builder.new_unary_operation (mode, op, false))
1756 return 0;
1757
1758 unsigned int count = builder.encoded_nelts ();
1759 for (unsigned int i = 0; i < count; i++)
1760 {
1761 rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
1762 CONST_VECTOR_ELT (op, i),
1763 GET_MODE_INNER (op_mode));
1764 if (!x || !valid_for_const_vector_p (mode, x))
1765 return 0;
1766 builder.quick_push (x);
1767 }
1768 return builder.build ();
1769 }
1770
1771 /* The order of these tests is critical so that, for example, we don't
1772 check the wrong mode (input vs. output) for a conversion operation,
1773 such as FIX. At some point, this should be simplified. */
1774
1775 if (code == FLOAT && CONST_SCALAR_INT_P (op))
1776 {
1777 REAL_VALUE_TYPE d;
1778
1779 if (op_mode == VOIDmode)
1780 {
1781 /* CONST_INT have VOIDmode as the mode. We assume that all
1782 the bits of the constant are significant, though, this is
1783 a dangerous assumption as many times CONST_INTs are
1784 created and used with garbage in the bits outside of the
1785 precision of the implied mode of the const_int. */
1786 op_mode = MAX_MODE_INT;
1787 }
1788
1789 real_from_integer (&d, mode, rtx_mode_t (op, op_mode), SIGNED);
1790
1791 /* Avoid the folding if flag_signaling_nans is on and
1792 operand is a signaling NaN. */
1793 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
1794 return 0;
1795
1796 d = real_value_truncate (mode, d);
1797 return const_double_from_real_value (d, mode);
1798 }
1799 else if (code == UNSIGNED_FLOAT && CONST_SCALAR_INT_P (op))
1800 {
1801 REAL_VALUE_TYPE d;
1802
1803 if (op_mode == VOIDmode)
1804 {
1805 /* CONST_INT have VOIDmode as the mode. We assume that all
1806 the bits of the constant are significant, though, this is
1807 a dangerous assumption as many times CONST_INTs are
1808 created and used with garbage in the bits outside of the
1809 precision of the implied mode of the const_int. */
1810 op_mode = MAX_MODE_INT;
1811 }
1812
1813 real_from_integer (&d, mode, rtx_mode_t (op, op_mode), UNSIGNED);
1814
1815 /* Avoid the folding if flag_signaling_nans is on and
1816 operand is a signaling NaN. */
1817 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
1818 return 0;
1819
1820 d = real_value_truncate (mode, d);
1821 return const_double_from_real_value (d, mode);
1822 }
1823
1824 if (CONST_SCALAR_INT_P (op) && is_a <scalar_int_mode> (mode, &result_mode))
1825 {
1826 unsigned int width = GET_MODE_PRECISION (result_mode);
1827 if (width > MAX_BITSIZE_MODE_ANY_INT)
1828 return 0;
1829
1830 wide_int result;
1831 scalar_int_mode imode = (op_mode == VOIDmode
1832 ? result_mode
1833 : as_a <scalar_int_mode> (op_mode));
1834 rtx_mode_t op0 = rtx_mode_t (op, imode);
1835 int int_value;
1836
1837 #if TARGET_SUPPORTS_WIDE_INT == 0
1838 /* This assert keeps the simplification from producing a result
1839 that cannot be represented in a CONST_DOUBLE but a lot of
1840 upstream callers expect that this function never fails to
1841 simplify something and so you if you added this to the test
1842 above the code would die later anyway. If this assert
1843 happens, you just need to make the port support wide int. */
1844 gcc_assert (width <= HOST_BITS_PER_DOUBLE_INT);
1845 #endif
1846
1847 switch (code)
1848 {
1849 case NOT:
1850 result = wi::bit_not (op0);
1851 break;
1852
1853 case NEG:
1854 result = wi::neg (op0);
1855 break;
1856
1857 case ABS:
1858 result = wi::abs (op0);
1859 break;
1860
1861 case FFS:
1862 result = wi::shwi (wi::ffs (op0), result_mode);
1863 break;
1864
1865 case CLZ:
1866 if (wi::ne_p (op0, 0))
1867 int_value = wi::clz (op0);
1868 else if (! CLZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
1869 return NULL_RTX;
1870 result = wi::shwi (int_value, result_mode);
1871 break;
1872
1873 case CLRSB:
1874 result = wi::shwi (wi::clrsb (op0), result_mode);
1875 break;
1876
1877 case CTZ:
1878 if (wi::ne_p (op0, 0))
1879 int_value = wi::ctz (op0);
1880 else if (! CTZ_DEFINED_VALUE_AT_ZERO (imode, int_value))
1881 return NULL_RTX;
1882 result = wi::shwi (int_value, result_mode);
1883 break;
1884
1885 case POPCOUNT:
1886 result = wi::shwi (wi::popcount (op0), result_mode);
1887 break;
1888
1889 case PARITY:
1890 result = wi::shwi (wi::parity (op0), result_mode);
1891 break;
1892
1893 case BSWAP:
1894 result = wide_int (op0).bswap ();
1895 break;
1896
1897 case TRUNCATE:
1898 case ZERO_EXTEND:
1899 result = wide_int::from (op0, width, UNSIGNED);
1900 break;
1901
1902 case SIGN_EXTEND:
1903 result = wide_int::from (op0, width, SIGNED);
1904 break;
1905
1906 case SQRT:
1907 default:
1908 return 0;
1909 }
1910
1911 return immed_wide_int_const (result, result_mode);
1912 }
1913
1914 else if (CONST_DOUBLE_AS_FLOAT_P (op)
1915 && SCALAR_FLOAT_MODE_P (mode)
1916 && SCALAR_FLOAT_MODE_P (GET_MODE (op)))
1917 {
1918 REAL_VALUE_TYPE d = *CONST_DOUBLE_REAL_VALUE (op);
1919 switch (code)
1920 {
1921 case SQRT:
1922 return 0;
1923 case ABS:
1924 d = real_value_abs (&d);
1925 break;
1926 case NEG:
1927 d = real_value_negate (&d);
1928 break;
1929 case FLOAT_TRUNCATE:
1930 /* Don't perform the operation if flag_signaling_nans is on
1931 and the operand is a signaling NaN. */
1932 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
1933 return NULL_RTX;
1934 d = real_value_truncate (mode, d);
1935 break;
1936 case FLOAT_EXTEND:
1937 /* Don't perform the operation if flag_signaling_nans is on
1938 and the operand is a signaling NaN. */
1939 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
1940 return NULL_RTX;
1941 /* All this does is change the mode, unless changing
1942 mode class. */
1943 if (GET_MODE_CLASS (mode) != GET_MODE_CLASS (GET_MODE (op)))
1944 real_convert (&d, mode, &d);
1945 break;
1946 case FIX:
1947 /* Don't perform the operation if flag_signaling_nans is on
1948 and the operand is a signaling NaN. */
1949 if (HONOR_SNANS (mode) && REAL_VALUE_ISSIGNALING_NAN (d))
1950 return NULL_RTX;
1951 real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
1952 break;
1953 case NOT:
1954 {
1955 long tmp[4];
1956 int i;
1957
1958 real_to_target (tmp, &d, GET_MODE (op));
1959 for (i = 0; i < 4; i++)
1960 tmp[i] = ~tmp[i];
1961 real_from_target (&d, tmp, mode);
1962 break;
1963 }
1964 default:
1965 gcc_unreachable ();
1966 }
1967 return const_double_from_real_value (d, mode);
1968 }
1969 else if (CONST_DOUBLE_AS_FLOAT_P (op)
1970 && SCALAR_FLOAT_MODE_P (GET_MODE (op))
1971 && is_int_mode (mode, &result_mode))
1972 {
1973 unsigned int width = GET_MODE_PRECISION (result_mode);
1974 if (width > MAX_BITSIZE_MODE_ANY_INT)
1975 return 0;
1976
1977 /* Although the overflow semantics of RTL's FIX and UNSIGNED_FIX
1978 operators are intentionally left unspecified (to ease implementation
1979 by target backends), for consistency, this routine implements the
1980 same semantics for constant folding as used by the middle-end. */
1981
1982 /* This was formerly used only for non-IEEE float.
1983 eggert@twinsun.com says it is safe for IEEE also. */
1984 REAL_VALUE_TYPE t;
1985 const REAL_VALUE_TYPE *x = CONST_DOUBLE_REAL_VALUE (op);
1986 wide_int wmax, wmin;
1987 /* This is part of the abi to real_to_integer, but we check
1988 things before making this call. */
1989 bool fail;
1990
1991 switch (code)
1992 {
1993 case FIX:
1994 if (REAL_VALUE_ISNAN (*x))
1995 return const0_rtx;
1996
1997 /* Test against the signed upper bound. */
1998 wmax = wi::max_value (width, SIGNED);
1999 real_from_integer (&t, VOIDmode, wmax, SIGNED);
2000 if (real_less (&t, x))
2001 return immed_wide_int_const (wmax, mode);
2002
2003 /* Test against the signed lower bound. */
2004 wmin = wi::min_value (width, SIGNED);
2005 real_from_integer (&t, VOIDmode, wmin, SIGNED);
2006 if (real_less (x, &t))
2007 return immed_wide_int_const (wmin, mode);
2008
2009 return immed_wide_int_const (real_to_integer (x, &fail, width),
2010 mode);
2011
2012 case UNSIGNED_FIX:
2013 if (REAL_VALUE_ISNAN (*x) || REAL_VALUE_NEGATIVE (*x))
2014 return const0_rtx;
2015
2016 /* Test against the unsigned upper bound. */
2017 wmax = wi::max_value (width, UNSIGNED);
2018 real_from_integer (&t, VOIDmode, wmax, UNSIGNED);
2019 if (real_less (&t, x))
2020 return immed_wide_int_const (wmax, mode);
2021
2022 return immed_wide_int_const (real_to_integer (x, &fail, width),
2023 mode);
2024
2025 default:
2026 gcc_unreachable ();
2027 }
2028 }
2029
2030 /* Handle polynomial integers. */
2031 else if (CONST_POLY_INT_P (op))
2032 {
2033 poly_wide_int result;
2034 switch (code)
2035 {
2036 case NEG:
2037 result = -const_poly_int_value (op);
2038 break;
2039
2040 case NOT:
2041 result = ~const_poly_int_value (op);
2042 break;
2043
2044 default:
2045 return NULL_RTX;
2046 }
2047 return immed_wide_int_const (result, mode);
2048 }
2049
2050 return NULL_RTX;
2051 }
2052
2053 /* Subroutine of simplify_binary_operation to simplify a binary operation
2054 CODE that can commute with byte swapping, with result mode MODE and
2055 operating on OP0 and OP1. CODE is currently one of AND, IOR or XOR.
2056 Return zero if no simplification or canonicalization is possible. */
2057
2058 static rtx
simplify_byte_swapping_operation(enum rtx_code code,machine_mode mode,rtx op0,rtx op1)2059 simplify_byte_swapping_operation (enum rtx_code code, machine_mode mode,
2060 rtx op0, rtx op1)
2061 {
2062 rtx tem;
2063
2064 /* (op (bswap x) C1)) -> (bswap (op x C2)) with C2 swapped. */
2065 if (GET_CODE (op0) == BSWAP && CONST_SCALAR_INT_P (op1))
2066 {
2067 tem = simplify_gen_binary (code, mode, XEXP (op0, 0),
2068 simplify_gen_unary (BSWAP, mode, op1, mode));
2069 return simplify_gen_unary (BSWAP, mode, tem, mode);
2070 }
2071
2072 /* (op (bswap x) (bswap y)) -> (bswap (op x y)). */
2073 if (GET_CODE (op0) == BSWAP && GET_CODE (op1) == BSWAP)
2074 {
2075 tem = simplify_gen_binary (code, mode, XEXP (op0, 0), XEXP (op1, 0));
2076 return simplify_gen_unary (BSWAP, mode, tem, mode);
2077 }
2078
2079 return NULL_RTX;
2080 }
2081
2082 /* Subroutine of simplify_binary_operation to simplify a commutative,
2083 associative binary operation CODE with result mode MODE, operating
2084 on OP0 and OP1. CODE is currently one of PLUS, MULT, AND, IOR, XOR,
2085 SMIN, SMAX, UMIN or UMAX. Return zero if no simplification or
2086 canonicalization is possible. */
2087
2088 static rtx
simplify_associative_operation(enum rtx_code code,machine_mode mode,rtx op0,rtx op1)2089 simplify_associative_operation (enum rtx_code code, machine_mode mode,
2090 rtx op0, rtx op1)
2091 {
2092 rtx tem;
2093
2094 /* Linearize the operator to the left. */
2095 if (GET_CODE (op1) == code)
2096 {
2097 /* "(a op b) op (c op d)" becomes "((a op b) op c) op d)". */
2098 if (GET_CODE (op0) == code)
2099 {
2100 tem = simplify_gen_binary (code, mode, op0, XEXP (op1, 0));
2101 return simplify_gen_binary (code, mode, tem, XEXP (op1, 1));
2102 }
2103
2104 /* "a op (b op c)" becomes "(b op c) op a". */
2105 if (! swap_commutative_operands_p (op1, op0))
2106 return simplify_gen_binary (code, mode, op1, op0);
2107
2108 std::swap (op0, op1);
2109 }
2110
2111 if (GET_CODE (op0) == code)
2112 {
2113 /* Canonicalize "(x op c) op y" as "(x op y) op c". */
2114 if (swap_commutative_operands_p (XEXP (op0, 1), op1))
2115 {
2116 tem = simplify_gen_binary (code, mode, XEXP (op0, 0), op1);
2117 return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2118 }
2119
2120 /* Attempt to simplify "(a op b) op c" as "a op (b op c)". */
2121 tem = simplify_binary_operation (code, mode, XEXP (op0, 1), op1);
2122 if (tem != 0)
2123 return simplify_gen_binary (code, mode, XEXP (op0, 0), tem);
2124
2125 /* Attempt to simplify "(a op b) op c" as "(a op c) op b". */
2126 tem = simplify_binary_operation (code, mode, XEXP (op0, 0), op1);
2127 if (tem != 0)
2128 return simplify_gen_binary (code, mode, tem, XEXP (op0, 1));
2129 }
2130
2131 return 0;
2132 }
2133
2134 /* Return a mask describing the COMPARISON. */
2135 static int
comparison_to_mask(enum rtx_code comparison)2136 comparison_to_mask (enum rtx_code comparison)
2137 {
2138 switch (comparison)
2139 {
2140 case LT:
2141 return 8;
2142 case GT:
2143 return 4;
2144 case EQ:
2145 return 2;
2146 case UNORDERED:
2147 return 1;
2148
2149 case LTGT:
2150 return 12;
2151 case LE:
2152 return 10;
2153 case GE:
2154 return 6;
2155 case UNLT:
2156 return 9;
2157 case UNGT:
2158 return 5;
2159 case UNEQ:
2160 return 3;
2161
2162 case ORDERED:
2163 return 14;
2164 case NE:
2165 return 13;
2166 case UNLE:
2167 return 11;
2168 case UNGE:
2169 return 7;
2170
2171 default:
2172 gcc_unreachable ();
2173 }
2174 }
2175
2176 /* Return a comparison corresponding to the MASK. */
2177 static enum rtx_code
mask_to_comparison(int mask)2178 mask_to_comparison (int mask)
2179 {
2180 switch (mask)
2181 {
2182 case 8:
2183 return LT;
2184 case 4:
2185 return GT;
2186 case 2:
2187 return EQ;
2188 case 1:
2189 return UNORDERED;
2190
2191 case 12:
2192 return LTGT;
2193 case 10:
2194 return LE;
2195 case 6:
2196 return GE;
2197 case 9:
2198 return UNLT;
2199 case 5:
2200 return UNGT;
2201 case 3:
2202 return UNEQ;
2203
2204 case 14:
2205 return ORDERED;
2206 case 13:
2207 return NE;
2208 case 11:
2209 return UNLE;
2210 case 7:
2211 return UNGE;
2212
2213 default:
2214 gcc_unreachable ();
2215 }
2216 }
2217
2218 /* Return true if CODE is valid for comparisons of mode MODE, false
2219 otherwise.
2220
2221 It is always safe to return false, even if the code was valid for the
2222 given mode as that will merely suppress optimizations. */
2223
2224 static bool
comparison_code_valid_for_mode(enum rtx_code code,enum machine_mode mode)2225 comparison_code_valid_for_mode (enum rtx_code code, enum machine_mode mode)
2226 {
2227 switch (code)
2228 {
2229 /* These are valid for integral, floating and vector modes. */
2230 case NE:
2231 case EQ:
2232 case GE:
2233 case GT:
2234 case LE:
2235 case LT:
2236 return (INTEGRAL_MODE_P (mode)
2237 || FLOAT_MODE_P (mode)
2238 || VECTOR_MODE_P (mode));
2239
2240 /* These are valid for floating point modes. */
2241 case LTGT:
2242 case UNORDERED:
2243 case ORDERED:
2244 case UNEQ:
2245 case UNGE:
2246 case UNGT:
2247 case UNLE:
2248 case UNLT:
2249 return FLOAT_MODE_P (mode);
2250
2251 /* These are filtered out in simplify_logical_operation, but
2252 we check for them too as a matter of safety. They are valid
2253 for integral and vector modes. */
2254 case GEU:
2255 case GTU:
2256 case LEU:
2257 case LTU:
2258 return INTEGRAL_MODE_P (mode) || VECTOR_MODE_P (mode);
2259
2260 default:
2261 gcc_unreachable ();
2262 }
2263 }
2264
2265 /* Canonicalize RES, a scalar const0_rtx/const_true_rtx to the right
2266 false/true value of comparison with MODE where comparison operands
2267 have CMP_MODE. */
2268
2269 static rtx
relational_result(machine_mode mode,machine_mode cmp_mode,rtx res)2270 relational_result (machine_mode mode, machine_mode cmp_mode, rtx res)
2271 {
2272 if (SCALAR_FLOAT_MODE_P (mode))
2273 {
2274 if (res == const0_rtx)
2275 return CONST0_RTX (mode);
2276 #ifdef FLOAT_STORE_FLAG_VALUE
2277 REAL_VALUE_TYPE val = FLOAT_STORE_FLAG_VALUE (mode);
2278 return const_double_from_real_value (val, mode);
2279 #else
2280 return NULL_RTX;
2281 #endif
2282 }
2283 if (VECTOR_MODE_P (mode))
2284 {
2285 if (res == const0_rtx)
2286 return CONST0_RTX (mode);
2287 #ifdef VECTOR_STORE_FLAG_VALUE
2288 rtx val = VECTOR_STORE_FLAG_VALUE (mode);
2289 if (val == NULL_RTX)
2290 return NULL_RTX;
2291 if (val == const1_rtx)
2292 return CONST1_RTX (mode);
2293
2294 return gen_const_vec_duplicate (mode, val);
2295 #else
2296 return NULL_RTX;
2297 #endif
2298 }
2299 /* For vector comparison with scalar int result, it is unknown
2300 if the target means here a comparison into an integral bitmask,
2301 or comparison where all comparisons true mean const_true_rtx
2302 whole result, or where any comparisons true mean const_true_rtx
2303 whole result. For const0_rtx all the cases are the same. */
2304 if (VECTOR_MODE_P (cmp_mode)
2305 && SCALAR_INT_MODE_P (mode)
2306 && res == const_true_rtx)
2307 return NULL_RTX;
2308
2309 return res;
2310 }
2311
2312 /* Simplify a logical operation CODE with result mode MODE, operating on OP0
2313 and OP1, which should be both relational operations. Return 0 if no such
2314 simplification is possible. */
2315 rtx
simplify_logical_relational_operation(enum rtx_code code,machine_mode mode,rtx op0,rtx op1)2316 simplify_logical_relational_operation (enum rtx_code code, machine_mode mode,
2317 rtx op0, rtx op1)
2318 {
2319 /* We only handle IOR of two relational operations. */
2320 if (code != IOR)
2321 return 0;
2322
2323 if (!(COMPARISON_P (op0) && COMPARISON_P (op1)))
2324 return 0;
2325
2326 if (!(rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2327 && rtx_equal_p (XEXP (op0, 1), XEXP (op1, 1))))
2328 return 0;
2329
2330 enum rtx_code code0 = GET_CODE (op0);
2331 enum rtx_code code1 = GET_CODE (op1);
2332
2333 /* We don't handle unsigned comparisons currently. */
2334 if (code0 == LTU || code0 == GTU || code0 == LEU || code0 == GEU)
2335 return 0;
2336 if (code1 == LTU || code1 == GTU || code1 == LEU || code1 == GEU)
2337 return 0;
2338
2339 int mask0 = comparison_to_mask (code0);
2340 int mask1 = comparison_to_mask (code1);
2341
2342 int mask = mask0 | mask1;
2343
2344 if (mask == 15)
2345 return relational_result (mode, GET_MODE (op0), const_true_rtx);
2346
2347 code = mask_to_comparison (mask);
2348
2349 /* Many comparison codes are only valid for certain mode classes. */
2350 if (!comparison_code_valid_for_mode (code, mode))
2351 return 0;
2352
2353 op0 = XEXP (op1, 0);
2354 op1 = XEXP (op1, 1);
2355
2356 return simplify_gen_relational (code, mode, VOIDmode, op0, op1);
2357 }
2358
2359 /* Simplify a binary operation CODE with result mode MODE, operating on OP0
2360 and OP1. Return 0 if no simplification is possible.
2361
2362 Don't use this for relational operations such as EQ or LT.
2363 Use simplify_relational_operation instead. */
2364 rtx
simplify_binary_operation(enum rtx_code code,machine_mode mode,rtx op0,rtx op1)2365 simplify_binary_operation (enum rtx_code code, machine_mode mode,
2366 rtx op0, rtx op1)
2367 {
2368 rtx trueop0, trueop1;
2369 rtx tem;
2370
2371 /* Relational operations don't work here. We must know the mode
2372 of the operands in order to do the comparison correctly.
2373 Assuming a full word can give incorrect results.
2374 Consider comparing 128 with -128 in QImode. */
2375 gcc_assert (GET_RTX_CLASS (code) != RTX_COMPARE);
2376 gcc_assert (GET_RTX_CLASS (code) != RTX_COMM_COMPARE);
2377
2378 /* Make sure the constant is second. */
2379 if (GET_RTX_CLASS (code) == RTX_COMM_ARITH
2380 && swap_commutative_operands_p (op0, op1))
2381 std::swap (op0, op1);
2382
2383 trueop0 = avoid_constant_pool_reference (op0);
2384 trueop1 = avoid_constant_pool_reference (op1);
2385
2386 tem = simplify_const_binary_operation (code, mode, trueop0, trueop1);
2387 if (tem)
2388 return tem;
2389 tem = simplify_binary_operation_1 (code, mode, op0, op1, trueop0, trueop1);
2390
2391 if (tem)
2392 return tem;
2393
2394 /* If the above steps did not result in a simplification and op0 or op1
2395 were constant pool references, use the referenced constants directly. */
2396 if (trueop0 != op0 || trueop1 != op1)
2397 return simplify_gen_binary (code, mode, trueop0, trueop1);
2398
2399 return NULL_RTX;
2400 }
2401
2402 /* Subroutine of simplify_binary_operation_1 that looks for cases in
2403 which OP0 and OP1 are both vector series or vector duplicates
2404 (which are really just series with a step of 0). If so, try to
2405 form a new series by applying CODE to the bases and to the steps.
2406 Return null if no simplification is possible.
2407
2408 MODE is the mode of the operation and is known to be a vector
2409 integer mode. */
2410
2411 static rtx
simplify_binary_operation_series(rtx_code code,machine_mode mode,rtx op0,rtx op1)2412 simplify_binary_operation_series (rtx_code code, machine_mode mode,
2413 rtx op0, rtx op1)
2414 {
2415 rtx base0, step0;
2416 if (vec_duplicate_p (op0, &base0))
2417 step0 = const0_rtx;
2418 else if (!vec_series_p (op0, &base0, &step0))
2419 return NULL_RTX;
2420
2421 rtx base1, step1;
2422 if (vec_duplicate_p (op1, &base1))
2423 step1 = const0_rtx;
2424 else if (!vec_series_p (op1, &base1, &step1))
2425 return NULL_RTX;
2426
2427 /* Only create a new series if we can simplify both parts. In other
2428 cases this isn't really a simplification, and it's not necessarily
2429 a win to replace a vector operation with a scalar operation. */
2430 scalar_mode inner_mode = GET_MODE_INNER (mode);
2431 rtx new_base = simplify_binary_operation (code, inner_mode, base0, base1);
2432 if (!new_base)
2433 return NULL_RTX;
2434
2435 rtx new_step = simplify_binary_operation (code, inner_mode, step0, step1);
2436 if (!new_step)
2437 return NULL_RTX;
2438
2439 return gen_vec_series (mode, new_base, new_step);
2440 }
2441
2442 /* Subroutine of simplify_binary_operation. Simplify a binary operation
2443 CODE with result mode MODE, operating on OP0 and OP1. If OP0 and/or
2444 OP1 are constant pool references, TRUEOP0 and TRUEOP1 represent the
2445 actual constants. */
2446
2447 static rtx
simplify_binary_operation_1(enum rtx_code code,machine_mode mode,rtx op0,rtx op1,rtx trueop0,rtx trueop1)2448 simplify_binary_operation_1 (enum rtx_code code, machine_mode mode,
2449 rtx op0, rtx op1, rtx trueop0, rtx trueop1)
2450 {
2451 rtx tem, reversed, opleft, opright, elt0, elt1;
2452 HOST_WIDE_INT val;
2453 scalar_int_mode int_mode, inner_mode;
2454 poly_int64 offset;
2455
2456 /* Even if we can't compute a constant result,
2457 there are some cases worth simplifying. */
2458
2459 switch (code)
2460 {
2461 case PLUS:
2462 /* Maybe simplify x + 0 to x. The two expressions are equivalent
2463 when x is NaN, infinite, or finite and nonzero. They aren't
2464 when x is -0 and the rounding mode is not towards -infinity,
2465 since (-0) + 0 is then 0. */
2466 if (!HONOR_SIGNED_ZEROS (mode) && trueop1 == CONST0_RTX (mode))
2467 return op0;
2468
2469 /* ((-a) + b) -> (b - a) and similarly for (a + (-b)). These
2470 transformations are safe even for IEEE. */
2471 if (GET_CODE (op0) == NEG)
2472 return simplify_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
2473 else if (GET_CODE (op1) == NEG)
2474 return simplify_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
2475
2476 /* (~a) + 1 -> -a */
2477 if (INTEGRAL_MODE_P (mode)
2478 && GET_CODE (op0) == NOT
2479 && trueop1 == const1_rtx)
2480 return simplify_gen_unary (NEG, mode, XEXP (op0, 0), mode);
2481
2482 /* Handle both-operands-constant cases. We can only add
2483 CONST_INTs to constants since the sum of relocatable symbols
2484 can't be handled by most assemblers. Don't add CONST_INT
2485 to CONST_INT since overflow won't be computed properly if wider
2486 than HOST_BITS_PER_WIDE_INT. */
2487
2488 if ((GET_CODE (op0) == CONST
2489 || GET_CODE (op0) == SYMBOL_REF
2490 || GET_CODE (op0) == LABEL_REF)
2491 && poly_int_rtx_p (op1, &offset))
2492 return plus_constant (mode, op0, offset);
2493 else if ((GET_CODE (op1) == CONST
2494 || GET_CODE (op1) == SYMBOL_REF
2495 || GET_CODE (op1) == LABEL_REF)
2496 && poly_int_rtx_p (op0, &offset))
2497 return plus_constant (mode, op1, offset);
2498
2499 /* See if this is something like X * C - X or vice versa or
2500 if the multiplication is written as a shift. If so, we can
2501 distribute and make a new multiply, shift, or maybe just
2502 have X (if C is 2 in the example above). But don't make
2503 something more expensive than we had before. */
2504
2505 if (is_a <scalar_int_mode> (mode, &int_mode))
2506 {
2507 rtx lhs = op0, rhs = op1;
2508
2509 wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
2510 wide_int coeff1 = wi::one (GET_MODE_PRECISION (int_mode));
2511
2512 if (GET_CODE (lhs) == NEG)
2513 {
2514 coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
2515 lhs = XEXP (lhs, 0);
2516 }
2517 else if (GET_CODE (lhs) == MULT
2518 && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
2519 {
2520 coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
2521 lhs = XEXP (lhs, 0);
2522 }
2523 else if (GET_CODE (lhs) == ASHIFT
2524 && CONST_INT_P (XEXP (lhs, 1))
2525 && INTVAL (XEXP (lhs, 1)) >= 0
2526 && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
2527 {
2528 coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
2529 GET_MODE_PRECISION (int_mode));
2530 lhs = XEXP (lhs, 0);
2531 }
2532
2533 if (GET_CODE (rhs) == NEG)
2534 {
2535 coeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
2536 rhs = XEXP (rhs, 0);
2537 }
2538 else if (GET_CODE (rhs) == MULT
2539 && CONST_INT_P (XEXP (rhs, 1)))
2540 {
2541 coeff1 = rtx_mode_t (XEXP (rhs, 1), int_mode);
2542 rhs = XEXP (rhs, 0);
2543 }
2544 else if (GET_CODE (rhs) == ASHIFT
2545 && CONST_INT_P (XEXP (rhs, 1))
2546 && INTVAL (XEXP (rhs, 1)) >= 0
2547 && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
2548 {
2549 coeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
2550 GET_MODE_PRECISION (int_mode));
2551 rhs = XEXP (rhs, 0);
2552 }
2553
2554 if (rtx_equal_p (lhs, rhs))
2555 {
2556 rtx orig = gen_rtx_PLUS (int_mode, op0, op1);
2557 rtx coeff;
2558 bool speed = optimize_function_for_speed_p (cfun);
2559
2560 coeff = immed_wide_int_const (coeff0 + coeff1, int_mode);
2561
2562 tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
2563 return (set_src_cost (tem, int_mode, speed)
2564 <= set_src_cost (orig, int_mode, speed) ? tem : 0);
2565 }
2566 }
2567
2568 /* (plus (xor X C1) C2) is (xor X (C1^C2)) if C2 is signbit. */
2569 if (CONST_SCALAR_INT_P (op1)
2570 && GET_CODE (op0) == XOR
2571 && CONST_SCALAR_INT_P (XEXP (op0, 1))
2572 && mode_signbit_p (mode, op1))
2573 return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
2574 simplify_gen_binary (XOR, mode, op1,
2575 XEXP (op0, 1)));
2576
2577 /* Canonicalize (plus (mult (neg B) C) A) to (minus A (mult B C)). */
2578 if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2579 && GET_CODE (op0) == MULT
2580 && GET_CODE (XEXP (op0, 0)) == NEG)
2581 {
2582 rtx in1, in2;
2583
2584 in1 = XEXP (XEXP (op0, 0), 0);
2585 in2 = XEXP (op0, 1);
2586 return simplify_gen_binary (MINUS, mode, op1,
2587 simplify_gen_binary (MULT, mode,
2588 in1, in2));
2589 }
2590
2591 /* (plus (comparison A B) C) can become (neg (rev-comp A B)) if
2592 C is 1 and STORE_FLAG_VALUE is -1 or if C is -1 and STORE_FLAG_VALUE
2593 is 1. */
2594 if (COMPARISON_P (op0)
2595 && ((STORE_FLAG_VALUE == -1 && trueop1 == const1_rtx)
2596 || (STORE_FLAG_VALUE == 1 && trueop1 == constm1_rtx))
2597 && (reversed = reversed_comparison (op0, mode)))
2598 return
2599 simplify_gen_unary (NEG, mode, reversed, mode);
2600
2601 /* If one of the operands is a PLUS or a MINUS, see if we can
2602 simplify this by the associative law.
2603 Don't use the associative law for floating point.
2604 The inaccuracy makes it nonassociative,
2605 and subtle programs can break if operations are associated. */
2606
2607 if (INTEGRAL_MODE_P (mode)
2608 && (plus_minus_operand_p (op0)
2609 || plus_minus_operand_p (op1))
2610 && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
2611 return tem;
2612
2613 /* Reassociate floating point addition only when the user
2614 specifies associative math operations. */
2615 if (FLOAT_MODE_P (mode)
2616 && flag_associative_math)
2617 {
2618 tem = simplify_associative_operation (code, mode, op0, op1);
2619 if (tem)
2620 return tem;
2621 }
2622
2623 /* Handle vector series. */
2624 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
2625 {
2626 tem = simplify_binary_operation_series (code, mode, op0, op1);
2627 if (tem)
2628 return tem;
2629 }
2630 break;
2631
2632 case COMPARE:
2633 /* Convert (compare (gt (flags) 0) (lt (flags) 0)) to (flags). */
2634 if (((GET_CODE (op0) == GT && GET_CODE (op1) == LT)
2635 || (GET_CODE (op0) == GTU && GET_CODE (op1) == LTU))
2636 && XEXP (op0, 1) == const0_rtx && XEXP (op1, 1) == const0_rtx)
2637 {
2638 rtx xop00 = XEXP (op0, 0);
2639 rtx xop10 = XEXP (op1, 0);
2640
2641 if (GET_CODE (xop00) == CC0 && GET_CODE (xop10) == CC0)
2642 return xop00;
2643
2644 if (REG_P (xop00) && REG_P (xop10)
2645 && REGNO (xop00) == REGNO (xop10)
2646 && GET_MODE (xop00) == mode
2647 && GET_MODE (xop10) == mode
2648 && GET_MODE_CLASS (mode) == MODE_CC)
2649 return xop00;
2650 }
2651 break;
2652
2653 case MINUS:
2654 /* We can't assume x-x is 0 even with non-IEEE floating point,
2655 but since it is zero except in very strange circumstances, we
2656 will treat it as zero with -ffinite-math-only. */
2657 if (rtx_equal_p (trueop0, trueop1)
2658 && ! side_effects_p (op0)
2659 && (!FLOAT_MODE_P (mode) || !HONOR_NANS (mode)))
2660 return CONST0_RTX (mode);
2661
2662 /* Change subtraction from zero into negation. (0 - x) is the
2663 same as -x when x is NaN, infinite, or finite and nonzero.
2664 But if the mode has signed zeros, and does not round towards
2665 -infinity, then 0 - 0 is 0, not -0. */
2666 if (!HONOR_SIGNED_ZEROS (mode) && trueop0 == CONST0_RTX (mode))
2667 return simplify_gen_unary (NEG, mode, op1, mode);
2668
2669 /* (-1 - a) is ~a, unless the expression contains symbolic
2670 constants, in which case not retaining additions and
2671 subtractions could cause invalid assembly to be produced. */
2672 if (trueop0 == constm1_rtx
2673 && !contains_symbolic_reference_p (op1))
2674 return simplify_gen_unary (NOT, mode, op1, mode);
2675
2676 /* Subtracting 0 has no effect unless the mode has signed zeros
2677 and supports rounding towards -infinity. In such a case,
2678 0 - 0 is -0. */
2679 if (!(HONOR_SIGNED_ZEROS (mode)
2680 && HONOR_SIGN_DEPENDENT_ROUNDING (mode))
2681 && trueop1 == CONST0_RTX (mode))
2682 return op0;
2683
2684 /* See if this is something like X * C - X or vice versa or
2685 if the multiplication is written as a shift. If so, we can
2686 distribute and make a new multiply, shift, or maybe just
2687 have X (if C is 2 in the example above). But don't make
2688 something more expensive than we had before. */
2689
2690 if (is_a <scalar_int_mode> (mode, &int_mode))
2691 {
2692 rtx lhs = op0, rhs = op1;
2693
2694 wide_int coeff0 = wi::one (GET_MODE_PRECISION (int_mode));
2695 wide_int negcoeff1 = wi::minus_one (GET_MODE_PRECISION (int_mode));
2696
2697 if (GET_CODE (lhs) == NEG)
2698 {
2699 coeff0 = wi::minus_one (GET_MODE_PRECISION (int_mode));
2700 lhs = XEXP (lhs, 0);
2701 }
2702 else if (GET_CODE (lhs) == MULT
2703 && CONST_SCALAR_INT_P (XEXP (lhs, 1)))
2704 {
2705 coeff0 = rtx_mode_t (XEXP (lhs, 1), int_mode);
2706 lhs = XEXP (lhs, 0);
2707 }
2708 else if (GET_CODE (lhs) == ASHIFT
2709 && CONST_INT_P (XEXP (lhs, 1))
2710 && INTVAL (XEXP (lhs, 1)) >= 0
2711 && INTVAL (XEXP (lhs, 1)) < GET_MODE_PRECISION (int_mode))
2712 {
2713 coeff0 = wi::set_bit_in_zero (INTVAL (XEXP (lhs, 1)),
2714 GET_MODE_PRECISION (int_mode));
2715 lhs = XEXP (lhs, 0);
2716 }
2717
2718 if (GET_CODE (rhs) == NEG)
2719 {
2720 negcoeff1 = wi::one (GET_MODE_PRECISION (int_mode));
2721 rhs = XEXP (rhs, 0);
2722 }
2723 else if (GET_CODE (rhs) == MULT
2724 && CONST_INT_P (XEXP (rhs, 1)))
2725 {
2726 negcoeff1 = wi::neg (rtx_mode_t (XEXP (rhs, 1), int_mode));
2727 rhs = XEXP (rhs, 0);
2728 }
2729 else if (GET_CODE (rhs) == ASHIFT
2730 && CONST_INT_P (XEXP (rhs, 1))
2731 && INTVAL (XEXP (rhs, 1)) >= 0
2732 && INTVAL (XEXP (rhs, 1)) < GET_MODE_PRECISION (int_mode))
2733 {
2734 negcoeff1 = wi::set_bit_in_zero (INTVAL (XEXP (rhs, 1)),
2735 GET_MODE_PRECISION (int_mode));
2736 negcoeff1 = -negcoeff1;
2737 rhs = XEXP (rhs, 0);
2738 }
2739
2740 if (rtx_equal_p (lhs, rhs))
2741 {
2742 rtx orig = gen_rtx_MINUS (int_mode, op0, op1);
2743 rtx coeff;
2744 bool speed = optimize_function_for_speed_p (cfun);
2745
2746 coeff = immed_wide_int_const (coeff0 + negcoeff1, int_mode);
2747
2748 tem = simplify_gen_binary (MULT, int_mode, lhs, coeff);
2749 return (set_src_cost (tem, int_mode, speed)
2750 <= set_src_cost (orig, int_mode, speed) ? tem : 0);
2751 }
2752 }
2753
2754 /* (a - (-b)) -> (a + b). True even for IEEE. */
2755 if (GET_CODE (op1) == NEG)
2756 return simplify_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
2757
2758 /* (-x - c) may be simplified as (-c - x). */
2759 if (GET_CODE (op0) == NEG
2760 && (CONST_SCALAR_INT_P (op1) || CONST_DOUBLE_AS_FLOAT_P (op1)))
2761 {
2762 tem = simplify_unary_operation (NEG, mode, op1, mode);
2763 if (tem)
2764 return simplify_gen_binary (MINUS, mode, tem, XEXP (op0, 0));
2765 }
2766
2767 if ((GET_CODE (op0) == CONST
2768 || GET_CODE (op0) == SYMBOL_REF
2769 || GET_CODE (op0) == LABEL_REF)
2770 && poly_int_rtx_p (op1, &offset))
2771 return plus_constant (mode, op0, trunc_int_for_mode (-offset, mode));
2772
2773 /* Don't let a relocatable value get a negative coeff. */
2774 if (poly_int_rtx_p (op1) && GET_MODE (op0) != VOIDmode)
2775 return simplify_gen_binary (PLUS, mode,
2776 op0,
2777 neg_poly_int_rtx (mode, op1));
2778
2779 /* (x - (x & y)) -> (x & ~y) */
2780 if (INTEGRAL_MODE_P (mode) && GET_CODE (op1) == AND)
2781 {
2782 if (rtx_equal_p (op0, XEXP (op1, 0)))
2783 {
2784 tem = simplify_gen_unary (NOT, mode, XEXP (op1, 1),
2785 GET_MODE (XEXP (op1, 1)));
2786 return simplify_gen_binary (AND, mode, op0, tem);
2787 }
2788 if (rtx_equal_p (op0, XEXP (op1, 1)))
2789 {
2790 tem = simplify_gen_unary (NOT, mode, XEXP (op1, 0),
2791 GET_MODE (XEXP (op1, 0)));
2792 return simplify_gen_binary (AND, mode, op0, tem);
2793 }
2794 }
2795
2796 /* If STORE_FLAG_VALUE is 1, (minus 1 (comparison foo bar)) can be done
2797 by reversing the comparison code if valid. */
2798 if (STORE_FLAG_VALUE == 1
2799 && trueop0 == const1_rtx
2800 && COMPARISON_P (op1)
2801 && (reversed = reversed_comparison (op1, mode)))
2802 return reversed;
2803
2804 /* Canonicalize (minus A (mult (neg B) C)) to (plus (mult B C) A). */
2805 if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2806 && GET_CODE (op1) == MULT
2807 && GET_CODE (XEXP (op1, 0)) == NEG)
2808 {
2809 rtx in1, in2;
2810
2811 in1 = XEXP (XEXP (op1, 0), 0);
2812 in2 = XEXP (op1, 1);
2813 return simplify_gen_binary (PLUS, mode,
2814 simplify_gen_binary (MULT, mode,
2815 in1, in2),
2816 op0);
2817 }
2818
2819 /* Canonicalize (minus (neg A) (mult B C)) to
2820 (minus (mult (neg B) C) A). */
2821 if (!HONOR_SIGN_DEPENDENT_ROUNDING (mode)
2822 && GET_CODE (op1) == MULT
2823 && GET_CODE (op0) == NEG)
2824 {
2825 rtx in1, in2;
2826
2827 in1 = simplify_gen_unary (NEG, mode, XEXP (op1, 0), mode);
2828 in2 = XEXP (op1, 1);
2829 return simplify_gen_binary (MINUS, mode,
2830 simplify_gen_binary (MULT, mode,
2831 in1, in2),
2832 XEXP (op0, 0));
2833 }
2834
2835 /* If one of the operands is a PLUS or a MINUS, see if we can
2836 simplify this by the associative law. This will, for example,
2837 canonicalize (minus A (plus B C)) to (minus (minus A B) C).
2838 Don't use the associative law for floating point.
2839 The inaccuracy makes it nonassociative,
2840 and subtle programs can break if operations are associated. */
2841
2842 if (INTEGRAL_MODE_P (mode)
2843 && (plus_minus_operand_p (op0)
2844 || plus_minus_operand_p (op1))
2845 && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
2846 return tem;
2847
2848 /* Handle vector series. */
2849 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
2850 {
2851 tem = simplify_binary_operation_series (code, mode, op0, op1);
2852 if (tem)
2853 return tem;
2854 }
2855 break;
2856
2857 case MULT:
2858 if (trueop1 == constm1_rtx)
2859 return simplify_gen_unary (NEG, mode, op0, mode);
2860
2861 if (GET_CODE (op0) == NEG)
2862 {
2863 rtx temp = simplify_unary_operation (NEG, mode, op1, mode);
2864 /* If op1 is a MULT as well and simplify_unary_operation
2865 just moved the NEG to the second operand, simplify_gen_binary
2866 below could through simplify_associative_operation move
2867 the NEG around again and recurse endlessly. */
2868 if (temp
2869 && GET_CODE (op1) == MULT
2870 && GET_CODE (temp) == MULT
2871 && XEXP (op1, 0) == XEXP (temp, 0)
2872 && GET_CODE (XEXP (temp, 1)) == NEG
2873 && XEXP (op1, 1) == XEXP (XEXP (temp, 1), 0))
2874 temp = NULL_RTX;
2875 if (temp)
2876 return simplify_gen_binary (MULT, mode, XEXP (op0, 0), temp);
2877 }
2878 if (GET_CODE (op1) == NEG)
2879 {
2880 rtx temp = simplify_unary_operation (NEG, mode, op0, mode);
2881 /* If op0 is a MULT as well and simplify_unary_operation
2882 just moved the NEG to the second operand, simplify_gen_binary
2883 below could through simplify_associative_operation move
2884 the NEG around again and recurse endlessly. */
2885 if (temp
2886 && GET_CODE (op0) == MULT
2887 && GET_CODE (temp) == MULT
2888 && XEXP (op0, 0) == XEXP (temp, 0)
2889 && GET_CODE (XEXP (temp, 1)) == NEG
2890 && XEXP (op0, 1) == XEXP (XEXP (temp, 1), 0))
2891 temp = NULL_RTX;
2892 if (temp)
2893 return simplify_gen_binary (MULT, mode, temp, XEXP (op1, 0));
2894 }
2895
2896 /* Maybe simplify x * 0 to 0. The reduction is not valid if
2897 x is NaN, since x * 0 is then also NaN. Nor is it valid
2898 when the mode has signed zeros, since multiplying a negative
2899 number by 0 will give -0, not 0. */
2900 if (!HONOR_NANS (mode)
2901 && !HONOR_SIGNED_ZEROS (mode)
2902 && trueop1 == CONST0_RTX (mode)
2903 && ! side_effects_p (op0))
2904 return op1;
2905
2906 /* In IEEE floating point, x*1 is not equivalent to x for
2907 signalling NaNs. */
2908 if (!HONOR_SNANS (mode)
2909 && trueop1 == CONST1_RTX (mode))
2910 return op0;
2911
2912 /* Convert multiply by constant power of two into shift. */
2913 if (CONST_SCALAR_INT_P (trueop1))
2914 {
2915 val = wi::exact_log2 (rtx_mode_t (trueop1, mode));
2916 if (val >= 0)
2917 return simplify_gen_binary (ASHIFT, mode, op0,
2918 gen_int_shift_amount (mode, val));
2919 }
2920
2921 /* x*2 is x+x and x*(-1) is -x */
2922 if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
2923 && SCALAR_FLOAT_MODE_P (GET_MODE (trueop1))
2924 && !DECIMAL_FLOAT_MODE_P (GET_MODE (trueop1))
2925 && GET_MODE (op0) == mode)
2926 {
2927 const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
2928
2929 if (real_equal (d1, &dconst2))
2930 return simplify_gen_binary (PLUS, mode, op0, copy_rtx (op0));
2931
2932 if (!HONOR_SNANS (mode)
2933 && real_equal (d1, &dconstm1))
2934 return simplify_gen_unary (NEG, mode, op0, mode);
2935 }
2936
2937 /* Optimize -x * -x as x * x. */
2938 if (FLOAT_MODE_P (mode)
2939 && GET_CODE (op0) == NEG
2940 && GET_CODE (op1) == NEG
2941 && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2942 && !side_effects_p (XEXP (op0, 0)))
2943 return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
2944
2945 /* Likewise, optimize abs(x) * abs(x) as x * x. */
2946 if (SCALAR_FLOAT_MODE_P (mode)
2947 && GET_CODE (op0) == ABS
2948 && GET_CODE (op1) == ABS
2949 && rtx_equal_p (XEXP (op0, 0), XEXP (op1, 0))
2950 && !side_effects_p (XEXP (op0, 0)))
2951 return simplify_gen_binary (MULT, mode, XEXP (op0, 0), XEXP (op1, 0));
2952
2953 /* Reassociate multiplication, but for floating point MULTs
2954 only when the user specifies unsafe math optimizations. */
2955 if (! FLOAT_MODE_P (mode)
2956 || flag_unsafe_math_optimizations)
2957 {
2958 tem = simplify_associative_operation (code, mode, op0, op1);
2959 if (tem)
2960 return tem;
2961 }
2962 break;
2963
2964 case IOR:
2965 if (trueop1 == CONST0_RTX (mode))
2966 return op0;
2967 if (INTEGRAL_MODE_P (mode)
2968 && trueop1 == CONSTM1_RTX (mode)
2969 && !side_effects_p (op0))
2970 return op1;
2971 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
2972 return op0;
2973 /* A | (~A) -> -1 */
2974 if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
2975 || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
2976 && ! side_effects_p (op0)
2977 && SCALAR_INT_MODE_P (mode))
2978 return constm1_rtx;
2979
2980 /* (ior A C) is C if all bits of A that might be nonzero are on in C. */
2981 if (CONST_INT_P (op1)
2982 && HWI_COMPUTABLE_MODE_P (mode)
2983 && (nonzero_bits (op0, mode) & ~UINTVAL (op1)) == 0
2984 && !side_effects_p (op0))
2985 return op1;
2986
2987 /* Canonicalize (X & C1) | C2. */
2988 if (GET_CODE (op0) == AND
2989 && CONST_INT_P (trueop1)
2990 && CONST_INT_P (XEXP (op0, 1)))
2991 {
2992 HOST_WIDE_INT mask = GET_MODE_MASK (mode);
2993 HOST_WIDE_INT c1 = INTVAL (XEXP (op0, 1));
2994 HOST_WIDE_INT c2 = INTVAL (trueop1);
2995
2996 /* If (C1&C2) == C1, then (X&C1)|C2 becomes C2. */
2997 if ((c1 & c2) == c1
2998 && !side_effects_p (XEXP (op0, 0)))
2999 return trueop1;
3000
3001 /* If (C1|C2) == ~0 then (X&C1)|C2 becomes X|C2. */
3002 if (((c1|c2) & mask) == mask)
3003 return simplify_gen_binary (IOR, mode, XEXP (op0, 0), op1);
3004 }
3005
3006 /* Convert (A & B) | A to A. */
3007 if (GET_CODE (op0) == AND
3008 && (rtx_equal_p (XEXP (op0, 0), op1)
3009 || rtx_equal_p (XEXP (op0, 1), op1))
3010 && ! side_effects_p (XEXP (op0, 0))
3011 && ! side_effects_p (XEXP (op0, 1)))
3012 return op1;
3013
3014 /* Convert (ior (ashift A CX) (lshiftrt A CY)) where CX+CY equals the
3015 mode size to (rotate A CX). */
3016
3017 if (GET_CODE (op1) == ASHIFT
3018 || GET_CODE (op1) == SUBREG)
3019 {
3020 opleft = op1;
3021 opright = op0;
3022 }
3023 else
3024 {
3025 opright = op1;
3026 opleft = op0;
3027 }
3028
3029 if (GET_CODE (opleft) == ASHIFT && GET_CODE (opright) == LSHIFTRT
3030 && rtx_equal_p (XEXP (opleft, 0), XEXP (opright, 0))
3031 && CONST_INT_P (XEXP (opleft, 1))
3032 && CONST_INT_P (XEXP (opright, 1))
3033 && (INTVAL (XEXP (opleft, 1)) + INTVAL (XEXP (opright, 1))
3034 == GET_MODE_UNIT_PRECISION (mode)))
3035 return gen_rtx_ROTATE (mode, XEXP (opright, 0), XEXP (opleft, 1));
3036
3037 /* Same, but for ashift that has been "simplified" to a wider mode
3038 by simplify_shift_const. */
3039
3040 if (GET_CODE (opleft) == SUBREG
3041 && is_a <scalar_int_mode> (mode, &int_mode)
3042 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (opleft)),
3043 &inner_mode)
3044 && GET_CODE (SUBREG_REG (opleft)) == ASHIFT
3045 && GET_CODE (opright) == LSHIFTRT
3046 && GET_CODE (XEXP (opright, 0)) == SUBREG
3047 && known_eq (SUBREG_BYTE (opleft), SUBREG_BYTE (XEXP (opright, 0)))
3048 && GET_MODE_SIZE (int_mode) < GET_MODE_SIZE (inner_mode)
3049 && rtx_equal_p (XEXP (SUBREG_REG (opleft), 0),
3050 SUBREG_REG (XEXP (opright, 0)))
3051 && CONST_INT_P (XEXP (SUBREG_REG (opleft), 1))
3052 && CONST_INT_P (XEXP (opright, 1))
3053 && (INTVAL (XEXP (SUBREG_REG (opleft), 1))
3054 + INTVAL (XEXP (opright, 1))
3055 == GET_MODE_PRECISION (int_mode)))
3056 return gen_rtx_ROTATE (int_mode, XEXP (opright, 0),
3057 XEXP (SUBREG_REG (opleft), 1));
3058
3059 /* If OP0 is (ashiftrt (plus ...) C), it might actually be
3060 a (sign_extend (plus ...)). Then check if OP1 is a CONST_INT and
3061 the PLUS does not affect any of the bits in OP1: then we can do
3062 the IOR as a PLUS and we can associate. This is valid if OP1
3063 can be safely shifted left C bits. */
3064 if (CONST_INT_P (trueop1) && GET_CODE (op0) == ASHIFTRT
3065 && GET_CODE (XEXP (op0, 0)) == PLUS
3066 && CONST_INT_P (XEXP (XEXP (op0, 0), 1))
3067 && CONST_INT_P (XEXP (op0, 1))
3068 && INTVAL (XEXP (op0, 1)) < HOST_BITS_PER_WIDE_INT)
3069 {
3070 int count = INTVAL (XEXP (op0, 1));
3071 HOST_WIDE_INT mask = UINTVAL (trueop1) << count;
3072
3073 if (mask >> count == INTVAL (trueop1)
3074 && trunc_int_for_mode (mask, mode) == mask
3075 && (mask & nonzero_bits (XEXP (op0, 0), mode)) == 0)
3076 return simplify_gen_binary (ASHIFTRT, mode,
3077 plus_constant (mode, XEXP (op0, 0),
3078 mask),
3079 XEXP (op0, 1));
3080 }
3081
3082 /* The following happens with bitfield merging.
3083 (X & C) | ((X | Y) & ~C) -> X | (Y & ~C) */
3084 if (GET_CODE (op0) == AND
3085 && GET_CODE (op1) == AND
3086 && CONST_INT_P (XEXP (op0, 1))
3087 && CONST_INT_P (XEXP (op1, 1))
3088 && (INTVAL (XEXP (op0, 1))
3089 == ~INTVAL (XEXP (op1, 1))))
3090 {
3091 /* The IOR may be on both sides. */
3092 rtx top0 = NULL_RTX, top1 = NULL_RTX;
3093 if (GET_CODE (XEXP (op1, 0)) == IOR)
3094 top0 = op0, top1 = op1;
3095 else if (GET_CODE (XEXP (op0, 0)) == IOR)
3096 top0 = op1, top1 = op0;
3097 if (top0 && top1)
3098 {
3099 /* X may be on either side of the inner IOR. */
3100 rtx tem = NULL_RTX;
3101 if (rtx_equal_p (XEXP (top0, 0),
3102 XEXP (XEXP (top1, 0), 0)))
3103 tem = XEXP (XEXP (top1, 0), 1);
3104 else if (rtx_equal_p (XEXP (top0, 0),
3105 XEXP (XEXP (top1, 0), 1)))
3106 tem = XEXP (XEXP (top1, 0), 0);
3107 if (tem)
3108 return simplify_gen_binary (IOR, mode, XEXP (top0, 0),
3109 simplify_gen_binary
3110 (AND, mode, tem, XEXP (top1, 1)));
3111 }
3112 }
3113
3114 tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3115 if (tem)
3116 return tem;
3117
3118 tem = simplify_associative_operation (code, mode, op0, op1);
3119 if (tem)
3120 return tem;
3121
3122 tem = simplify_logical_relational_operation (code, mode, op0, op1);
3123 if (tem)
3124 return tem;
3125 break;
3126
3127 case XOR:
3128 if (trueop1 == CONST0_RTX (mode))
3129 return op0;
3130 if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
3131 return simplify_gen_unary (NOT, mode, op0, mode);
3132 if (rtx_equal_p (trueop0, trueop1)
3133 && ! side_effects_p (op0)
3134 && GET_MODE_CLASS (mode) != MODE_CC)
3135 return CONST0_RTX (mode);
3136
3137 /* Canonicalize XOR of the most significant bit to PLUS. */
3138 if (CONST_SCALAR_INT_P (op1)
3139 && mode_signbit_p (mode, op1))
3140 return simplify_gen_binary (PLUS, mode, op0, op1);
3141 /* (xor (plus X C1) C2) is (xor X (C1^C2)) if C1 is signbit. */
3142 if (CONST_SCALAR_INT_P (op1)
3143 && GET_CODE (op0) == PLUS
3144 && CONST_SCALAR_INT_P (XEXP (op0, 1))
3145 && mode_signbit_p (mode, XEXP (op0, 1)))
3146 return simplify_gen_binary (XOR, mode, XEXP (op0, 0),
3147 simplify_gen_binary (XOR, mode, op1,
3148 XEXP (op0, 1)));
3149
3150 /* If we are XORing two things that have no bits in common,
3151 convert them into an IOR. This helps to detect rotation encoded
3152 using those methods and possibly other simplifications. */
3153
3154 if (HWI_COMPUTABLE_MODE_P (mode)
3155 && (nonzero_bits (op0, mode)
3156 & nonzero_bits (op1, mode)) == 0)
3157 return (simplify_gen_binary (IOR, mode, op0, op1));
3158
3159 /* Convert (XOR (NOT x) (NOT y)) to (XOR x y).
3160 Also convert (XOR (NOT x) y) to (NOT (XOR x y)), similarly for
3161 (NOT y). */
3162 {
3163 int num_negated = 0;
3164
3165 if (GET_CODE (op0) == NOT)
3166 num_negated++, op0 = XEXP (op0, 0);
3167 if (GET_CODE (op1) == NOT)
3168 num_negated++, op1 = XEXP (op1, 0);
3169
3170 if (num_negated == 2)
3171 return simplify_gen_binary (XOR, mode, op0, op1);
3172 else if (num_negated == 1)
3173 return simplify_gen_unary (NOT, mode,
3174 simplify_gen_binary (XOR, mode, op0, op1),
3175 mode);
3176 }
3177
3178 /* Convert (xor (and A B) B) to (and (not A) B). The latter may
3179 correspond to a machine insn or result in further simplifications
3180 if B is a constant. */
3181
3182 if (GET_CODE (op0) == AND
3183 && rtx_equal_p (XEXP (op0, 1), op1)
3184 && ! side_effects_p (op1))
3185 return simplify_gen_binary (AND, mode,
3186 simplify_gen_unary (NOT, mode,
3187 XEXP (op0, 0), mode),
3188 op1);
3189
3190 else if (GET_CODE (op0) == AND
3191 && rtx_equal_p (XEXP (op0, 0), op1)
3192 && ! side_effects_p (op1))
3193 return simplify_gen_binary (AND, mode,
3194 simplify_gen_unary (NOT, mode,
3195 XEXP (op0, 1), mode),
3196 op1);
3197
3198 /* Given (xor (ior (xor A B) C) D), where B, C and D are
3199 constants, simplify to (xor (ior A C) (B&~C)^D), canceling
3200 out bits inverted twice and not set by C. Similarly, given
3201 (xor (and (xor A B) C) D), simplify without inverting C in
3202 the xor operand: (xor (and A C) (B&C)^D).
3203 */
3204 else if ((GET_CODE (op0) == IOR || GET_CODE (op0) == AND)
3205 && GET_CODE (XEXP (op0, 0)) == XOR
3206 && CONST_INT_P (op1)
3207 && CONST_INT_P (XEXP (op0, 1))
3208 && CONST_INT_P (XEXP (XEXP (op0, 0), 1)))
3209 {
3210 enum rtx_code op = GET_CODE (op0);
3211 rtx a = XEXP (XEXP (op0, 0), 0);
3212 rtx b = XEXP (XEXP (op0, 0), 1);
3213 rtx c = XEXP (op0, 1);
3214 rtx d = op1;
3215 HOST_WIDE_INT bval = INTVAL (b);
3216 HOST_WIDE_INT cval = INTVAL (c);
3217 HOST_WIDE_INT dval = INTVAL (d);
3218 HOST_WIDE_INT xcval;
3219
3220 if (op == IOR)
3221 xcval = ~cval;
3222 else
3223 xcval = cval;
3224
3225 return simplify_gen_binary (XOR, mode,
3226 simplify_gen_binary (op, mode, a, c),
3227 gen_int_mode ((bval & xcval) ^ dval,
3228 mode));
3229 }
3230
3231 /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P),
3232 we can transform like this:
3233 (A&B)^C == ~(A&B)&C | ~C&(A&B)
3234 == (~A|~B)&C | ~C&(A&B) * DeMorgan's Law
3235 == ~A&C | ~B&C | A&(~C&B) * Distribute and re-order
3236 Attempt a few simplifications when B and C are both constants. */
3237 if (GET_CODE (op0) == AND
3238 && CONST_INT_P (op1)
3239 && CONST_INT_P (XEXP (op0, 1)))
3240 {
3241 rtx a = XEXP (op0, 0);
3242 rtx b = XEXP (op0, 1);
3243 rtx c = op1;
3244 HOST_WIDE_INT bval = INTVAL (b);
3245 HOST_WIDE_INT cval = INTVAL (c);
3246
3247 /* Instead of computing ~A&C, we compute its negated value,
3248 ~(A|~C). If it yields -1, ~A&C is zero, so we can
3249 optimize for sure. If it does not simplify, we still try
3250 to compute ~A&C below, but since that always allocates
3251 RTL, we don't try that before committing to returning a
3252 simplified expression. */
3253 rtx n_na_c = simplify_binary_operation (IOR, mode, a,
3254 GEN_INT (~cval));
3255
3256 if ((~cval & bval) == 0)
3257 {
3258 rtx na_c = NULL_RTX;
3259 if (n_na_c)
3260 na_c = simplify_gen_unary (NOT, mode, n_na_c, mode);
3261 else
3262 {
3263 /* If ~A does not simplify, don't bother: we don't
3264 want to simplify 2 operations into 3, and if na_c
3265 were to simplify with na, n_na_c would have
3266 simplified as well. */
3267 rtx na = simplify_unary_operation (NOT, mode, a, mode);
3268 if (na)
3269 na_c = simplify_gen_binary (AND, mode, na, c);
3270 }
3271
3272 /* Try to simplify ~A&C | ~B&C. */
3273 if (na_c != NULL_RTX)
3274 return simplify_gen_binary (IOR, mode, na_c,
3275 gen_int_mode (~bval & cval, mode));
3276 }
3277 else
3278 {
3279 /* If ~A&C is zero, simplify A&(~C&B) | ~B&C. */
3280 if (n_na_c == CONSTM1_RTX (mode))
3281 {
3282 rtx a_nc_b = simplify_gen_binary (AND, mode, a,
3283 gen_int_mode (~cval & bval,
3284 mode));
3285 return simplify_gen_binary (IOR, mode, a_nc_b,
3286 gen_int_mode (~bval & cval,
3287 mode));
3288 }
3289 }
3290 }
3291
3292 /* If we have (xor (and (xor A B) C) A) with C a constant we can instead
3293 do (ior (and A ~C) (and B C)) which is a machine instruction on some
3294 machines, and also has shorter instruction path length. */
3295 if (GET_CODE (op0) == AND
3296 && GET_CODE (XEXP (op0, 0)) == XOR
3297 && CONST_INT_P (XEXP (op0, 1))
3298 && rtx_equal_p (XEXP (XEXP (op0, 0), 0), trueop1))
3299 {
3300 rtx a = trueop1;
3301 rtx b = XEXP (XEXP (op0, 0), 1);
3302 rtx c = XEXP (op0, 1);
3303 rtx nc = simplify_gen_unary (NOT, mode, c, mode);
3304 rtx a_nc = simplify_gen_binary (AND, mode, a, nc);
3305 rtx bc = simplify_gen_binary (AND, mode, b, c);
3306 return simplify_gen_binary (IOR, mode, a_nc, bc);
3307 }
3308 /* Similarly, (xor (and (xor A B) C) B) as (ior (and A C) (and B ~C)) */
3309 else if (GET_CODE (op0) == AND
3310 && GET_CODE (XEXP (op0, 0)) == XOR
3311 && CONST_INT_P (XEXP (op0, 1))
3312 && rtx_equal_p (XEXP (XEXP (op0, 0), 1), trueop1))
3313 {
3314 rtx a = XEXP (XEXP (op0, 0), 0);
3315 rtx b = trueop1;
3316 rtx c = XEXP (op0, 1);
3317 rtx nc = simplify_gen_unary (NOT, mode, c, mode);
3318 rtx b_nc = simplify_gen_binary (AND, mode, b, nc);
3319 rtx ac = simplify_gen_binary (AND, mode, a, c);
3320 return simplify_gen_binary (IOR, mode, ac, b_nc);
3321 }
3322
3323 /* (xor (comparison foo bar) (const_int 1)) can become the reversed
3324 comparison if STORE_FLAG_VALUE is 1. */
3325 if (STORE_FLAG_VALUE == 1
3326 && trueop1 == const1_rtx
3327 && COMPARISON_P (op0)
3328 && (reversed = reversed_comparison (op0, mode)))
3329 return reversed;
3330
3331 /* (lshiftrt foo C) where C is the number of bits in FOO minus 1
3332 is (lt foo (const_int 0)), so we can perform the above
3333 simplification if STORE_FLAG_VALUE is 1. */
3334
3335 if (is_a <scalar_int_mode> (mode, &int_mode)
3336 && STORE_FLAG_VALUE == 1
3337 && trueop1 == const1_rtx
3338 && GET_CODE (op0) == LSHIFTRT
3339 && CONST_INT_P (XEXP (op0, 1))
3340 && INTVAL (XEXP (op0, 1)) == GET_MODE_PRECISION (int_mode) - 1)
3341 return gen_rtx_GE (int_mode, XEXP (op0, 0), const0_rtx);
3342
3343 /* (xor (comparison foo bar) (const_int sign-bit))
3344 when STORE_FLAG_VALUE is the sign bit. */
3345 if (is_a <scalar_int_mode> (mode, &int_mode)
3346 && val_signbit_p (int_mode, STORE_FLAG_VALUE)
3347 && trueop1 == const_true_rtx
3348 && COMPARISON_P (op0)
3349 && (reversed = reversed_comparison (op0, int_mode)))
3350 return reversed;
3351
3352 tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3353 if (tem)
3354 return tem;
3355
3356 tem = simplify_associative_operation (code, mode, op0, op1);
3357 if (tem)
3358 return tem;
3359 break;
3360
3361 case AND:
3362 if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
3363 return trueop1;
3364 if (INTEGRAL_MODE_P (mode) && trueop1 == CONSTM1_RTX (mode))
3365 return op0;
3366 if (HWI_COMPUTABLE_MODE_P (mode))
3367 {
3368 HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, mode);
3369 HOST_WIDE_INT nzop1;
3370 if (CONST_INT_P (trueop1))
3371 {
3372 HOST_WIDE_INT val1 = INTVAL (trueop1);
3373 /* If we are turning off bits already known off in OP0, we need
3374 not do an AND. */
3375 if ((nzop0 & ~val1) == 0)
3376 return op0;
3377 }
3378 nzop1 = nonzero_bits (trueop1, mode);
3379 /* If we are clearing all the nonzero bits, the result is zero. */
3380 if ((nzop1 & nzop0) == 0
3381 && !side_effects_p (op0) && !side_effects_p (op1))
3382 return CONST0_RTX (mode);
3383 }
3384 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
3385 && GET_MODE_CLASS (mode) != MODE_CC)
3386 return op0;
3387 /* A & (~A) -> 0 */
3388 if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
3389 || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
3390 && ! side_effects_p (op0)
3391 && GET_MODE_CLASS (mode) != MODE_CC)
3392 return CONST0_RTX (mode);
3393
3394 /* Transform (and (extend X) C) into (zero_extend (and X C)) if
3395 there are no nonzero bits of C outside of X's mode. */
3396 if ((GET_CODE (op0) == SIGN_EXTEND
3397 || GET_CODE (op0) == ZERO_EXTEND)
3398 && CONST_INT_P (trueop1)
3399 && HWI_COMPUTABLE_MODE_P (mode)
3400 && (~GET_MODE_MASK (GET_MODE (XEXP (op0, 0)))
3401 & UINTVAL (trueop1)) == 0)
3402 {
3403 machine_mode imode = GET_MODE (XEXP (op0, 0));
3404 tem = simplify_gen_binary (AND, imode, XEXP (op0, 0),
3405 gen_int_mode (INTVAL (trueop1),
3406 imode));
3407 return simplify_gen_unary (ZERO_EXTEND, mode, tem, imode);
3408 }
3409
3410 /* Transform (and (truncate X) C) into (truncate (and X C)). This way
3411 we might be able to further simplify the AND with X and potentially
3412 remove the truncation altogether. */
3413 if (GET_CODE (op0) == TRUNCATE && CONST_INT_P (trueop1))
3414 {
3415 rtx x = XEXP (op0, 0);
3416 machine_mode xmode = GET_MODE (x);
3417 tem = simplify_gen_binary (AND, xmode, x,
3418 gen_int_mode (INTVAL (trueop1), xmode));
3419 return simplify_gen_unary (TRUNCATE, mode, tem, xmode);
3420 }
3421
3422 /* Canonicalize (A | C1) & C2 as (A & C2) | (C1 & C2). */
3423 if (GET_CODE (op0) == IOR
3424 && CONST_INT_P (trueop1)
3425 && CONST_INT_P (XEXP (op0, 1)))
3426 {
3427 HOST_WIDE_INT tmp = INTVAL (trueop1) & INTVAL (XEXP (op0, 1));
3428 return simplify_gen_binary (IOR, mode,
3429 simplify_gen_binary (AND, mode,
3430 XEXP (op0, 0), op1),
3431 gen_int_mode (tmp, mode));
3432 }
3433
3434 /* Convert (A ^ B) & A to A & (~B) since the latter is often a single
3435 insn (and may simplify more). */
3436 if (GET_CODE (op0) == XOR
3437 && rtx_equal_p (XEXP (op0, 0), op1)
3438 && ! side_effects_p (op1))
3439 return simplify_gen_binary (AND, mode,
3440 simplify_gen_unary (NOT, mode,
3441 XEXP (op0, 1), mode),
3442 op1);
3443
3444 if (GET_CODE (op0) == XOR
3445 && rtx_equal_p (XEXP (op0, 1), op1)
3446 && ! side_effects_p (op1))
3447 return simplify_gen_binary (AND, mode,
3448 simplify_gen_unary (NOT, mode,
3449 XEXP (op0, 0), mode),
3450 op1);
3451
3452 /* Similarly for (~(A ^ B)) & A. */
3453 if (GET_CODE (op0) == NOT
3454 && GET_CODE (XEXP (op0, 0)) == XOR
3455 && rtx_equal_p (XEXP (XEXP (op0, 0), 0), op1)
3456 && ! side_effects_p (op1))
3457 return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 1), op1);
3458
3459 if (GET_CODE (op0) == NOT
3460 && GET_CODE (XEXP (op0, 0)) == XOR
3461 && rtx_equal_p (XEXP (XEXP (op0, 0), 1), op1)
3462 && ! side_effects_p (op1))
3463 return simplify_gen_binary (AND, mode, XEXP (XEXP (op0, 0), 0), op1);
3464
3465 /* Convert (A | B) & A to A. */
3466 if (GET_CODE (op0) == IOR
3467 && (rtx_equal_p (XEXP (op0, 0), op1)
3468 || rtx_equal_p (XEXP (op0, 1), op1))
3469 && ! side_effects_p (XEXP (op0, 0))
3470 && ! side_effects_p (XEXP (op0, 1)))
3471 return op1;
3472
3473 /* For constants M and N, if M == (1LL << cst) - 1 && (N & M) == M,
3474 ((A & N) + B) & M -> (A + B) & M
3475 Similarly if (N & M) == 0,
3476 ((A | N) + B) & M -> (A + B) & M
3477 and for - instead of + and/or ^ instead of |.
3478 Also, if (N & M) == 0, then
3479 (A +- N) & M -> A & M. */
3480 if (CONST_INT_P (trueop1)
3481 && HWI_COMPUTABLE_MODE_P (mode)
3482 && ~UINTVAL (trueop1)
3483 && (UINTVAL (trueop1) & (UINTVAL (trueop1) + 1)) == 0
3484 && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS))
3485 {
3486 rtx pmop[2];
3487 int which;
3488
3489 pmop[0] = XEXP (op0, 0);
3490 pmop[1] = XEXP (op0, 1);
3491
3492 if (CONST_INT_P (pmop[1])
3493 && (UINTVAL (pmop[1]) & UINTVAL (trueop1)) == 0)
3494 return simplify_gen_binary (AND, mode, pmop[0], op1);
3495
3496 for (which = 0; which < 2; which++)
3497 {
3498 tem = pmop[which];
3499 switch (GET_CODE (tem))
3500 {
3501 case AND:
3502 if (CONST_INT_P (XEXP (tem, 1))
3503 && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1))
3504 == UINTVAL (trueop1))
3505 pmop[which] = XEXP (tem, 0);
3506 break;
3507 case IOR:
3508 case XOR:
3509 if (CONST_INT_P (XEXP (tem, 1))
3510 && (UINTVAL (XEXP (tem, 1)) & UINTVAL (trueop1)) == 0)
3511 pmop[which] = XEXP (tem, 0);
3512 break;
3513 default:
3514 break;
3515 }
3516 }
3517
3518 if (pmop[0] != XEXP (op0, 0) || pmop[1] != XEXP (op0, 1))
3519 {
3520 tem = simplify_gen_binary (GET_CODE (op0), mode,
3521 pmop[0], pmop[1]);
3522 return simplify_gen_binary (code, mode, tem, op1);
3523 }
3524 }
3525
3526 /* (and X (ior (not X) Y) -> (and X Y) */
3527 if (GET_CODE (op1) == IOR
3528 && GET_CODE (XEXP (op1, 0)) == NOT
3529 && rtx_equal_p (op0, XEXP (XEXP (op1, 0), 0)))
3530 return simplify_gen_binary (AND, mode, op0, XEXP (op1, 1));
3531
3532 /* (and (ior (not X) Y) X) -> (and X Y) */
3533 if (GET_CODE (op0) == IOR
3534 && GET_CODE (XEXP (op0, 0)) == NOT
3535 && rtx_equal_p (op1, XEXP (XEXP (op0, 0), 0)))
3536 return simplify_gen_binary (AND, mode, op1, XEXP (op0, 1));
3537
3538 /* (and X (ior Y (not X)) -> (and X Y) */
3539 if (GET_CODE (op1) == IOR
3540 && GET_CODE (XEXP (op1, 1)) == NOT
3541 && rtx_equal_p (op0, XEXP (XEXP (op1, 1), 0)))
3542 return simplify_gen_binary (AND, mode, op0, XEXP (op1, 0));
3543
3544 /* (and (ior Y (not X)) X) -> (and X Y) */
3545 if (GET_CODE (op0) == IOR
3546 && GET_CODE (XEXP (op0, 1)) == NOT
3547 && rtx_equal_p (op1, XEXP (XEXP (op0, 1), 0)))
3548 return simplify_gen_binary (AND, mode, op1, XEXP (op0, 0));
3549
3550 tem = simplify_byte_swapping_operation (code, mode, op0, op1);
3551 if (tem)
3552 return tem;
3553
3554 tem = simplify_associative_operation (code, mode, op0, op1);
3555 if (tem)
3556 return tem;
3557 break;
3558
3559 case UDIV:
3560 /* 0/x is 0 (or x&0 if x has side-effects). */
3561 if (trueop0 == CONST0_RTX (mode)
3562 && !cfun->can_throw_non_call_exceptions)
3563 {
3564 if (side_effects_p (op1))
3565 return simplify_gen_binary (AND, mode, op1, trueop0);
3566 return trueop0;
3567 }
3568 /* x/1 is x. */
3569 if (trueop1 == CONST1_RTX (mode))
3570 {
3571 tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
3572 if (tem)
3573 return tem;
3574 }
3575 /* Convert divide by power of two into shift. */
3576 if (CONST_INT_P (trueop1)
3577 && (val = exact_log2 (UINTVAL (trueop1))) > 0)
3578 return simplify_gen_binary (LSHIFTRT, mode, op0,
3579 gen_int_shift_amount (mode, val));
3580 break;
3581
3582 case DIV:
3583 /* Handle floating point and integers separately. */
3584 if (SCALAR_FLOAT_MODE_P (mode))
3585 {
3586 /* Maybe change 0.0 / x to 0.0. This transformation isn't
3587 safe for modes with NaNs, since 0.0 / 0.0 will then be
3588 NaN rather than 0.0. Nor is it safe for modes with signed
3589 zeros, since dividing 0 by a negative number gives -0.0 */
3590 if (trueop0 == CONST0_RTX (mode)
3591 && !HONOR_NANS (mode)
3592 && !HONOR_SIGNED_ZEROS (mode)
3593 && ! side_effects_p (op1))
3594 return op0;
3595 /* x/1.0 is x. */
3596 if (trueop1 == CONST1_RTX (mode)
3597 && !HONOR_SNANS (mode))
3598 return op0;
3599
3600 if (CONST_DOUBLE_AS_FLOAT_P (trueop1)
3601 && trueop1 != CONST0_RTX (mode))
3602 {
3603 const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
3604
3605 /* x/-1.0 is -x. */
3606 if (real_equal (d1, &dconstm1)
3607 && !HONOR_SNANS (mode))
3608 return simplify_gen_unary (NEG, mode, op0, mode);
3609
3610 /* Change FP division by a constant into multiplication.
3611 Only do this with -freciprocal-math. */
3612 if (flag_reciprocal_math
3613 && !real_equal (d1, &dconst0))
3614 {
3615 REAL_VALUE_TYPE d;
3616 real_arithmetic (&d, RDIV_EXPR, &dconst1, d1);
3617 tem = const_double_from_real_value (d, mode);
3618 return simplify_gen_binary (MULT, mode, op0, tem);
3619 }
3620 }
3621 }
3622 else if (SCALAR_INT_MODE_P (mode))
3623 {
3624 /* 0/x is 0 (or x&0 if x has side-effects). */
3625 if (trueop0 == CONST0_RTX (mode)
3626 && !cfun->can_throw_non_call_exceptions)
3627 {
3628 if (side_effects_p (op1))
3629 return simplify_gen_binary (AND, mode, op1, trueop0);
3630 return trueop0;
3631 }
3632 /* x/1 is x. */
3633 if (trueop1 == CONST1_RTX (mode))
3634 {
3635 tem = rtl_hooks.gen_lowpart_no_emit (mode, op0);
3636 if (tem)
3637 return tem;
3638 }
3639 /* x/-1 is -x. */
3640 if (trueop1 == constm1_rtx)
3641 {
3642 rtx x = rtl_hooks.gen_lowpart_no_emit (mode, op0);
3643 if (x)
3644 return simplify_gen_unary (NEG, mode, x, mode);
3645 }
3646 }
3647 break;
3648
3649 case UMOD:
3650 /* 0%x is 0 (or x&0 if x has side-effects). */
3651 if (trueop0 == CONST0_RTX (mode))
3652 {
3653 if (side_effects_p (op1))
3654 return simplify_gen_binary (AND, mode, op1, trueop0);
3655 return trueop0;
3656 }
3657 /* x%1 is 0 (of x&0 if x has side-effects). */
3658 if (trueop1 == CONST1_RTX (mode))
3659 {
3660 if (side_effects_p (op0))
3661 return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
3662 return CONST0_RTX (mode);
3663 }
3664 /* Implement modulus by power of two as AND. */
3665 if (CONST_INT_P (trueop1)
3666 && exact_log2 (UINTVAL (trueop1)) > 0)
3667 return simplify_gen_binary (AND, mode, op0,
3668 gen_int_mode (UINTVAL (trueop1) - 1,
3669 mode));
3670 break;
3671
3672 case MOD:
3673 /* 0%x is 0 (or x&0 if x has side-effects). */
3674 if (trueop0 == CONST0_RTX (mode))
3675 {
3676 if (side_effects_p (op1))
3677 return simplify_gen_binary (AND, mode, op1, trueop0);
3678 return trueop0;
3679 }
3680 /* x%1 and x%-1 is 0 (or x&0 if x has side-effects). */
3681 if (trueop1 == CONST1_RTX (mode) || trueop1 == constm1_rtx)
3682 {
3683 if (side_effects_p (op0))
3684 return simplify_gen_binary (AND, mode, op0, CONST0_RTX (mode));
3685 return CONST0_RTX (mode);
3686 }
3687 break;
3688
3689 case ROTATERT:
3690 case ROTATE:
3691 /* Canonicalize rotates by constant amount. If op1 is bitsize / 2,
3692 prefer left rotation, if op1 is from bitsize / 2 + 1 to
3693 bitsize - 1, use other direction of rotate with 1 .. bitsize / 2 - 1
3694 amount instead. */
3695 #if defined(HAVE_rotate) && defined(HAVE_rotatert)
3696 if (CONST_INT_P (trueop1)
3697 && IN_RANGE (INTVAL (trueop1),
3698 GET_MODE_UNIT_PRECISION (mode) / 2 + (code == ROTATE),
3699 GET_MODE_UNIT_PRECISION (mode) - 1))
3700 {
3701 int new_amount = GET_MODE_UNIT_PRECISION (mode) - INTVAL (trueop1);
3702 rtx new_amount_rtx = gen_int_shift_amount (mode, new_amount);
3703 return simplify_gen_binary (code == ROTATE ? ROTATERT : ROTATE,
3704 mode, op0, new_amount_rtx);
3705 }
3706 #endif
3707 /* FALLTHRU */
3708 case ASHIFTRT:
3709 if (trueop1 == CONST0_RTX (mode))
3710 return op0;
3711 if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
3712 return op0;
3713 /* Rotating ~0 always results in ~0. */
3714 if (CONST_INT_P (trueop0)
3715 && HWI_COMPUTABLE_MODE_P (mode)
3716 && UINTVAL (trueop0) == GET_MODE_MASK (mode)
3717 && ! side_effects_p (op1))
3718 return op0;
3719
3720 canonicalize_shift:
3721 /* Given:
3722 scalar modes M1, M2
3723 scalar constants c1, c2
3724 size (M2) > size (M1)
3725 c1 == size (M2) - size (M1)
3726 optimize:
3727 ([a|l]shiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int <c1>))
3728 <low_part>)
3729 (const_int <c2>))
3730 to:
3731 (subreg:M1 ([a|l]shiftrt:M2 (reg:M2) (const_int <c1 + c2>))
3732 <low_part>). */
3733 if ((code == ASHIFTRT || code == LSHIFTRT)
3734 && is_a <scalar_int_mode> (mode, &int_mode)
3735 && SUBREG_P (op0)
3736 && CONST_INT_P (op1)
3737 && GET_CODE (SUBREG_REG (op0)) == LSHIFTRT
3738 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (op0)),
3739 &inner_mode)
3740 && CONST_INT_P (XEXP (SUBREG_REG (op0), 1))
3741 && GET_MODE_BITSIZE (inner_mode) > GET_MODE_BITSIZE (int_mode)
3742 && (INTVAL (XEXP (SUBREG_REG (op0), 1))
3743 == GET_MODE_BITSIZE (inner_mode) - GET_MODE_BITSIZE (int_mode))
3744 && subreg_lowpart_p (op0))
3745 {
3746 rtx tmp = gen_int_shift_amount
3747 (inner_mode, INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (op1));
3748
3749 /* Combine would usually zero out the value when combining two
3750 local shifts and the range becomes larger or equal to the mode.
3751 However since we fold away one of the shifts here combine won't
3752 see it so we should immediately zero the result if it's out of
3753 range. */
3754 if (code == LSHIFTRT
3755 && INTVAL (tmp) >= GET_MODE_BITSIZE (inner_mode))
3756 tmp = const0_rtx;
3757 else
3758 tmp = simplify_gen_binary (code,
3759 inner_mode,
3760 XEXP (SUBREG_REG (op0), 0),
3761 tmp);
3762
3763 return lowpart_subreg (int_mode, tmp, inner_mode);
3764 }
3765
3766 if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
3767 {
3768 val = INTVAL (op1) & (GET_MODE_UNIT_PRECISION (mode) - 1);
3769 if (val != INTVAL (op1))
3770 return simplify_gen_binary (code, mode, op0,
3771 gen_int_shift_amount (mode, val));
3772 }
3773 break;
3774
3775 case ASHIFT:
3776 case SS_ASHIFT:
3777 case US_ASHIFT:
3778 if (trueop1 == CONST0_RTX (mode))
3779 return op0;
3780 if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
3781 return op0;
3782 goto canonicalize_shift;
3783
3784 case LSHIFTRT:
3785 if (trueop1 == CONST0_RTX (mode))
3786 return op0;
3787 if (trueop0 == CONST0_RTX (mode) && ! side_effects_p (op1))
3788 return op0;
3789 /* Optimize (lshiftrt (clz X) C) as (eq X 0). */
3790 if (GET_CODE (op0) == CLZ
3791 && is_a <scalar_int_mode> (GET_MODE (XEXP (op0, 0)), &inner_mode)
3792 && CONST_INT_P (trueop1)
3793 && STORE_FLAG_VALUE == 1
3794 && INTVAL (trueop1) < GET_MODE_UNIT_PRECISION (mode))
3795 {
3796 unsigned HOST_WIDE_INT zero_val = 0;
3797
3798 if (CLZ_DEFINED_VALUE_AT_ZERO (inner_mode, zero_val)
3799 && zero_val == GET_MODE_PRECISION (inner_mode)
3800 && INTVAL (trueop1) == exact_log2 (zero_val))
3801 return simplify_gen_relational (EQ, mode, inner_mode,
3802 XEXP (op0, 0), const0_rtx);
3803 }
3804 goto canonicalize_shift;
3805
3806 case SMIN:
3807 if (HWI_COMPUTABLE_MODE_P (mode)
3808 && mode_signbit_p (mode, trueop1)
3809 && ! side_effects_p (op0))
3810 return op1;
3811 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
3812 return op0;
3813 tem = simplify_associative_operation (code, mode, op0, op1);
3814 if (tem)
3815 return tem;
3816 break;
3817
3818 case SMAX:
3819 if (HWI_COMPUTABLE_MODE_P (mode)
3820 && CONST_INT_P (trueop1)
3821 && (UINTVAL (trueop1) == GET_MODE_MASK (mode) >> 1)
3822 && ! side_effects_p (op0))
3823 return op1;
3824 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
3825 return op0;
3826 tem = simplify_associative_operation (code, mode, op0, op1);
3827 if (tem)
3828 return tem;
3829 break;
3830
3831 case UMIN:
3832 if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
3833 return op1;
3834 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
3835 return op0;
3836 tem = simplify_associative_operation (code, mode, op0, op1);
3837 if (tem)
3838 return tem;
3839 break;
3840
3841 case UMAX:
3842 if (trueop1 == constm1_rtx && ! side_effects_p (op0))
3843 return op1;
3844 if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0))
3845 return op0;
3846 tem = simplify_associative_operation (code, mode, op0, op1);
3847 if (tem)
3848 return tem;
3849 break;
3850
3851 case SS_PLUS:
3852 case US_PLUS:
3853 case SS_MINUS:
3854 case US_MINUS:
3855 case SS_MULT:
3856 case US_MULT:
3857 case SS_DIV:
3858 case US_DIV:
3859 /* ??? There are simplifications that can be done. */
3860 return 0;
3861
3862 case VEC_SERIES:
3863 if (op1 == CONST0_RTX (GET_MODE_INNER (mode)))
3864 return gen_vec_duplicate (mode, op0);
3865 if (valid_for_const_vector_p (mode, op0)
3866 && valid_for_const_vector_p (mode, op1))
3867 return gen_const_vec_series (mode, op0, op1);
3868 return 0;
3869
3870 case VEC_SELECT:
3871 if (!VECTOR_MODE_P (mode))
3872 {
3873 gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
3874 gcc_assert (mode == GET_MODE_INNER (GET_MODE (trueop0)));
3875 gcc_assert (GET_CODE (trueop1) == PARALLEL);
3876 gcc_assert (XVECLEN (trueop1, 0) == 1);
3877
3878 /* We can't reason about selections made at runtime. */
3879 if (!CONST_INT_P (XVECEXP (trueop1, 0, 0)))
3880 return 0;
3881
3882 if (vec_duplicate_p (trueop0, &elt0))
3883 return elt0;
3884
3885 if (GET_CODE (trueop0) == CONST_VECTOR)
3886 return CONST_VECTOR_ELT (trueop0, INTVAL (XVECEXP
3887 (trueop1, 0, 0)));
3888
3889 /* Extract a scalar element from a nested VEC_SELECT expression
3890 (with optional nested VEC_CONCAT expression). Some targets
3891 (i386) extract scalar element from a vector using chain of
3892 nested VEC_SELECT expressions. When input operand is a memory
3893 operand, this operation can be simplified to a simple scalar
3894 load from an offseted memory address. */
3895 int n_elts;
3896 if (GET_CODE (trueop0) == VEC_SELECT
3897 && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
3898 .is_constant (&n_elts)))
3899 {
3900 rtx op0 = XEXP (trueop0, 0);
3901 rtx op1 = XEXP (trueop0, 1);
3902
3903 int i = INTVAL (XVECEXP (trueop1, 0, 0));
3904 int elem;
3905
3906 rtvec vec;
3907 rtx tmp_op, tmp;
3908
3909 gcc_assert (GET_CODE (op1) == PARALLEL);
3910 gcc_assert (i < n_elts);
3911
3912 /* Select element, pointed by nested selector. */
3913 elem = INTVAL (XVECEXP (op1, 0, i));
3914
3915 /* Handle the case when nested VEC_SELECT wraps VEC_CONCAT. */
3916 if (GET_CODE (op0) == VEC_CONCAT)
3917 {
3918 rtx op00 = XEXP (op0, 0);
3919 rtx op01 = XEXP (op0, 1);
3920
3921 machine_mode mode00, mode01;
3922 int n_elts00, n_elts01;
3923
3924 mode00 = GET_MODE (op00);
3925 mode01 = GET_MODE (op01);
3926
3927 /* Find out the number of elements of each operand.
3928 Since the concatenated result has a constant number
3929 of elements, the operands must too. */
3930 n_elts00 = GET_MODE_NUNITS (mode00).to_constant ();
3931 n_elts01 = GET_MODE_NUNITS (mode01).to_constant ();
3932
3933 gcc_assert (n_elts == n_elts00 + n_elts01);
3934
3935 /* Select correct operand of VEC_CONCAT
3936 and adjust selector. */
3937 if (elem < n_elts01)
3938 tmp_op = op00;
3939 else
3940 {
3941 tmp_op = op01;
3942 elem -= n_elts00;
3943 }
3944 }
3945 else
3946 tmp_op = op0;
3947
3948 vec = rtvec_alloc (1);
3949 RTVEC_ELT (vec, 0) = GEN_INT (elem);
3950
3951 tmp = gen_rtx_fmt_ee (code, mode,
3952 tmp_op, gen_rtx_PARALLEL (VOIDmode, vec));
3953 return tmp;
3954 }
3955 }
3956 else
3957 {
3958 gcc_assert (VECTOR_MODE_P (GET_MODE (trueop0)));
3959 gcc_assert (GET_MODE_INNER (mode)
3960 == GET_MODE_INNER (GET_MODE (trueop0)));
3961 gcc_assert (GET_CODE (trueop1) == PARALLEL);
3962
3963 if (vec_duplicate_p (trueop0, &elt0))
3964 /* It doesn't matter which elements are selected by trueop1,
3965 because they are all the same. */
3966 return gen_vec_duplicate (mode, elt0);
3967
3968 if (GET_CODE (trueop0) == CONST_VECTOR)
3969 {
3970 unsigned n_elts = XVECLEN (trueop1, 0);
3971 rtvec v = rtvec_alloc (n_elts);
3972 unsigned int i;
3973
3974 gcc_assert (known_eq (n_elts, GET_MODE_NUNITS (mode)));
3975 for (i = 0; i < n_elts; i++)
3976 {
3977 rtx x = XVECEXP (trueop1, 0, i);
3978
3979 if (!CONST_INT_P (x))
3980 return 0;
3981
3982 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0,
3983 INTVAL (x));
3984 }
3985
3986 return gen_rtx_CONST_VECTOR (mode, v);
3987 }
3988
3989 /* Recognize the identity. */
3990 if (GET_MODE (trueop0) == mode)
3991 {
3992 bool maybe_ident = true;
3993 for (int i = 0; i < XVECLEN (trueop1, 0); i++)
3994 {
3995 rtx j = XVECEXP (trueop1, 0, i);
3996 if (!CONST_INT_P (j) || INTVAL (j) != i)
3997 {
3998 maybe_ident = false;
3999 break;
4000 }
4001 }
4002 if (maybe_ident)
4003 return trueop0;
4004 }
4005
4006 /* If we build {a,b} then permute it, build the result directly. */
4007 if (XVECLEN (trueop1, 0) == 2
4008 && CONST_INT_P (XVECEXP (trueop1, 0, 0))
4009 && CONST_INT_P (XVECEXP (trueop1, 0, 1))
4010 && GET_CODE (trueop0) == VEC_CONCAT
4011 && GET_CODE (XEXP (trueop0, 0)) == VEC_CONCAT
4012 && GET_MODE (XEXP (trueop0, 0)) == mode
4013 && GET_CODE (XEXP (trueop0, 1)) == VEC_CONCAT
4014 && GET_MODE (XEXP (trueop0, 1)) == mode)
4015 {
4016 unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
4017 unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
4018 rtx subop0, subop1;
4019
4020 gcc_assert (i0 < 4 && i1 < 4);
4021 subop0 = XEXP (XEXP (trueop0, i0 / 2), i0 % 2);
4022 subop1 = XEXP (XEXP (trueop0, i1 / 2), i1 % 2);
4023
4024 return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
4025 }
4026
4027 if (XVECLEN (trueop1, 0) == 2
4028 && CONST_INT_P (XVECEXP (trueop1, 0, 0))
4029 && CONST_INT_P (XVECEXP (trueop1, 0, 1))
4030 && GET_CODE (trueop0) == VEC_CONCAT
4031 && GET_MODE (trueop0) == mode)
4032 {
4033 unsigned int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
4034 unsigned int i1 = INTVAL (XVECEXP (trueop1, 0, 1));
4035 rtx subop0, subop1;
4036
4037 gcc_assert (i0 < 2 && i1 < 2);
4038 subop0 = XEXP (trueop0, i0);
4039 subop1 = XEXP (trueop0, i1);
4040
4041 return simplify_gen_binary (VEC_CONCAT, mode, subop0, subop1);
4042 }
4043
4044 /* If we select one half of a vec_concat, return that. */
4045 int l0, l1;
4046 if (GET_CODE (trueop0) == VEC_CONCAT
4047 && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 0)))
4048 .is_constant (&l0))
4049 && (GET_MODE_NUNITS (GET_MODE (XEXP (trueop0, 1)))
4050 .is_constant (&l1))
4051 && CONST_INT_P (XVECEXP (trueop1, 0, 0)))
4052 {
4053 rtx subop0 = XEXP (trueop0, 0);
4054 rtx subop1 = XEXP (trueop0, 1);
4055 machine_mode mode0 = GET_MODE (subop0);
4056 machine_mode mode1 = GET_MODE (subop1);
4057 int i0 = INTVAL (XVECEXP (trueop1, 0, 0));
4058 if (i0 == 0 && !side_effects_p (op1) && mode == mode0)
4059 {
4060 bool success = true;
4061 for (int i = 1; i < l0; ++i)
4062 {
4063 rtx j = XVECEXP (trueop1, 0, i);
4064 if (!CONST_INT_P (j) || INTVAL (j) != i)
4065 {
4066 success = false;
4067 break;
4068 }
4069 }
4070 if (success)
4071 return subop0;
4072 }
4073 if (i0 == l0 && !side_effects_p (op0) && mode == mode1)
4074 {
4075 bool success = true;
4076 for (int i = 1; i < l1; ++i)
4077 {
4078 rtx j = XVECEXP (trueop1, 0, i);
4079 if (!CONST_INT_P (j) || INTVAL (j) != i0 + i)
4080 {
4081 success = false;
4082 break;
4083 }
4084 }
4085 if (success)
4086 return subop1;
4087 }
4088 }
4089 }
4090
4091 if (XVECLEN (trueop1, 0) == 1
4092 && CONST_INT_P (XVECEXP (trueop1, 0, 0))
4093 && GET_CODE (trueop0) == VEC_CONCAT)
4094 {
4095 rtx vec = trueop0;
4096 offset = INTVAL (XVECEXP (trueop1, 0, 0)) * GET_MODE_SIZE (mode);
4097
4098 /* Try to find the element in the VEC_CONCAT. */
4099 while (GET_MODE (vec) != mode
4100 && GET_CODE (vec) == VEC_CONCAT)
4101 {
4102 poly_int64 vec_size;
4103
4104 if (CONST_INT_P (XEXP (vec, 0)))
4105 {
4106 /* vec_concat of two const_ints doesn't make sense with
4107 respect to modes. */
4108 if (CONST_INT_P (XEXP (vec, 1)))
4109 return 0;
4110
4111 vec_size = GET_MODE_SIZE (GET_MODE (trueop0))
4112 - GET_MODE_SIZE (GET_MODE (XEXP (vec, 1)));
4113 }
4114 else
4115 vec_size = GET_MODE_SIZE (GET_MODE (XEXP (vec, 0)));
4116
4117 if (known_lt (offset, vec_size))
4118 vec = XEXP (vec, 0);
4119 else if (known_ge (offset, vec_size))
4120 {
4121 offset -= vec_size;
4122 vec = XEXP (vec, 1);
4123 }
4124 else
4125 break;
4126 vec = avoid_constant_pool_reference (vec);
4127 }
4128
4129 if (GET_MODE (vec) == mode)
4130 return vec;
4131 }
4132
4133 /* If we select elements in a vec_merge that all come from the same
4134 operand, select from that operand directly. */
4135 if (GET_CODE (op0) == VEC_MERGE)
4136 {
4137 rtx trueop02 = avoid_constant_pool_reference (XEXP (op0, 2));
4138 if (CONST_INT_P (trueop02))
4139 {
4140 unsigned HOST_WIDE_INT sel = UINTVAL (trueop02);
4141 bool all_operand0 = true;
4142 bool all_operand1 = true;
4143 for (int i = 0; i < XVECLEN (trueop1, 0); i++)
4144 {
4145 rtx j = XVECEXP (trueop1, 0, i);
4146 if (sel & (HOST_WIDE_INT_1U << UINTVAL (j)))
4147 all_operand1 = false;
4148 else
4149 all_operand0 = false;
4150 }
4151 if (all_operand0 && !side_effects_p (XEXP (op0, 1)))
4152 return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 0), op1);
4153 if (all_operand1 && !side_effects_p (XEXP (op0, 0)))
4154 return simplify_gen_binary (VEC_SELECT, mode, XEXP (op0, 1), op1);
4155 }
4156 }
4157
4158 /* If we have two nested selects that are inverses of each
4159 other, replace them with the source operand. */
4160 if (GET_CODE (trueop0) == VEC_SELECT
4161 && GET_MODE (XEXP (trueop0, 0)) == mode)
4162 {
4163 rtx op0_subop1 = XEXP (trueop0, 1);
4164 gcc_assert (GET_CODE (op0_subop1) == PARALLEL);
4165 gcc_assert (known_eq (XVECLEN (trueop1, 0), GET_MODE_NUNITS (mode)));
4166
4167 /* Apply the outer ordering vector to the inner one. (The inner
4168 ordering vector is expressly permitted to be of a different
4169 length than the outer one.) If the result is { 0, 1, ..., n-1 }
4170 then the two VEC_SELECTs cancel. */
4171 for (int i = 0; i < XVECLEN (trueop1, 0); ++i)
4172 {
4173 rtx x = XVECEXP (trueop1, 0, i);
4174 if (!CONST_INT_P (x))
4175 return 0;
4176 rtx y = XVECEXP (op0_subop1, 0, INTVAL (x));
4177 if (!CONST_INT_P (y) || i != INTVAL (y))
4178 return 0;
4179 }
4180 return XEXP (trueop0, 0);
4181 }
4182
4183 return 0;
4184 case VEC_CONCAT:
4185 {
4186 machine_mode op0_mode = (GET_MODE (trueop0) != VOIDmode
4187 ? GET_MODE (trueop0)
4188 : GET_MODE_INNER (mode));
4189 machine_mode op1_mode = (GET_MODE (trueop1) != VOIDmode
4190 ? GET_MODE (trueop1)
4191 : GET_MODE_INNER (mode));
4192
4193 gcc_assert (VECTOR_MODE_P (mode));
4194 gcc_assert (known_eq (GET_MODE_SIZE (op0_mode)
4195 + GET_MODE_SIZE (op1_mode),
4196 GET_MODE_SIZE (mode)));
4197
4198 if (VECTOR_MODE_P (op0_mode))
4199 gcc_assert (GET_MODE_INNER (mode)
4200 == GET_MODE_INNER (op0_mode));
4201 else
4202 gcc_assert (GET_MODE_INNER (mode) == op0_mode);
4203
4204 if (VECTOR_MODE_P (op1_mode))
4205 gcc_assert (GET_MODE_INNER (mode)
4206 == GET_MODE_INNER (op1_mode));
4207 else
4208 gcc_assert (GET_MODE_INNER (mode) == op1_mode);
4209
4210 unsigned int n_elts, in_n_elts;
4211 if ((GET_CODE (trueop0) == CONST_VECTOR
4212 || CONST_SCALAR_INT_P (trueop0)
4213 || CONST_DOUBLE_AS_FLOAT_P (trueop0))
4214 && (GET_CODE (trueop1) == CONST_VECTOR
4215 || CONST_SCALAR_INT_P (trueop1)
4216 || CONST_DOUBLE_AS_FLOAT_P (trueop1))
4217 && GET_MODE_NUNITS (mode).is_constant (&n_elts)
4218 && GET_MODE_NUNITS (op0_mode).is_constant (&in_n_elts))
4219 {
4220 rtvec v = rtvec_alloc (n_elts);
4221 unsigned int i;
4222 for (i = 0; i < n_elts; i++)
4223 {
4224 if (i < in_n_elts)
4225 {
4226 if (!VECTOR_MODE_P (op0_mode))
4227 RTVEC_ELT (v, i) = trueop0;
4228 else
4229 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop0, i);
4230 }
4231 else
4232 {
4233 if (!VECTOR_MODE_P (op1_mode))
4234 RTVEC_ELT (v, i) = trueop1;
4235 else
4236 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (trueop1,
4237 i - in_n_elts);
4238 }
4239 }
4240
4241 return gen_rtx_CONST_VECTOR (mode, v);
4242 }
4243
4244 /* Try to merge two VEC_SELECTs from the same vector into a single one.
4245 Restrict the transformation to avoid generating a VEC_SELECT with a
4246 mode unrelated to its operand. */
4247 if (GET_CODE (trueop0) == VEC_SELECT
4248 && GET_CODE (trueop1) == VEC_SELECT
4249 && rtx_equal_p (XEXP (trueop0, 0), XEXP (trueop1, 0))
4250 && GET_MODE (XEXP (trueop0, 0)) == mode)
4251 {
4252 rtx par0 = XEXP (trueop0, 1);
4253 rtx par1 = XEXP (trueop1, 1);
4254 int len0 = XVECLEN (par0, 0);
4255 int len1 = XVECLEN (par1, 0);
4256 rtvec vec = rtvec_alloc (len0 + len1);
4257 for (int i = 0; i < len0; i++)
4258 RTVEC_ELT (vec, i) = XVECEXP (par0, 0, i);
4259 for (int i = 0; i < len1; i++)
4260 RTVEC_ELT (vec, len0 + i) = XVECEXP (par1, 0, i);
4261 return simplify_gen_binary (VEC_SELECT, mode, XEXP (trueop0, 0),
4262 gen_rtx_PARALLEL (VOIDmode, vec));
4263 }
4264 }
4265 return 0;
4266
4267 default:
4268 gcc_unreachable ();
4269 }
4270
4271 if (mode == GET_MODE (op0)
4272 && mode == GET_MODE (op1)
4273 && vec_duplicate_p (op0, &elt0)
4274 && vec_duplicate_p (op1, &elt1))
4275 {
4276 /* Try applying the operator to ELT and see if that simplifies.
4277 We can duplicate the result if so.
4278
4279 The reason we don't use simplify_gen_binary is that it isn't
4280 necessarily a win to convert things like:
4281
4282 (plus:V (vec_duplicate:V (reg:S R1))
4283 (vec_duplicate:V (reg:S R2)))
4284
4285 to:
4286
4287 (vec_duplicate:V (plus:S (reg:S R1) (reg:S R2)))
4288
4289 The first might be done entirely in vector registers while the
4290 second might need a move between register files. */
4291 tem = simplify_binary_operation (code, GET_MODE_INNER (mode),
4292 elt0, elt1);
4293 if (tem)
4294 return gen_vec_duplicate (mode, tem);
4295 }
4296
4297 return 0;
4298 }
4299
4300 /* Return true if binary operation OP distributes over addition in operand
4301 OPNO, with the other operand being held constant. OPNO counts from 1. */
4302
4303 static bool
distributes_over_addition_p(rtx_code op,int opno)4304 distributes_over_addition_p (rtx_code op, int opno)
4305 {
4306 switch (op)
4307 {
4308 case PLUS:
4309 case MINUS:
4310 case MULT:
4311 return true;
4312
4313 case ASHIFT:
4314 return opno == 1;
4315
4316 default:
4317 return false;
4318 }
4319 }
4320
4321 rtx
simplify_const_binary_operation(enum rtx_code code,machine_mode mode,rtx op0,rtx op1)4322 simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
4323 rtx op0, rtx op1)
4324 {
4325 if (VECTOR_MODE_P (mode)
4326 && code != VEC_CONCAT
4327 && GET_CODE (op0) == CONST_VECTOR
4328 && GET_CODE (op1) == CONST_VECTOR)
4329 {
4330 bool step_ok_p;
4331 if (CONST_VECTOR_STEPPED_P (op0)
4332 && CONST_VECTOR_STEPPED_P (op1))
4333 /* We can operate directly on the encoding if:
4334
4335 a3 - a2 == a2 - a1 && b3 - b2 == b2 - b1
4336 implies
4337 (a3 op b3) - (a2 op b2) == (a2 op b2) - (a1 op b1)
4338
4339 Addition and subtraction are the supported operators
4340 for which this is true. */
4341 step_ok_p = (code == PLUS || code == MINUS);
4342 else if (CONST_VECTOR_STEPPED_P (op0))
4343 /* We can operate directly on stepped encodings if:
4344
4345 a3 - a2 == a2 - a1
4346 implies:
4347 (a3 op c) - (a2 op c) == (a2 op c) - (a1 op c)
4348
4349 which is true if (x -> x op c) distributes over addition. */
4350 step_ok_p = distributes_over_addition_p (code, 1);
4351 else
4352 /* Similarly in reverse. */
4353 step_ok_p = distributes_over_addition_p (code, 2);
4354 rtx_vector_builder builder;
4355 if (!builder.new_binary_operation (mode, op0, op1, step_ok_p))
4356 return 0;
4357
4358 unsigned int count = builder.encoded_nelts ();
4359 for (unsigned int i = 0; i < count; i++)
4360 {
4361 rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
4362 CONST_VECTOR_ELT (op0, i),
4363 CONST_VECTOR_ELT (op1, i));
4364 if (!x || !valid_for_const_vector_p (mode, x))
4365 return 0;
4366 builder.quick_push (x);
4367 }
4368 return builder.build ();
4369 }
4370
4371 if (VECTOR_MODE_P (mode)
4372 && code == VEC_CONCAT
4373 && (CONST_SCALAR_INT_P (op0)
4374 || CONST_FIXED_P (op0)
4375 || CONST_DOUBLE_AS_FLOAT_P (op0))
4376 && (CONST_SCALAR_INT_P (op1)
4377 || CONST_DOUBLE_AS_FLOAT_P (op1)
4378 || CONST_FIXED_P (op1)))
4379 {
4380 /* Both inputs have a constant number of elements, so the result
4381 must too. */
4382 unsigned n_elts = GET_MODE_NUNITS (mode).to_constant ();
4383 rtvec v = rtvec_alloc (n_elts);
4384
4385 gcc_assert (n_elts >= 2);
4386 if (n_elts == 2)
4387 {
4388 gcc_assert (GET_CODE (op0) != CONST_VECTOR);
4389 gcc_assert (GET_CODE (op1) != CONST_VECTOR);
4390
4391 RTVEC_ELT (v, 0) = op0;
4392 RTVEC_ELT (v, 1) = op1;
4393 }
4394 else
4395 {
4396 unsigned op0_n_elts = GET_MODE_NUNITS (GET_MODE (op0)).to_constant ();
4397 unsigned op1_n_elts = GET_MODE_NUNITS (GET_MODE (op1)).to_constant ();
4398 unsigned i;
4399
4400 gcc_assert (GET_CODE (op0) == CONST_VECTOR);
4401 gcc_assert (GET_CODE (op1) == CONST_VECTOR);
4402 gcc_assert (op0_n_elts + op1_n_elts == n_elts);
4403
4404 for (i = 0; i < op0_n_elts; ++i)
4405 RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op0, i);
4406 for (i = 0; i < op1_n_elts; ++i)
4407 RTVEC_ELT (v, op0_n_elts+i) = CONST_VECTOR_ELT (op1, i);
4408 }
4409
4410 return gen_rtx_CONST_VECTOR (mode, v);
4411 }
4412
4413 if (SCALAR_FLOAT_MODE_P (mode)
4414 && CONST_DOUBLE_AS_FLOAT_P (op0)
4415 && CONST_DOUBLE_AS_FLOAT_P (op1)
4416 && mode == GET_MODE (op0) && mode == GET_MODE (op1))
4417 {
4418 if (code == AND
4419 || code == IOR
4420 || code == XOR)
4421 {
4422 long tmp0[4];
4423 long tmp1[4];
4424 REAL_VALUE_TYPE r;
4425 int i;
4426
4427 real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0),
4428 GET_MODE (op0));
4429 real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1),
4430 GET_MODE (op1));
4431 for (i = 0; i < 4; i++)
4432 {
4433 switch (code)
4434 {
4435 case AND:
4436 tmp0[i] &= tmp1[i];
4437 break;
4438 case IOR:
4439 tmp0[i] |= tmp1[i];
4440 break;
4441 case XOR:
4442 tmp0[i] ^= tmp1[i];
4443 break;
4444 default:
4445 gcc_unreachable ();
4446 }
4447 }
4448 real_from_target (&r, tmp0, mode);
4449 return const_double_from_real_value (r, mode);
4450 }
4451 else
4452 {
4453 REAL_VALUE_TYPE f0, f1, value, result;
4454 const REAL_VALUE_TYPE *opr0, *opr1;
4455 bool inexact;
4456
4457 opr0 = CONST_DOUBLE_REAL_VALUE (op0);
4458 opr1 = CONST_DOUBLE_REAL_VALUE (op1);
4459
4460 if (HONOR_SNANS (mode)
4461 && (REAL_VALUE_ISSIGNALING_NAN (*opr0)
4462 || REAL_VALUE_ISSIGNALING_NAN (*opr1)))
4463 return 0;
4464
4465 real_convert (&f0, mode, opr0);
4466 real_convert (&f1, mode, opr1);
4467
4468 if (code == DIV
4469 && real_equal (&f1, &dconst0)
4470 && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
4471 return 0;
4472
4473 if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
4474 && flag_trapping_math
4475 && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
4476 {
4477 int s0 = REAL_VALUE_NEGATIVE (f0);
4478 int s1 = REAL_VALUE_NEGATIVE (f1);
4479
4480 switch (code)
4481 {
4482 case PLUS:
4483 /* Inf + -Inf = NaN plus exception. */
4484 if (s0 != s1)
4485 return 0;
4486 break;
4487 case MINUS:
4488 /* Inf - Inf = NaN plus exception. */
4489 if (s0 == s1)
4490 return 0;
4491 break;
4492 case DIV:
4493 /* Inf / Inf = NaN plus exception. */
4494 return 0;
4495 default:
4496 break;
4497 }
4498 }
4499
4500 if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
4501 && flag_trapping_math
4502 && ((REAL_VALUE_ISINF (f0) && real_equal (&f1, &dconst0))
4503 || (REAL_VALUE_ISINF (f1)
4504 && real_equal (&f0, &dconst0))))
4505 /* Inf * 0 = NaN plus exception. */
4506 return 0;
4507
4508 inexact = real_arithmetic (&value, rtx_to_tree_code (code),
4509 &f0, &f1);
4510 real_convert (&result, mode, &value);
4511
4512 /* Don't constant fold this floating point operation if
4513 the result has overflowed and flag_trapping_math. */
4514
4515 if (flag_trapping_math
4516 && MODE_HAS_INFINITIES (mode)
4517 && REAL_VALUE_ISINF (result)
4518 && !REAL_VALUE_ISINF (f0)
4519 && !REAL_VALUE_ISINF (f1))
4520 /* Overflow plus exception. */
4521 return 0;
4522
4523 /* Don't constant fold this floating point operation if the
4524 result may dependent upon the run-time rounding mode and
4525 flag_rounding_math is set, or if GCC's software emulation
4526 is unable to accurately represent the result. */
4527
4528 if ((flag_rounding_math
4529 || (MODE_COMPOSITE_P (mode) && !flag_unsafe_math_optimizations))
4530 && (inexact || !real_identical (&result, &value)))
4531 return NULL_RTX;
4532
4533 return const_double_from_real_value (result, mode);
4534 }
4535 }
4536
4537 /* We can fold some multi-word operations. */
4538 scalar_int_mode int_mode;
4539 if (is_a <scalar_int_mode> (mode, &int_mode)
4540 && CONST_SCALAR_INT_P (op0)
4541 && CONST_SCALAR_INT_P (op1)
4542 && GET_MODE_PRECISION (int_mode) <= MAX_BITSIZE_MODE_ANY_INT)
4543 {
4544 wide_int result;
4545 wi::overflow_type overflow;
4546 rtx_mode_t pop0 = rtx_mode_t (op0, int_mode);
4547 rtx_mode_t pop1 = rtx_mode_t (op1, int_mode);
4548
4549 #if TARGET_SUPPORTS_WIDE_INT == 0
4550 /* This assert keeps the simplification from producing a result
4551 that cannot be represented in a CONST_DOUBLE but a lot of
4552 upstream callers expect that this function never fails to
4553 simplify something and so you if you added this to the test
4554 above the code would die later anyway. If this assert
4555 happens, you just need to make the port support wide int. */
4556 gcc_assert (GET_MODE_PRECISION (int_mode) <= HOST_BITS_PER_DOUBLE_INT);
4557 #endif
4558 switch (code)
4559 {
4560 case MINUS:
4561 result = wi::sub (pop0, pop1);
4562 break;
4563
4564 case PLUS:
4565 result = wi::add (pop0, pop1);
4566 break;
4567
4568 case MULT:
4569 result = wi::mul (pop0, pop1);
4570 break;
4571
4572 case DIV:
4573 result = wi::div_trunc (pop0, pop1, SIGNED, &overflow);
4574 if (overflow)
4575 return NULL_RTX;
4576 break;
4577
4578 case MOD:
4579 result = wi::mod_trunc (pop0, pop1, SIGNED, &overflow);
4580 if (overflow)
4581 return NULL_RTX;
4582 break;
4583
4584 case UDIV:
4585 result = wi::div_trunc (pop0, pop1, UNSIGNED, &overflow);
4586 if (overflow)
4587 return NULL_RTX;
4588 break;
4589
4590 case UMOD:
4591 result = wi::mod_trunc (pop0, pop1, UNSIGNED, &overflow);
4592 if (overflow)
4593 return NULL_RTX;
4594 break;
4595
4596 case AND:
4597 result = wi::bit_and (pop0, pop1);
4598 break;
4599
4600 case IOR:
4601 result = wi::bit_or (pop0, pop1);
4602 break;
4603
4604 case XOR:
4605 result = wi::bit_xor (pop0, pop1);
4606 break;
4607
4608 case SMIN:
4609 result = wi::smin (pop0, pop1);
4610 break;
4611
4612 case SMAX:
4613 result = wi::smax (pop0, pop1);
4614 break;
4615
4616 case UMIN:
4617 result = wi::umin (pop0, pop1);
4618 break;
4619
4620 case UMAX:
4621 result = wi::umax (pop0, pop1);
4622 break;
4623
4624 case LSHIFTRT:
4625 case ASHIFTRT:
4626 case ASHIFT:
4627 {
4628 wide_int wop1 = pop1;
4629 if (SHIFT_COUNT_TRUNCATED)
4630 wop1 = wi::umod_trunc (wop1, GET_MODE_PRECISION (int_mode));
4631 else if (wi::geu_p (wop1, GET_MODE_PRECISION (int_mode)))
4632 return NULL_RTX;
4633
4634 switch (code)
4635 {
4636 case LSHIFTRT:
4637 result = wi::lrshift (pop0, wop1);
4638 break;
4639
4640 case ASHIFTRT:
4641 result = wi::arshift (pop0, wop1);
4642 break;
4643
4644 case ASHIFT:
4645 result = wi::lshift (pop0, wop1);
4646 break;
4647
4648 default:
4649 gcc_unreachable ();
4650 }
4651 break;
4652 }
4653 case ROTATE:
4654 case ROTATERT:
4655 {
4656 if (wi::neg_p (pop1))
4657 return NULL_RTX;
4658
4659 switch (code)
4660 {
4661 case ROTATE:
4662 result = wi::lrotate (pop0, pop1);
4663 break;
4664
4665 case ROTATERT:
4666 result = wi::rrotate (pop0, pop1);
4667 break;
4668
4669 default:
4670 gcc_unreachable ();
4671 }
4672 break;
4673 }
4674 default:
4675 return NULL_RTX;
4676 }
4677 return immed_wide_int_const (result, int_mode);
4678 }
4679
4680 /* Handle polynomial integers. */
4681 if (NUM_POLY_INT_COEFFS > 1
4682 && is_a <scalar_int_mode> (mode, &int_mode)
4683 && poly_int_rtx_p (op0)
4684 && poly_int_rtx_p (op1))
4685 {
4686 poly_wide_int result;
4687 switch (code)
4688 {
4689 case PLUS:
4690 result = wi::to_poly_wide (op0, mode) + wi::to_poly_wide (op1, mode);
4691 break;
4692
4693 case MINUS:
4694 result = wi::to_poly_wide (op0, mode) - wi::to_poly_wide (op1, mode);
4695 break;
4696
4697 case MULT:
4698 if (CONST_SCALAR_INT_P (op1))
4699 result = wi::to_poly_wide (op0, mode) * rtx_mode_t (op1, mode);
4700 else
4701 return NULL_RTX;
4702 break;
4703
4704 case ASHIFT:
4705 if (CONST_SCALAR_INT_P (op1))
4706 {
4707 wide_int shift = rtx_mode_t (op1, mode);
4708 if (SHIFT_COUNT_TRUNCATED)
4709 shift = wi::umod_trunc (shift, GET_MODE_PRECISION (int_mode));
4710 else if (wi::geu_p (shift, GET_MODE_PRECISION (int_mode)))
4711 return NULL_RTX;
4712 result = wi::to_poly_wide (op0, mode) << shift;
4713 }
4714 else
4715 return NULL_RTX;
4716 break;
4717
4718 case IOR:
4719 if (!CONST_SCALAR_INT_P (op1)
4720 || !can_ior_p (wi::to_poly_wide (op0, mode),
4721 rtx_mode_t (op1, mode), &result))
4722 return NULL_RTX;
4723 break;
4724
4725 default:
4726 return NULL_RTX;
4727 }
4728 return immed_wide_int_const (result, int_mode);
4729 }
4730
4731 return NULL_RTX;
4732 }
4733
4734
4735
4736 /* Return a positive integer if X should sort after Y. The value
4737 returned is 1 if and only if X and Y are both regs. */
4738
4739 static int
simplify_plus_minus_op_data_cmp(rtx x,rtx y)4740 simplify_plus_minus_op_data_cmp (rtx x, rtx y)
4741 {
4742 int result;
4743
4744 result = (commutative_operand_precedence (y)
4745 - commutative_operand_precedence (x));
4746 if (result)
4747 return result + result;
4748
4749 /* Group together equal REGs to do more simplification. */
4750 if (REG_P (x) && REG_P (y))
4751 return REGNO (x) > REGNO (y);
4752
4753 return 0;
4754 }
4755
4756 /* Simplify and canonicalize a PLUS or MINUS, at least one of whose
4757 operands may be another PLUS or MINUS.
4758
4759 Rather than test for specific case, we do this by a brute-force method
4760 and do all possible simplifications until no more changes occur. Then
4761 we rebuild the operation.
4762
4763 May return NULL_RTX when no changes were made. */
4764
4765 static rtx
simplify_plus_minus(enum rtx_code code,machine_mode mode,rtx op0,rtx op1)4766 simplify_plus_minus (enum rtx_code code, machine_mode mode, rtx op0,
4767 rtx op1)
4768 {
4769 struct simplify_plus_minus_op_data
4770 {
4771 rtx op;
4772 short neg;
4773 } ops[16];
4774 rtx result, tem;
4775 int n_ops = 2;
4776 int changed, n_constants, canonicalized = 0;
4777 int i, j;
4778
4779 memset (ops, 0, sizeof ops);
4780
4781 /* Set up the two operands and then expand them until nothing has been
4782 changed. If we run out of room in our array, give up; this should
4783 almost never happen. */
4784
4785 ops[0].op = op0;
4786 ops[0].neg = 0;
4787 ops[1].op = op1;
4788 ops[1].neg = (code == MINUS);
4789
4790 do
4791 {
4792 changed = 0;
4793 n_constants = 0;
4794
4795 for (i = 0; i < n_ops; i++)
4796 {
4797 rtx this_op = ops[i].op;
4798 int this_neg = ops[i].neg;
4799 enum rtx_code this_code = GET_CODE (this_op);
4800
4801 switch (this_code)
4802 {
4803 case PLUS:
4804 case MINUS:
4805 if (n_ops == ARRAY_SIZE (ops))
4806 return NULL_RTX;
4807
4808 ops[n_ops].op = XEXP (this_op, 1);
4809 ops[n_ops].neg = (this_code == MINUS) ^ this_neg;
4810 n_ops++;
4811
4812 ops[i].op = XEXP (this_op, 0);
4813 changed = 1;
4814 /* If this operand was negated then we will potentially
4815 canonicalize the expression. Similarly if we don't
4816 place the operands adjacent we're re-ordering the
4817 expression and thus might be performing a
4818 canonicalization. Ignore register re-ordering.
4819 ??? It might be better to shuffle the ops array here,
4820 but then (plus (plus (A, B), plus (C, D))) wouldn't
4821 be seen as non-canonical. */
4822 if (this_neg
4823 || (i != n_ops - 2
4824 && !(REG_P (ops[i].op) && REG_P (ops[n_ops - 1].op))))
4825 canonicalized = 1;
4826 break;
4827
4828 case NEG:
4829 ops[i].op = XEXP (this_op, 0);
4830 ops[i].neg = ! this_neg;
4831 changed = 1;
4832 canonicalized = 1;
4833 break;
4834
4835 case CONST:
4836 if (n_ops != ARRAY_SIZE (ops)
4837 && GET_CODE (XEXP (this_op, 0)) == PLUS
4838 && CONSTANT_P (XEXP (XEXP (this_op, 0), 0))
4839 && CONSTANT_P (XEXP (XEXP (this_op, 0), 1)))
4840 {
4841 ops[i].op = XEXP (XEXP (this_op, 0), 0);
4842 ops[n_ops].op = XEXP (XEXP (this_op, 0), 1);
4843 ops[n_ops].neg = this_neg;
4844 n_ops++;
4845 changed = 1;
4846 canonicalized = 1;
4847 }
4848 break;
4849
4850 case NOT:
4851 /* ~a -> (-a - 1) */
4852 if (n_ops != ARRAY_SIZE (ops))
4853 {
4854 ops[n_ops].op = CONSTM1_RTX (mode);
4855 ops[n_ops++].neg = this_neg;
4856 ops[i].op = XEXP (this_op, 0);
4857 ops[i].neg = !this_neg;
4858 changed = 1;
4859 canonicalized = 1;
4860 }
4861 break;
4862
4863 CASE_CONST_SCALAR_INT:
4864 case CONST_POLY_INT:
4865 n_constants++;
4866 if (this_neg)
4867 {
4868 ops[i].op = neg_poly_int_rtx (mode, this_op);
4869 ops[i].neg = 0;
4870 changed = 1;
4871 canonicalized = 1;
4872 }
4873 break;
4874
4875 default:
4876 break;
4877 }
4878 }
4879 }
4880 while (changed);
4881
4882 if (n_constants > 1)
4883 canonicalized = 1;
4884
4885 gcc_assert (n_ops >= 2);
4886
4887 /* If we only have two operands, we can avoid the loops. */
4888 if (n_ops == 2)
4889 {
4890 enum rtx_code code = ops[0].neg || ops[1].neg ? MINUS : PLUS;
4891 rtx lhs, rhs;
4892
4893 /* Get the two operands. Be careful with the order, especially for
4894 the cases where code == MINUS. */
4895 if (ops[0].neg && ops[1].neg)
4896 {
4897 lhs = gen_rtx_NEG (mode, ops[0].op);
4898 rhs = ops[1].op;
4899 }
4900 else if (ops[0].neg)
4901 {
4902 lhs = ops[1].op;
4903 rhs = ops[0].op;
4904 }
4905 else
4906 {
4907 lhs = ops[0].op;
4908 rhs = ops[1].op;
4909 }
4910
4911 return simplify_const_binary_operation (code, mode, lhs, rhs);
4912 }
4913
4914 /* Now simplify each pair of operands until nothing changes. */
4915 while (1)
4916 {
4917 /* Insertion sort is good enough for a small array. */
4918 for (i = 1; i < n_ops; i++)
4919 {
4920 struct simplify_plus_minus_op_data save;
4921 int cmp;
4922
4923 j = i - 1;
4924 cmp = simplify_plus_minus_op_data_cmp (ops[j].op, ops[i].op);
4925 if (cmp <= 0)
4926 continue;
4927 /* Just swapping registers doesn't count as canonicalization. */
4928 if (cmp != 1)
4929 canonicalized = 1;
4930
4931 save = ops[i];
4932 do
4933 ops[j + 1] = ops[j];
4934 while (j--
4935 && simplify_plus_minus_op_data_cmp (ops[j].op, save.op) > 0);
4936 ops[j + 1] = save;
4937 }
4938
4939 changed = 0;
4940 for (i = n_ops - 1; i > 0; i--)
4941 for (j = i - 1; j >= 0; j--)
4942 {
4943 rtx lhs = ops[j].op, rhs = ops[i].op;
4944 int lneg = ops[j].neg, rneg = ops[i].neg;
4945
4946 if (lhs != 0 && rhs != 0)
4947 {
4948 enum rtx_code ncode = PLUS;
4949
4950 if (lneg != rneg)
4951 {
4952 ncode = MINUS;
4953 if (lneg)
4954 std::swap (lhs, rhs);
4955 }
4956 else if (swap_commutative_operands_p (lhs, rhs))
4957 std::swap (lhs, rhs);
4958
4959 if ((GET_CODE (lhs) == CONST || CONST_INT_P (lhs))
4960 && (GET_CODE (rhs) == CONST || CONST_INT_P (rhs)))
4961 {
4962 rtx tem_lhs, tem_rhs;
4963
4964 tem_lhs = GET_CODE (lhs) == CONST ? XEXP (lhs, 0) : lhs;
4965 tem_rhs = GET_CODE (rhs) == CONST ? XEXP (rhs, 0) : rhs;
4966 tem = simplify_binary_operation (ncode, mode, tem_lhs,
4967 tem_rhs);
4968
4969 if (tem && !CONSTANT_P (tem))
4970 tem = gen_rtx_CONST (GET_MODE (tem), tem);
4971 }
4972 else
4973 tem = simplify_binary_operation (ncode, mode, lhs, rhs);
4974
4975 if (tem)
4976 {
4977 /* Reject "simplifications" that just wrap the two
4978 arguments in a CONST. Failure to do so can result
4979 in infinite recursion with simplify_binary_operation
4980 when it calls us to simplify CONST operations.
4981 Also, if we find such a simplification, don't try
4982 any more combinations with this rhs: We must have
4983 something like symbol+offset, ie. one of the
4984 trivial CONST expressions we handle later. */
4985 if (GET_CODE (tem) == CONST
4986 && GET_CODE (XEXP (tem, 0)) == ncode
4987 && XEXP (XEXP (tem, 0), 0) == lhs
4988 && XEXP (XEXP (tem, 0), 1) == rhs)
4989 break;
4990 lneg &= rneg;
4991 if (GET_CODE (tem) == NEG)
4992 tem = XEXP (tem, 0), lneg = !lneg;
4993 if (poly_int_rtx_p (tem) && lneg)
4994 tem = neg_poly_int_rtx (mode, tem), lneg = 0;
4995
4996 ops[i].op = tem;
4997 ops[i].neg = lneg;
4998 ops[j].op = NULL_RTX;
4999 changed = 1;
5000 canonicalized = 1;
5001 }
5002 }
5003 }
5004
5005 if (!changed)
5006 break;
5007
5008 /* Pack all the operands to the lower-numbered entries. */
5009 for (i = 0, j = 0; j < n_ops; j++)
5010 if (ops[j].op)
5011 {
5012 ops[i] = ops[j];
5013 i++;
5014 }
5015 n_ops = i;
5016 }
5017
5018 /* If nothing changed, check that rematerialization of rtl instructions
5019 is still required. */
5020 if (!canonicalized)
5021 {
5022 /* Perform rematerialization if only all operands are registers and
5023 all operations are PLUS. */
5024 /* ??? Also disallow (non-global, non-frame) fixed registers to work
5025 around rs6000 and how it uses the CA register. See PR67145. */
5026 for (i = 0; i < n_ops; i++)
5027 if (ops[i].neg
5028 || !REG_P (ops[i].op)
5029 || (REGNO (ops[i].op) < FIRST_PSEUDO_REGISTER
5030 && fixed_regs[REGNO (ops[i].op)]
5031 && !global_regs[REGNO (ops[i].op)]
5032 && ops[i].op != frame_pointer_rtx
5033 && ops[i].op != arg_pointer_rtx
5034 && ops[i].op != stack_pointer_rtx))
5035 return NULL_RTX;
5036 goto gen_result;
5037 }
5038
5039 /* Create (minus -C X) instead of (neg (const (plus X C))). */
5040 if (n_ops == 2
5041 && CONST_INT_P (ops[1].op)
5042 && CONSTANT_P (ops[0].op)
5043 && ops[0].neg)
5044 return gen_rtx_fmt_ee (MINUS, mode, ops[1].op, ops[0].op);
5045
5046 /* We suppressed creation of trivial CONST expressions in the
5047 combination loop to avoid recursion. Create one manually now.
5048 The combination loop should have ensured that there is exactly
5049 one CONST_INT, and the sort will have ensured that it is last
5050 in the array and that any other constant will be next-to-last. */
5051
5052 if (n_ops > 1
5053 && poly_int_rtx_p (ops[n_ops - 1].op)
5054 && CONSTANT_P (ops[n_ops - 2].op))
5055 {
5056 rtx value = ops[n_ops - 1].op;
5057 if (ops[n_ops - 1].neg ^ ops[n_ops - 2].neg)
5058 value = neg_poly_int_rtx (mode, value);
5059 if (CONST_INT_P (value))
5060 {
5061 ops[n_ops - 2].op = plus_constant (mode, ops[n_ops - 2].op,
5062 INTVAL (value));
5063 n_ops--;
5064 }
5065 }
5066
5067 /* Put a non-negated operand first, if possible. */
5068
5069 for (i = 0; i < n_ops && ops[i].neg; i++)
5070 continue;
5071 if (i == n_ops)
5072 ops[0].op = gen_rtx_NEG (mode, ops[0].op);
5073 else if (i != 0)
5074 {
5075 tem = ops[0].op;
5076 ops[0] = ops[i];
5077 ops[i].op = tem;
5078 ops[i].neg = 1;
5079 }
5080
5081 /* Now make the result by performing the requested operations. */
5082 gen_result:
5083 result = ops[0].op;
5084 for (i = 1; i < n_ops; i++)
5085 result = gen_rtx_fmt_ee (ops[i].neg ? MINUS : PLUS,
5086 mode, result, ops[i].op);
5087
5088 return result;
5089 }
5090
5091 /* Check whether an operand is suitable for calling simplify_plus_minus. */
5092 static bool
plus_minus_operand_p(const_rtx x)5093 plus_minus_operand_p (const_rtx x)
5094 {
5095 return GET_CODE (x) == PLUS
5096 || GET_CODE (x) == MINUS
5097 || (GET_CODE (x) == CONST
5098 && GET_CODE (XEXP (x, 0)) == PLUS
5099 && CONSTANT_P (XEXP (XEXP (x, 0), 0))
5100 && CONSTANT_P (XEXP (XEXP (x, 0), 1)));
5101 }
5102
5103 /* Like simplify_binary_operation except used for relational operators.
5104 MODE is the mode of the result. If MODE is VOIDmode, both operands must
5105 not also be VOIDmode.
5106
5107 CMP_MODE specifies in which mode the comparison is done in, so it is
5108 the mode of the operands. If CMP_MODE is VOIDmode, it is taken from
5109 the operands or, if both are VOIDmode, the operands are compared in
5110 "infinite precision". */
5111 rtx
simplify_relational_operation(enum rtx_code code,machine_mode mode,machine_mode cmp_mode,rtx op0,rtx op1)5112 simplify_relational_operation (enum rtx_code code, machine_mode mode,
5113 machine_mode cmp_mode, rtx op0, rtx op1)
5114 {
5115 rtx tem, trueop0, trueop1;
5116
5117 if (cmp_mode == VOIDmode)
5118 cmp_mode = GET_MODE (op0);
5119 if (cmp_mode == VOIDmode)
5120 cmp_mode = GET_MODE (op1);
5121
5122 tem = simplify_const_relational_operation (code, cmp_mode, op0, op1);
5123 if (tem)
5124 return relational_result (mode, cmp_mode, tem);
5125
5126 /* For the following tests, ensure const0_rtx is op1. */
5127 if (swap_commutative_operands_p (op0, op1)
5128 || (op0 == const0_rtx && op1 != const0_rtx))
5129 std::swap (op0, op1), code = swap_condition (code);
5130
5131 /* If op0 is a compare, extract the comparison arguments from it. */
5132 if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
5133 return simplify_gen_relational (code, mode, VOIDmode,
5134 XEXP (op0, 0), XEXP (op0, 1));
5135
5136 if (GET_MODE_CLASS (cmp_mode) == MODE_CC
5137 || CC0_P (op0))
5138 return NULL_RTX;
5139
5140 trueop0 = avoid_constant_pool_reference (op0);
5141 trueop1 = avoid_constant_pool_reference (op1);
5142 return simplify_relational_operation_1 (code, mode, cmp_mode,
5143 trueop0, trueop1);
5144 }
5145
5146 /* This part of simplify_relational_operation is only used when CMP_MODE
5147 is not in class MODE_CC (i.e. it is a real comparison).
5148
5149 MODE is the mode of the result, while CMP_MODE specifies in which
5150 mode the comparison is done in, so it is the mode of the operands. */
5151
5152 static rtx
simplify_relational_operation_1(enum rtx_code code,machine_mode mode,machine_mode cmp_mode,rtx op0,rtx op1)5153 simplify_relational_operation_1 (enum rtx_code code, machine_mode mode,
5154 machine_mode cmp_mode, rtx op0, rtx op1)
5155 {
5156 enum rtx_code op0code = GET_CODE (op0);
5157
5158 if (op1 == const0_rtx && COMPARISON_P (op0))
5159 {
5160 /* If op0 is a comparison, extract the comparison arguments
5161 from it. */
5162 if (code == NE)
5163 {
5164 if (GET_MODE (op0) == mode)
5165 return simplify_rtx (op0);
5166 else
5167 return simplify_gen_relational (GET_CODE (op0), mode, VOIDmode,
5168 XEXP (op0, 0), XEXP (op0, 1));
5169 }
5170 else if (code == EQ)
5171 {
5172 enum rtx_code new_code = reversed_comparison_code (op0, NULL);
5173 if (new_code != UNKNOWN)
5174 return simplify_gen_relational (new_code, mode, VOIDmode,
5175 XEXP (op0, 0), XEXP (op0, 1));
5176 }
5177 }
5178
5179 /* (LTU/GEU (PLUS a C) C), where C is constant, can be simplified to
5180 (GEU/LTU a -C). Likewise for (LTU/GEU (PLUS a C) a). */
5181 if ((code == LTU || code == GEU)
5182 && GET_CODE (op0) == PLUS
5183 && CONST_INT_P (XEXP (op0, 1))
5184 && (rtx_equal_p (op1, XEXP (op0, 0))
5185 || rtx_equal_p (op1, XEXP (op0, 1)))
5186 /* (LTU/GEU (PLUS a 0) 0) is not the same as (GEU/LTU a 0). */
5187 && XEXP (op0, 1) != const0_rtx)
5188 {
5189 rtx new_cmp
5190 = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
5191 return simplify_gen_relational ((code == LTU ? GEU : LTU), mode,
5192 cmp_mode, XEXP (op0, 0), new_cmp);
5193 }
5194
5195 /* (GTU (PLUS a C) (C - 1)) where C is a non-zero constant can be
5196 transformed into (LTU a -C). */
5197 if (code == GTU && GET_CODE (op0) == PLUS && CONST_INT_P (op1)
5198 && CONST_INT_P (XEXP (op0, 1))
5199 && (UINTVAL (op1) == UINTVAL (XEXP (op0, 1)) - 1)
5200 && XEXP (op0, 1) != const0_rtx)
5201 {
5202 rtx new_cmp
5203 = simplify_gen_unary (NEG, cmp_mode, XEXP (op0, 1), cmp_mode);
5204 return simplify_gen_relational (LTU, mode, cmp_mode,
5205 XEXP (op0, 0), new_cmp);
5206 }
5207
5208 /* Canonicalize (LTU/GEU (PLUS a b) b) as (LTU/GEU (PLUS a b) a). */
5209 if ((code == LTU || code == GEU)
5210 && GET_CODE (op0) == PLUS
5211 && rtx_equal_p (op1, XEXP (op0, 1))
5212 /* Don't recurse "infinitely" for (LTU/GEU (PLUS b b) b). */
5213 && !rtx_equal_p (op1, XEXP (op0, 0)))
5214 return simplify_gen_relational (code, mode, cmp_mode, op0,
5215 copy_rtx (XEXP (op0, 0)));
5216
5217 if (op1 == const0_rtx)
5218 {
5219 /* Canonicalize (GTU x 0) as (NE x 0). */
5220 if (code == GTU)
5221 return simplify_gen_relational (NE, mode, cmp_mode, op0, op1);
5222 /* Canonicalize (LEU x 0) as (EQ x 0). */
5223 if (code == LEU)
5224 return simplify_gen_relational (EQ, mode, cmp_mode, op0, op1);
5225 }
5226 else if (op1 == const1_rtx)
5227 {
5228 switch (code)
5229 {
5230 case GE:
5231 /* Canonicalize (GE x 1) as (GT x 0). */
5232 return simplify_gen_relational (GT, mode, cmp_mode,
5233 op0, const0_rtx);
5234 case GEU:
5235 /* Canonicalize (GEU x 1) as (NE x 0). */
5236 return simplify_gen_relational (NE, mode, cmp_mode,
5237 op0, const0_rtx);
5238 case LT:
5239 /* Canonicalize (LT x 1) as (LE x 0). */
5240 return simplify_gen_relational (LE, mode, cmp_mode,
5241 op0, const0_rtx);
5242 case LTU:
5243 /* Canonicalize (LTU x 1) as (EQ x 0). */
5244 return simplify_gen_relational (EQ, mode, cmp_mode,
5245 op0, const0_rtx);
5246 default:
5247 break;
5248 }
5249 }
5250 else if (op1 == constm1_rtx)
5251 {
5252 /* Canonicalize (LE x -1) as (LT x 0). */
5253 if (code == LE)
5254 return simplify_gen_relational (LT, mode, cmp_mode, op0, const0_rtx);
5255 /* Canonicalize (GT x -1) as (GE x 0). */
5256 if (code == GT)
5257 return simplify_gen_relational (GE, mode, cmp_mode, op0, const0_rtx);
5258 }
5259
5260 /* (eq/ne (plus x cst1) cst2) simplifies to (eq/ne x (cst2 - cst1)) */
5261 if ((code == EQ || code == NE)
5262 && (op0code == PLUS || op0code == MINUS)
5263 && CONSTANT_P (op1)
5264 && CONSTANT_P (XEXP (op0, 1))
5265 && (INTEGRAL_MODE_P (cmp_mode) || flag_unsafe_math_optimizations))
5266 {
5267 rtx x = XEXP (op0, 0);
5268 rtx c = XEXP (op0, 1);
5269 enum rtx_code invcode = op0code == PLUS ? MINUS : PLUS;
5270 rtx tem = simplify_gen_binary (invcode, cmp_mode, op1, c);
5271
5272 /* Detect an infinite recursive condition, where we oscillate at this
5273 simplification case between:
5274 A + B == C <---> C - B == A,
5275 where A, B, and C are all constants with non-simplifiable expressions,
5276 usually SYMBOL_REFs. */
5277 if (GET_CODE (tem) == invcode
5278 && CONSTANT_P (x)
5279 && rtx_equal_p (c, XEXP (tem, 1)))
5280 return NULL_RTX;
5281
5282 return simplify_gen_relational (code, mode, cmp_mode, x, tem);
5283 }
5284
5285 /* (ne:SI (zero_extract:SI FOO (const_int 1) BAR) (const_int 0))) is
5286 the same as (zero_extract:SI FOO (const_int 1) BAR). */
5287 scalar_int_mode int_mode, int_cmp_mode;
5288 if (code == NE
5289 && op1 == const0_rtx
5290 && is_int_mode (mode, &int_mode)
5291 && is_a <scalar_int_mode> (cmp_mode, &int_cmp_mode)
5292 /* ??? Work-around BImode bugs in the ia64 backend. */
5293 && int_mode != BImode
5294 && int_cmp_mode != BImode
5295 && nonzero_bits (op0, int_cmp_mode) == 1
5296 && STORE_FLAG_VALUE == 1)
5297 return GET_MODE_SIZE (int_mode) > GET_MODE_SIZE (int_cmp_mode)
5298 ? simplify_gen_unary (ZERO_EXTEND, int_mode, op0, int_cmp_mode)
5299 : lowpart_subreg (int_mode, op0, int_cmp_mode);
5300
5301 /* (eq/ne (xor x y) 0) simplifies to (eq/ne x y). */
5302 if ((code == EQ || code == NE)
5303 && op1 == const0_rtx
5304 && op0code == XOR)
5305 return simplify_gen_relational (code, mode, cmp_mode,
5306 XEXP (op0, 0), XEXP (op0, 1));
5307
5308 /* (eq/ne (xor x y) x) simplifies to (eq/ne y 0). */
5309 if ((code == EQ || code == NE)
5310 && op0code == XOR
5311 && rtx_equal_p (XEXP (op0, 0), op1)
5312 && !side_effects_p (XEXP (op0, 0)))
5313 return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 1),
5314 CONST0_RTX (mode));
5315
5316 /* Likewise (eq/ne (xor x y) y) simplifies to (eq/ne x 0). */
5317 if ((code == EQ || code == NE)
5318 && op0code == XOR
5319 && rtx_equal_p (XEXP (op0, 1), op1)
5320 && !side_effects_p (XEXP (op0, 1)))
5321 return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
5322 CONST0_RTX (mode));
5323
5324 /* (eq/ne (xor x C1) C2) simplifies to (eq/ne x (C1^C2)). */
5325 if ((code == EQ || code == NE)
5326 && op0code == XOR
5327 && CONST_SCALAR_INT_P (op1)
5328 && CONST_SCALAR_INT_P (XEXP (op0, 1)))
5329 return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
5330 simplify_gen_binary (XOR, cmp_mode,
5331 XEXP (op0, 1), op1));
5332
5333 /* Simplify eq/ne (and/ior x y) x/y) for targets with a BICS instruction or
5334 constant folding if x/y is a constant. */
5335 if ((code == EQ || code == NE)
5336 && (op0code == AND || op0code == IOR)
5337 && !side_effects_p (op1)
5338 && op1 != CONST0_RTX (cmp_mode))
5339 {
5340 /* Both (eq/ne (and x y) x) and (eq/ne (ior x y) y) simplify to
5341 (eq/ne (and (not y) x) 0). */
5342 if ((op0code == AND && rtx_equal_p (XEXP (op0, 0), op1))
5343 || (op0code == IOR && rtx_equal_p (XEXP (op0, 1), op1)))
5344 {
5345 rtx not_y = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 1),
5346 cmp_mode);
5347 rtx lhs = simplify_gen_binary (AND, cmp_mode, not_y, XEXP (op0, 0));
5348
5349 return simplify_gen_relational (code, mode, cmp_mode, lhs,
5350 CONST0_RTX (cmp_mode));
5351 }
5352
5353 /* Both (eq/ne (and x y) y) and (eq/ne (ior x y) x) simplify to
5354 (eq/ne (and (not x) y) 0). */
5355 if ((op0code == AND && rtx_equal_p (XEXP (op0, 1), op1))
5356 || (op0code == IOR && rtx_equal_p (XEXP (op0, 0), op1)))
5357 {
5358 rtx not_x = simplify_gen_unary (NOT, cmp_mode, XEXP (op0, 0),
5359 cmp_mode);
5360 rtx lhs = simplify_gen_binary (AND, cmp_mode, not_x, XEXP (op0, 1));
5361
5362 return simplify_gen_relational (code, mode, cmp_mode, lhs,
5363 CONST0_RTX (cmp_mode));
5364 }
5365 }
5366
5367 /* (eq/ne (bswap x) C1) simplifies to (eq/ne x C2) with C2 swapped. */
5368 if ((code == EQ || code == NE)
5369 && GET_CODE (op0) == BSWAP
5370 && CONST_SCALAR_INT_P (op1))
5371 return simplify_gen_relational (code, mode, cmp_mode, XEXP (op0, 0),
5372 simplify_gen_unary (BSWAP, cmp_mode,
5373 op1, cmp_mode));
5374
5375 /* (eq/ne (bswap x) (bswap y)) simplifies to (eq/ne x y). */
5376 if ((code == EQ || code == NE)
5377 && GET_CODE (op0) == BSWAP
5378 && GET_CODE (op1) == BSWAP)
5379 return simplify_gen_relational (code, mode, cmp_mode,
5380 XEXP (op0, 0), XEXP (op1, 0));
5381
5382 if (op0code == POPCOUNT && op1 == const0_rtx)
5383 switch (code)
5384 {
5385 case EQ:
5386 case LE:
5387 case LEU:
5388 /* (eq (popcount x) (const_int 0)) -> (eq x (const_int 0)). */
5389 return simplify_gen_relational (EQ, mode, GET_MODE (XEXP (op0, 0)),
5390 XEXP (op0, 0), const0_rtx);
5391
5392 case NE:
5393 case GT:
5394 case GTU:
5395 /* (ne (popcount x) (const_int 0)) -> (ne x (const_int 0)). */
5396 return simplify_gen_relational (NE, mode, GET_MODE (XEXP (op0, 0)),
5397 XEXP (op0, 0), const0_rtx);
5398
5399 default:
5400 break;
5401 }
5402
5403 return NULL_RTX;
5404 }
5405
5406 enum
5407 {
5408 CMP_EQ = 1,
5409 CMP_LT = 2,
5410 CMP_GT = 4,
5411 CMP_LTU = 8,
5412 CMP_GTU = 16
5413 };
5414
5415
5416 /* Convert the known results for EQ, LT, GT, LTU, GTU contained in
5417 KNOWN_RESULT to a CONST_INT, based on the requested comparison CODE
5418 For KNOWN_RESULT to make sense it should be either CMP_EQ, or the
5419 logical OR of one of (CMP_LT, CMP_GT) and one of (CMP_LTU, CMP_GTU).
5420 For floating-point comparisons, assume that the operands were ordered. */
5421
5422 static rtx
comparison_result(enum rtx_code code,int known_results)5423 comparison_result (enum rtx_code code, int known_results)
5424 {
5425 switch (code)
5426 {
5427 case EQ:
5428 case UNEQ:
5429 return (known_results & CMP_EQ) ? const_true_rtx : const0_rtx;
5430 case NE:
5431 case LTGT:
5432 return (known_results & CMP_EQ) ? const0_rtx : const_true_rtx;
5433
5434 case LT:
5435 case UNLT:
5436 return (known_results & CMP_LT) ? const_true_rtx : const0_rtx;
5437 case GE:
5438 case UNGE:
5439 return (known_results & CMP_LT) ? const0_rtx : const_true_rtx;
5440
5441 case GT:
5442 case UNGT:
5443 return (known_results & CMP_GT) ? const_true_rtx : const0_rtx;
5444 case LE:
5445 case UNLE:
5446 return (known_results & CMP_GT) ? const0_rtx : const_true_rtx;
5447
5448 case LTU:
5449 return (known_results & CMP_LTU) ? const_true_rtx : const0_rtx;
5450 case GEU:
5451 return (known_results & CMP_LTU) ? const0_rtx : const_true_rtx;
5452
5453 case GTU:
5454 return (known_results & CMP_GTU) ? const_true_rtx : const0_rtx;
5455 case LEU:
5456 return (known_results & CMP_GTU) ? const0_rtx : const_true_rtx;
5457
5458 case ORDERED:
5459 return const_true_rtx;
5460 case UNORDERED:
5461 return const0_rtx;
5462 default:
5463 gcc_unreachable ();
5464 }
5465 }
5466
5467 /* Check if the given comparison (done in the given MODE) is actually
5468 a tautology or a contradiction. If the mode is VOIDmode, the
5469 comparison is done in "infinite precision". If no simplification
5470 is possible, this function returns zero. Otherwise, it returns
5471 either const_true_rtx or const0_rtx. */
5472
5473 rtx
simplify_const_relational_operation(enum rtx_code code,machine_mode mode,rtx op0,rtx op1)5474 simplify_const_relational_operation (enum rtx_code code,
5475 machine_mode mode,
5476 rtx op0, rtx op1)
5477 {
5478 rtx tem;
5479 rtx trueop0;
5480 rtx trueop1;
5481
5482 gcc_assert (mode != VOIDmode
5483 || (GET_MODE (op0) == VOIDmode
5484 && GET_MODE (op1) == VOIDmode));
5485
5486 /* If op0 is a compare, extract the comparison arguments from it. */
5487 if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
5488 {
5489 op1 = XEXP (op0, 1);
5490 op0 = XEXP (op0, 0);
5491
5492 if (GET_MODE (op0) != VOIDmode)
5493 mode = GET_MODE (op0);
5494 else if (GET_MODE (op1) != VOIDmode)
5495 mode = GET_MODE (op1);
5496 else
5497 return 0;
5498 }
5499
5500 /* We can't simplify MODE_CC values since we don't know what the
5501 actual comparison is. */
5502 if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC || CC0_P (op0))
5503 return 0;
5504
5505 /* Make sure the constant is second. */
5506 if (swap_commutative_operands_p (op0, op1))
5507 {
5508 std::swap (op0, op1);
5509 code = swap_condition (code);
5510 }
5511
5512 trueop0 = avoid_constant_pool_reference (op0);
5513 trueop1 = avoid_constant_pool_reference (op1);
5514
5515 /* For integer comparisons of A and B maybe we can simplify A - B and can
5516 then simplify a comparison of that with zero. If A and B are both either
5517 a register or a CONST_INT, this can't help; testing for these cases will
5518 prevent infinite recursion here and speed things up.
5519
5520 We can only do this for EQ and NE comparisons as otherwise we may
5521 lose or introduce overflow which we cannot disregard as undefined as
5522 we do not know the signedness of the operation on either the left or
5523 the right hand side of the comparison. */
5524
5525 if (INTEGRAL_MODE_P (mode) && trueop1 != const0_rtx
5526 && (code == EQ || code == NE)
5527 && ! ((REG_P (op0) || CONST_INT_P (trueop0))
5528 && (REG_P (op1) || CONST_INT_P (trueop1)))
5529 && (tem = simplify_binary_operation (MINUS, mode, op0, op1)) != 0
5530 /* We cannot do this if tem is a nonzero address. */
5531 && ! nonzero_address_p (tem))
5532 return simplify_const_relational_operation (signed_condition (code),
5533 mode, tem, const0_rtx);
5534
5535 if (! HONOR_NANS (mode) && code == ORDERED)
5536 return const_true_rtx;
5537
5538 if (! HONOR_NANS (mode) && code == UNORDERED)
5539 return const0_rtx;
5540
5541 /* For modes without NaNs, if the two operands are equal, we know the
5542 result except if they have side-effects. Even with NaNs we know
5543 the result of unordered comparisons and, if signaling NaNs are
5544 irrelevant, also the result of LT/GT/LTGT. */
5545 if ((! HONOR_NANS (trueop0)
5546 || code == UNEQ || code == UNLE || code == UNGE
5547 || ((code == LT || code == GT || code == LTGT)
5548 && ! HONOR_SNANS (trueop0)))
5549 && rtx_equal_p (trueop0, trueop1)
5550 && ! side_effects_p (trueop0))
5551 return comparison_result (code, CMP_EQ);
5552
5553 /* If the operands are floating-point constants, see if we can fold
5554 the result. */
5555 if (CONST_DOUBLE_AS_FLOAT_P (trueop0)
5556 && CONST_DOUBLE_AS_FLOAT_P (trueop1)
5557 && SCALAR_FLOAT_MODE_P (GET_MODE (trueop0)))
5558 {
5559 const REAL_VALUE_TYPE *d0 = CONST_DOUBLE_REAL_VALUE (trueop0);
5560 const REAL_VALUE_TYPE *d1 = CONST_DOUBLE_REAL_VALUE (trueop1);
5561
5562 /* Comparisons are unordered iff at least one of the values is NaN. */
5563 if (REAL_VALUE_ISNAN (*d0) || REAL_VALUE_ISNAN (*d1))
5564 switch (code)
5565 {
5566 case UNEQ:
5567 case UNLT:
5568 case UNGT:
5569 case UNLE:
5570 case UNGE:
5571 case NE:
5572 case UNORDERED:
5573 return const_true_rtx;
5574 case EQ:
5575 case LT:
5576 case GT:
5577 case LE:
5578 case GE:
5579 case LTGT:
5580 case ORDERED:
5581 return const0_rtx;
5582 default:
5583 return 0;
5584 }
5585
5586 return comparison_result (code,
5587 (real_equal (d0, d1) ? CMP_EQ :
5588 real_less (d0, d1) ? CMP_LT : CMP_GT));
5589 }
5590
5591 /* Otherwise, see if the operands are both integers. */
5592 if ((GET_MODE_CLASS (mode) == MODE_INT || mode == VOIDmode)
5593 && CONST_SCALAR_INT_P (trueop0) && CONST_SCALAR_INT_P (trueop1))
5594 {
5595 /* It would be nice if we really had a mode here. However, the
5596 largest int representable on the target is as good as
5597 infinite. */
5598 machine_mode cmode = (mode == VOIDmode) ? MAX_MODE_INT : mode;
5599 rtx_mode_t ptrueop0 = rtx_mode_t (trueop0, cmode);
5600 rtx_mode_t ptrueop1 = rtx_mode_t (trueop1, cmode);
5601
5602 if (wi::eq_p (ptrueop0, ptrueop1))
5603 return comparison_result (code, CMP_EQ);
5604 else
5605 {
5606 int cr = wi::lts_p (ptrueop0, ptrueop1) ? CMP_LT : CMP_GT;
5607 cr |= wi::ltu_p (ptrueop0, ptrueop1) ? CMP_LTU : CMP_GTU;
5608 return comparison_result (code, cr);
5609 }
5610 }
5611
5612 /* Optimize comparisons with upper and lower bounds. */
5613 scalar_int_mode int_mode;
5614 if (CONST_INT_P (trueop1)
5615 && is_a <scalar_int_mode> (mode, &int_mode)
5616 && HWI_COMPUTABLE_MODE_P (int_mode)
5617 && !side_effects_p (trueop0))
5618 {
5619 int sign;
5620 unsigned HOST_WIDE_INT nonzero = nonzero_bits (trueop0, int_mode);
5621 HOST_WIDE_INT val = INTVAL (trueop1);
5622 HOST_WIDE_INT mmin, mmax;
5623
5624 if (code == GEU
5625 || code == LEU
5626 || code == GTU
5627 || code == LTU)
5628 sign = 0;
5629 else
5630 sign = 1;
5631
5632 /* Get a reduced range if the sign bit is zero. */
5633 if (nonzero <= (GET_MODE_MASK (int_mode) >> 1))
5634 {
5635 mmin = 0;
5636 mmax = nonzero;
5637 }
5638 else
5639 {
5640 rtx mmin_rtx, mmax_rtx;
5641 get_mode_bounds (int_mode, sign, int_mode, &mmin_rtx, &mmax_rtx);
5642
5643 mmin = INTVAL (mmin_rtx);
5644 mmax = INTVAL (mmax_rtx);
5645 if (sign)
5646 {
5647 unsigned int sign_copies
5648 = num_sign_bit_copies (trueop0, int_mode);
5649
5650 mmin >>= (sign_copies - 1);
5651 mmax >>= (sign_copies - 1);
5652 }
5653 }
5654
5655 switch (code)
5656 {
5657 /* x >= y is always true for y <= mmin, always false for y > mmax. */
5658 case GEU:
5659 if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
5660 return const_true_rtx;
5661 if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
5662 return const0_rtx;
5663 break;
5664 case GE:
5665 if (val <= mmin)
5666 return const_true_rtx;
5667 if (val > mmax)
5668 return const0_rtx;
5669 break;
5670
5671 /* x <= y is always true for y >= mmax, always false for y < mmin. */
5672 case LEU:
5673 if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
5674 return const_true_rtx;
5675 if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
5676 return const0_rtx;
5677 break;
5678 case LE:
5679 if (val >= mmax)
5680 return const_true_rtx;
5681 if (val < mmin)
5682 return const0_rtx;
5683 break;
5684
5685 case EQ:
5686 /* x == y is always false for y out of range. */
5687 if (val < mmin || val > mmax)
5688 return const0_rtx;
5689 break;
5690
5691 /* x > y is always false for y >= mmax, always true for y < mmin. */
5692 case GTU:
5693 if ((unsigned HOST_WIDE_INT) val >= (unsigned HOST_WIDE_INT) mmax)
5694 return const0_rtx;
5695 if ((unsigned HOST_WIDE_INT) val < (unsigned HOST_WIDE_INT) mmin)
5696 return const_true_rtx;
5697 break;
5698 case GT:
5699 if (val >= mmax)
5700 return const0_rtx;
5701 if (val < mmin)
5702 return const_true_rtx;
5703 break;
5704
5705 /* x < y is always false for y <= mmin, always true for y > mmax. */
5706 case LTU:
5707 if ((unsigned HOST_WIDE_INT) val <= (unsigned HOST_WIDE_INT) mmin)
5708 return const0_rtx;
5709 if ((unsigned HOST_WIDE_INT) val > (unsigned HOST_WIDE_INT) mmax)
5710 return const_true_rtx;
5711 break;
5712 case LT:
5713 if (val <= mmin)
5714 return const0_rtx;
5715 if (val > mmax)
5716 return const_true_rtx;
5717 break;
5718
5719 case NE:
5720 /* x != y is always true for y out of range. */
5721 if (val < mmin || val > mmax)
5722 return const_true_rtx;
5723 break;
5724
5725 default:
5726 break;
5727 }
5728 }
5729
5730 /* Optimize integer comparisons with zero. */
5731 if (is_a <scalar_int_mode> (mode, &int_mode)
5732 && trueop1 == const0_rtx
5733 && !side_effects_p (trueop0))
5734 {
5735 /* Some addresses are known to be nonzero. We don't know
5736 their sign, but equality comparisons are known. */
5737 if (nonzero_address_p (trueop0))
5738 {
5739 if (code == EQ || code == LEU)
5740 return const0_rtx;
5741 if (code == NE || code == GTU)
5742 return const_true_rtx;
5743 }
5744
5745 /* See if the first operand is an IOR with a constant. If so, we
5746 may be able to determine the result of this comparison. */
5747 if (GET_CODE (op0) == IOR)
5748 {
5749 rtx inner_const = avoid_constant_pool_reference (XEXP (op0, 1));
5750 if (CONST_INT_P (inner_const) && inner_const != const0_rtx)
5751 {
5752 int sign_bitnum = GET_MODE_PRECISION (int_mode) - 1;
5753 int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
5754 && (UINTVAL (inner_const)
5755 & (HOST_WIDE_INT_1U
5756 << sign_bitnum)));
5757
5758 switch (code)
5759 {
5760 case EQ:
5761 case LEU:
5762 return const0_rtx;
5763 case NE:
5764 case GTU:
5765 return const_true_rtx;
5766 case LT:
5767 case LE:
5768 if (has_sign)
5769 return const_true_rtx;
5770 break;
5771 case GT:
5772 case GE:
5773 if (has_sign)
5774 return const0_rtx;
5775 break;
5776 default:
5777 break;
5778 }
5779 }
5780 }
5781 }
5782
5783 /* Optimize comparison of ABS with zero. */
5784 if (trueop1 == CONST0_RTX (mode) && !side_effects_p (trueop0)
5785 && (GET_CODE (trueop0) == ABS
5786 || (GET_CODE (trueop0) == FLOAT_EXTEND
5787 && GET_CODE (XEXP (trueop0, 0)) == ABS)))
5788 {
5789 switch (code)
5790 {
5791 case LT:
5792 /* Optimize abs(x) < 0.0. */
5793 if (!INTEGRAL_MODE_P (mode) && !HONOR_SNANS (mode))
5794 return const0_rtx;
5795 break;
5796
5797 case GE:
5798 /* Optimize abs(x) >= 0.0. */
5799 if (!INTEGRAL_MODE_P (mode) && !HONOR_NANS (mode))
5800 return const_true_rtx;
5801 break;
5802
5803 case UNGE:
5804 /* Optimize ! (abs(x) < 0.0). */
5805 return const_true_rtx;
5806
5807 default:
5808 break;
5809 }
5810 }
5811
5812 return 0;
5813 }
5814
5815 /* Recognize expressions of the form (X CMP 0) ? VAL : OP (X)
5816 where OP is CLZ or CTZ and VAL is the value from CLZ_DEFINED_VALUE_AT_ZERO
5817 or CTZ_DEFINED_VALUE_AT_ZERO respectively and return OP (X) if the expression
5818 can be simplified to that or NULL_RTX if not.
5819 Assume X is compared against zero with CMP_CODE and the true
5820 arm is TRUE_VAL and the false arm is FALSE_VAL. */
5821
5822 static rtx
simplify_cond_clz_ctz(rtx x,rtx_code cmp_code,rtx true_val,rtx false_val)5823 simplify_cond_clz_ctz (rtx x, rtx_code cmp_code, rtx true_val, rtx false_val)
5824 {
5825 if (cmp_code != EQ && cmp_code != NE)
5826 return NULL_RTX;
5827
5828 /* Result on X == 0 and X !=0 respectively. */
5829 rtx on_zero, on_nonzero;
5830 if (cmp_code == EQ)
5831 {
5832 on_zero = true_val;
5833 on_nonzero = false_val;
5834 }
5835 else
5836 {
5837 on_zero = false_val;
5838 on_nonzero = true_val;
5839 }
5840
5841 rtx_code op_code = GET_CODE (on_nonzero);
5842 if ((op_code != CLZ && op_code != CTZ)
5843 || !rtx_equal_p (XEXP (on_nonzero, 0), x)
5844 || !CONST_INT_P (on_zero))
5845 return NULL_RTX;
5846
5847 HOST_WIDE_INT op_val;
5848 scalar_int_mode mode ATTRIBUTE_UNUSED
5849 = as_a <scalar_int_mode> (GET_MODE (XEXP (on_nonzero, 0)));
5850 if (((op_code == CLZ && CLZ_DEFINED_VALUE_AT_ZERO (mode, op_val))
5851 || (op_code == CTZ && CTZ_DEFINED_VALUE_AT_ZERO (mode, op_val)))
5852 && op_val == INTVAL (on_zero))
5853 return on_nonzero;
5854
5855 return NULL_RTX;
5856 }
5857
5858 /* Try to simplify X given that it appears within operand OP of a
5859 VEC_MERGE operation whose mask is MASK. X need not use the same
5860 vector mode as the VEC_MERGE, but it must have the same number of
5861 elements.
5862
5863 Return the simplified X on success, otherwise return NULL_RTX. */
5864
5865 rtx
simplify_merge_mask(rtx x,rtx mask,int op)5866 simplify_merge_mask (rtx x, rtx mask, int op)
5867 {
5868 gcc_assert (VECTOR_MODE_P (GET_MODE (x)));
5869 poly_uint64 nunits = GET_MODE_NUNITS (GET_MODE (x));
5870 if (GET_CODE (x) == VEC_MERGE && rtx_equal_p (XEXP (x, 2), mask))
5871 {
5872 if (side_effects_p (XEXP (x, 1 - op)))
5873 return NULL_RTX;
5874
5875 return XEXP (x, op);
5876 }
5877 if (UNARY_P (x)
5878 && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
5879 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits))
5880 {
5881 rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
5882 if (top0)
5883 return simplify_gen_unary (GET_CODE (x), GET_MODE (x), top0,
5884 GET_MODE (XEXP (x, 0)));
5885 }
5886 if (BINARY_P (x)
5887 && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
5888 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
5889 && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
5890 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits))
5891 {
5892 rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
5893 rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
5894 if (top0 || top1)
5895 {
5896 if (COMPARISON_P (x))
5897 return simplify_gen_relational (GET_CODE (x), GET_MODE (x),
5898 GET_MODE (XEXP (x, 0)) != VOIDmode
5899 ? GET_MODE (XEXP (x, 0))
5900 : GET_MODE (XEXP (x, 1)),
5901 top0 ? top0 : XEXP (x, 0),
5902 top1 ? top1 : XEXP (x, 1));
5903 else
5904 return simplify_gen_binary (GET_CODE (x), GET_MODE (x),
5905 top0 ? top0 : XEXP (x, 0),
5906 top1 ? top1 : XEXP (x, 1));
5907 }
5908 }
5909 if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY
5910 && VECTOR_MODE_P (GET_MODE (XEXP (x, 0)))
5911 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 0))), nunits)
5912 && VECTOR_MODE_P (GET_MODE (XEXP (x, 1)))
5913 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 1))), nunits)
5914 && VECTOR_MODE_P (GET_MODE (XEXP (x, 2)))
5915 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (x, 2))), nunits))
5916 {
5917 rtx top0 = simplify_merge_mask (XEXP (x, 0), mask, op);
5918 rtx top1 = simplify_merge_mask (XEXP (x, 1), mask, op);
5919 rtx top2 = simplify_merge_mask (XEXP (x, 2), mask, op);
5920 if (top0 || top1 || top2)
5921 return simplify_gen_ternary (GET_CODE (x), GET_MODE (x),
5922 GET_MODE (XEXP (x, 0)),
5923 top0 ? top0 : XEXP (x, 0),
5924 top1 ? top1 : XEXP (x, 1),
5925 top2 ? top2 : XEXP (x, 2));
5926 }
5927 return NULL_RTX;
5928 }
5929
5930
5931 /* Simplify CODE, an operation with result mode MODE and three operands,
5932 OP0, OP1, and OP2. OP0_MODE was the mode of OP0 before it became
5933 a constant. Return 0 if no simplifications is possible. */
5934
5935 rtx
simplify_ternary_operation(enum rtx_code code,machine_mode mode,machine_mode op0_mode,rtx op0,rtx op1,rtx op2)5936 simplify_ternary_operation (enum rtx_code code, machine_mode mode,
5937 machine_mode op0_mode, rtx op0, rtx op1,
5938 rtx op2)
5939 {
5940 bool any_change = false;
5941 rtx tem, trueop2;
5942 scalar_int_mode int_mode, int_op0_mode;
5943 unsigned int n_elts;
5944
5945 switch (code)
5946 {
5947 case FMA:
5948 /* Simplify negations around the multiplication. */
5949 /* -a * -b + c => a * b + c. */
5950 if (GET_CODE (op0) == NEG)
5951 {
5952 tem = simplify_unary_operation (NEG, mode, op1, mode);
5953 if (tem)
5954 op1 = tem, op0 = XEXP (op0, 0), any_change = true;
5955 }
5956 else if (GET_CODE (op1) == NEG)
5957 {
5958 tem = simplify_unary_operation (NEG, mode, op0, mode);
5959 if (tem)
5960 op0 = tem, op1 = XEXP (op1, 0), any_change = true;
5961 }
5962
5963 /* Canonicalize the two multiplication operands. */
5964 /* a * -b + c => -b * a + c. */
5965 if (swap_commutative_operands_p (op0, op1))
5966 std::swap (op0, op1), any_change = true;
5967
5968 if (any_change)
5969 return gen_rtx_FMA (mode, op0, op1, op2);
5970 return NULL_RTX;
5971
5972 case SIGN_EXTRACT:
5973 case ZERO_EXTRACT:
5974 if (CONST_INT_P (op0)
5975 && CONST_INT_P (op1)
5976 && CONST_INT_P (op2)
5977 && is_a <scalar_int_mode> (mode, &int_mode)
5978 && INTVAL (op1) + INTVAL (op2) <= GET_MODE_PRECISION (int_mode)
5979 && HWI_COMPUTABLE_MODE_P (int_mode))
5980 {
5981 /* Extracting a bit-field from a constant */
5982 unsigned HOST_WIDE_INT val = UINTVAL (op0);
5983 HOST_WIDE_INT op1val = INTVAL (op1);
5984 HOST_WIDE_INT op2val = INTVAL (op2);
5985 if (!BITS_BIG_ENDIAN)
5986 val >>= op2val;
5987 else if (is_a <scalar_int_mode> (op0_mode, &int_op0_mode))
5988 val >>= GET_MODE_PRECISION (int_op0_mode) - op2val - op1val;
5989 else
5990 /* Not enough information to calculate the bit position. */
5991 break;
5992
5993 if (HOST_BITS_PER_WIDE_INT != op1val)
5994 {
5995 /* First zero-extend. */
5996 val &= (HOST_WIDE_INT_1U << op1val) - 1;
5997 /* If desired, propagate sign bit. */
5998 if (code == SIGN_EXTRACT
5999 && (val & (HOST_WIDE_INT_1U << (op1val - 1)))
6000 != 0)
6001 val |= ~ ((HOST_WIDE_INT_1U << op1val) - 1);
6002 }
6003
6004 return gen_int_mode (val, int_mode);
6005 }
6006 break;
6007
6008 case IF_THEN_ELSE:
6009 if (CONST_INT_P (op0))
6010 return op0 != const0_rtx ? op1 : op2;
6011
6012 /* Convert c ? a : a into "a". */
6013 if (rtx_equal_p (op1, op2) && ! side_effects_p (op0))
6014 return op1;
6015
6016 /* Convert a != b ? a : b into "a". */
6017 if (GET_CODE (op0) == NE
6018 && ! side_effects_p (op0)
6019 && ! HONOR_NANS (mode)
6020 && ! HONOR_SIGNED_ZEROS (mode)
6021 && ((rtx_equal_p (XEXP (op0, 0), op1)
6022 && rtx_equal_p (XEXP (op0, 1), op2))
6023 || (rtx_equal_p (XEXP (op0, 0), op2)
6024 && rtx_equal_p (XEXP (op0, 1), op1))))
6025 return op1;
6026
6027 /* Convert a == b ? a : b into "b". */
6028 if (GET_CODE (op0) == EQ
6029 && ! side_effects_p (op0)
6030 && ! HONOR_NANS (mode)
6031 && ! HONOR_SIGNED_ZEROS (mode)
6032 && ((rtx_equal_p (XEXP (op0, 0), op1)
6033 && rtx_equal_p (XEXP (op0, 1), op2))
6034 || (rtx_equal_p (XEXP (op0, 0), op2)
6035 && rtx_equal_p (XEXP (op0, 1), op1))))
6036 return op2;
6037
6038 /* Convert (!c) != {0,...,0} ? a : b into
6039 c != {0,...,0} ? b : a for vector modes. */
6040 if (VECTOR_MODE_P (GET_MODE (op1))
6041 && GET_CODE (op0) == NE
6042 && GET_CODE (XEXP (op0, 0)) == NOT
6043 && GET_CODE (XEXP (op0, 1)) == CONST_VECTOR)
6044 {
6045 rtx cv = XEXP (op0, 1);
6046 int nunits;
6047 bool ok = true;
6048 if (!CONST_VECTOR_NUNITS (cv).is_constant (&nunits))
6049 ok = false;
6050 else
6051 for (int i = 0; i < nunits; ++i)
6052 if (CONST_VECTOR_ELT (cv, i) != const0_rtx)
6053 {
6054 ok = false;
6055 break;
6056 }
6057 if (ok)
6058 {
6059 rtx new_op0 = gen_rtx_NE (GET_MODE (op0),
6060 XEXP (XEXP (op0, 0), 0),
6061 XEXP (op0, 1));
6062 rtx retval = gen_rtx_IF_THEN_ELSE (mode, new_op0, op2, op1);
6063 return retval;
6064 }
6065 }
6066
6067 /* Convert x == 0 ? N : clz (x) into clz (x) when
6068 CLZ_DEFINED_VALUE_AT_ZERO is defined to N for the mode of x.
6069 Similarly for ctz (x). */
6070 if (COMPARISON_P (op0) && !side_effects_p (op0)
6071 && XEXP (op0, 1) == const0_rtx)
6072 {
6073 rtx simplified
6074 = simplify_cond_clz_ctz (XEXP (op0, 0), GET_CODE (op0),
6075 op1, op2);
6076 if (simplified)
6077 return simplified;
6078 }
6079
6080 if (COMPARISON_P (op0) && ! side_effects_p (op0))
6081 {
6082 machine_mode cmp_mode = (GET_MODE (XEXP (op0, 0)) == VOIDmode
6083 ? GET_MODE (XEXP (op0, 1))
6084 : GET_MODE (XEXP (op0, 0)));
6085 rtx temp;
6086
6087 /* Look for happy constants in op1 and op2. */
6088 if (CONST_INT_P (op1) && CONST_INT_P (op2))
6089 {
6090 HOST_WIDE_INT t = INTVAL (op1);
6091 HOST_WIDE_INT f = INTVAL (op2);
6092
6093 if (t == STORE_FLAG_VALUE && f == 0)
6094 code = GET_CODE (op0);
6095 else if (t == 0 && f == STORE_FLAG_VALUE)
6096 {
6097 enum rtx_code tmp;
6098 tmp = reversed_comparison_code (op0, NULL);
6099 if (tmp == UNKNOWN)
6100 break;
6101 code = tmp;
6102 }
6103 else
6104 break;
6105
6106 return simplify_gen_relational (code, mode, cmp_mode,
6107 XEXP (op0, 0), XEXP (op0, 1));
6108 }
6109
6110 temp = simplify_relational_operation (GET_CODE (op0), op0_mode,
6111 cmp_mode, XEXP (op0, 0),
6112 XEXP (op0, 1));
6113
6114 /* See if any simplifications were possible. */
6115 if (temp)
6116 {
6117 if (CONST_INT_P (temp))
6118 return temp == const0_rtx ? op2 : op1;
6119 else if (temp)
6120 return gen_rtx_IF_THEN_ELSE (mode, temp, op1, op2);
6121 }
6122 }
6123 break;
6124
6125 case VEC_MERGE:
6126 gcc_assert (GET_MODE (op0) == mode);
6127 gcc_assert (GET_MODE (op1) == mode);
6128 gcc_assert (VECTOR_MODE_P (mode));
6129 trueop2 = avoid_constant_pool_reference (op2);
6130 if (CONST_INT_P (trueop2)
6131 && GET_MODE_NUNITS (mode).is_constant (&n_elts))
6132 {
6133 unsigned HOST_WIDE_INT sel = UINTVAL (trueop2);
6134 unsigned HOST_WIDE_INT mask;
6135 if (n_elts == HOST_BITS_PER_WIDE_INT)
6136 mask = -1;
6137 else
6138 mask = (HOST_WIDE_INT_1U << n_elts) - 1;
6139
6140 if (!(sel & mask) && !side_effects_p (op0))
6141 return op1;
6142 if ((sel & mask) == mask && !side_effects_p (op1))
6143 return op0;
6144
6145 rtx trueop0 = avoid_constant_pool_reference (op0);
6146 rtx trueop1 = avoid_constant_pool_reference (op1);
6147 if (GET_CODE (trueop0) == CONST_VECTOR
6148 && GET_CODE (trueop1) == CONST_VECTOR)
6149 {
6150 rtvec v = rtvec_alloc (n_elts);
6151 unsigned int i;
6152
6153 for (i = 0; i < n_elts; i++)
6154 RTVEC_ELT (v, i) = ((sel & (HOST_WIDE_INT_1U << i))
6155 ? CONST_VECTOR_ELT (trueop0, i)
6156 : CONST_VECTOR_ELT (trueop1, i));
6157 return gen_rtx_CONST_VECTOR (mode, v);
6158 }
6159
6160 /* Replace (vec_merge (vec_merge a b m) c n) with (vec_merge b c n)
6161 if no element from a appears in the result. */
6162 if (GET_CODE (op0) == VEC_MERGE)
6163 {
6164 tem = avoid_constant_pool_reference (XEXP (op0, 2));
6165 if (CONST_INT_P (tem))
6166 {
6167 unsigned HOST_WIDE_INT sel0 = UINTVAL (tem);
6168 if (!(sel & sel0 & mask) && !side_effects_p (XEXP (op0, 0)))
6169 return simplify_gen_ternary (code, mode, mode,
6170 XEXP (op0, 1), op1, op2);
6171 if (!(sel & ~sel0 & mask) && !side_effects_p (XEXP (op0, 1)))
6172 return simplify_gen_ternary (code, mode, mode,
6173 XEXP (op0, 0), op1, op2);
6174 }
6175 }
6176 if (GET_CODE (op1) == VEC_MERGE)
6177 {
6178 tem = avoid_constant_pool_reference (XEXP (op1, 2));
6179 if (CONST_INT_P (tem))
6180 {
6181 unsigned HOST_WIDE_INT sel1 = UINTVAL (tem);
6182 if (!(~sel & sel1 & mask) && !side_effects_p (XEXP (op1, 0)))
6183 return simplify_gen_ternary (code, mode, mode,
6184 op0, XEXP (op1, 1), op2);
6185 if (!(~sel & ~sel1 & mask) && !side_effects_p (XEXP (op1, 1)))
6186 return simplify_gen_ternary (code, mode, mode,
6187 op0, XEXP (op1, 0), op2);
6188 }
6189 }
6190
6191 /* Replace (vec_merge (vec_duplicate (vec_select a parallel (i))) a 1 << i)
6192 with a. */
6193 if (GET_CODE (op0) == VEC_DUPLICATE
6194 && GET_CODE (XEXP (op0, 0)) == VEC_SELECT
6195 && GET_CODE (XEXP (XEXP (op0, 0), 1)) == PARALLEL
6196 && known_eq (GET_MODE_NUNITS (GET_MODE (XEXP (op0, 0))), 1))
6197 {
6198 tem = XVECEXP ((XEXP (XEXP (op0, 0), 1)), 0, 0);
6199 if (CONST_INT_P (tem) && CONST_INT_P (op2))
6200 {
6201 if (XEXP (XEXP (op0, 0), 0) == op1
6202 && UINTVAL (op2) == HOST_WIDE_INT_1U << UINTVAL (tem))
6203 return op1;
6204 }
6205 }
6206 /* Replace (vec_merge (vec_duplicate (X)) (const_vector [A, B])
6207 (const_int N))
6208 with (vec_concat (X) (B)) if N == 1 or
6209 (vec_concat (A) (X)) if N == 2. */
6210 if (GET_CODE (op0) == VEC_DUPLICATE
6211 && GET_CODE (op1) == CONST_VECTOR
6212 && known_eq (CONST_VECTOR_NUNITS (op1), 2)
6213 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6214 && IN_RANGE (sel, 1, 2))
6215 {
6216 rtx newop0 = XEXP (op0, 0);
6217 rtx newop1 = CONST_VECTOR_ELT (op1, 2 - sel);
6218 if (sel == 2)
6219 std::swap (newop0, newop1);
6220 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6221 }
6222 /* Replace (vec_merge (vec_duplicate x) (vec_concat (y) (z)) (const_int N))
6223 with (vec_concat x z) if N == 1, or (vec_concat y x) if N == 2.
6224 Only applies for vectors of two elements. */
6225 if (GET_CODE (op0) == VEC_DUPLICATE
6226 && GET_CODE (op1) == VEC_CONCAT
6227 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6228 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6229 && IN_RANGE (sel, 1, 2))
6230 {
6231 rtx newop0 = XEXP (op0, 0);
6232 rtx newop1 = XEXP (op1, 2 - sel);
6233 rtx otherop = XEXP (op1, sel - 1);
6234 if (sel == 2)
6235 std::swap (newop0, newop1);
6236 /* Don't want to throw away the other part of the vec_concat if
6237 it has side-effects. */
6238 if (!side_effects_p (otherop))
6239 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6240 }
6241
6242 /* Replace:
6243
6244 (vec_merge:outer (vec_duplicate:outer x:inner)
6245 (subreg:outer y:inner 0)
6246 (const_int N))
6247
6248 with (vec_concat:outer x:inner y:inner) if N == 1,
6249 or (vec_concat:outer y:inner x:inner) if N == 2.
6250
6251 Implicitly, this means we have a paradoxical subreg, but such
6252 a check is cheap, so make it anyway.
6253
6254 Only applies for vectors of two elements. */
6255 if (GET_CODE (op0) == VEC_DUPLICATE
6256 && GET_CODE (op1) == SUBREG
6257 && GET_MODE (op1) == GET_MODE (op0)
6258 && GET_MODE (SUBREG_REG (op1)) == GET_MODE (XEXP (op0, 0))
6259 && paradoxical_subreg_p (op1)
6260 && subreg_lowpart_p (op1)
6261 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6262 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6263 && IN_RANGE (sel, 1, 2))
6264 {
6265 rtx newop0 = XEXP (op0, 0);
6266 rtx newop1 = SUBREG_REG (op1);
6267 if (sel == 2)
6268 std::swap (newop0, newop1);
6269 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6270 }
6271
6272 /* Same as above but with switched operands:
6273 Replace (vec_merge:outer (subreg:outer x:inner 0)
6274 (vec_duplicate:outer y:inner)
6275 (const_int N))
6276
6277 with (vec_concat:outer x:inner y:inner) if N == 1,
6278 or (vec_concat:outer y:inner x:inner) if N == 2. */
6279 if (GET_CODE (op1) == VEC_DUPLICATE
6280 && GET_CODE (op0) == SUBREG
6281 && GET_MODE (op0) == GET_MODE (op1)
6282 && GET_MODE (SUBREG_REG (op0)) == GET_MODE (XEXP (op1, 0))
6283 && paradoxical_subreg_p (op0)
6284 && subreg_lowpart_p (op0)
6285 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6286 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6287 && IN_RANGE (sel, 1, 2))
6288 {
6289 rtx newop0 = SUBREG_REG (op0);
6290 rtx newop1 = XEXP (op1, 0);
6291 if (sel == 2)
6292 std::swap (newop0, newop1);
6293 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6294 }
6295
6296 /* Replace (vec_merge (vec_duplicate x) (vec_duplicate y)
6297 (const_int n))
6298 with (vec_concat x y) or (vec_concat y x) depending on value
6299 of N. */
6300 if (GET_CODE (op0) == VEC_DUPLICATE
6301 && GET_CODE (op1) == VEC_DUPLICATE
6302 && known_eq (GET_MODE_NUNITS (GET_MODE (op0)), 2)
6303 && known_eq (GET_MODE_NUNITS (GET_MODE (op1)), 2)
6304 && IN_RANGE (sel, 1, 2))
6305 {
6306 rtx newop0 = XEXP (op0, 0);
6307 rtx newop1 = XEXP (op1, 0);
6308 if (sel == 2)
6309 std::swap (newop0, newop1);
6310
6311 return simplify_gen_binary (VEC_CONCAT, mode, newop0, newop1);
6312 }
6313 }
6314
6315 if (rtx_equal_p (op0, op1)
6316 && !side_effects_p (op2) && !side_effects_p (op1))
6317 return op0;
6318
6319 if (!side_effects_p (op2))
6320 {
6321 rtx top0
6322 = may_trap_p (op0) ? NULL_RTX : simplify_merge_mask (op0, op2, 0);
6323 rtx top1
6324 = may_trap_p (op1) ? NULL_RTX : simplify_merge_mask (op1, op2, 1);
6325 if (top0 || top1)
6326 return simplify_gen_ternary (code, mode, mode,
6327 top0 ? top0 : op0,
6328 top1 ? top1 : op1, op2);
6329 }
6330
6331 break;
6332
6333 default:
6334 gcc_unreachable ();
6335 }
6336
6337 return 0;
6338 }
6339
6340 /* Try to calculate NUM_BYTES bytes of the target memory image of X,
6341 starting at byte FIRST_BYTE. Return true on success and add the
6342 bytes to BYTES, such that each byte has BITS_PER_UNIT bits and such
6343 that the bytes follow target memory order. Leave BYTES unmodified
6344 on failure.
6345
6346 MODE is the mode of X. The caller must reserve NUM_BYTES bytes in
6347 BYTES before calling this function. */
6348
6349 bool
native_encode_rtx(machine_mode mode,rtx x,vec<target_unit> & bytes,unsigned int first_byte,unsigned int num_bytes)6350 native_encode_rtx (machine_mode mode, rtx x, vec<target_unit> &bytes,
6351 unsigned int first_byte, unsigned int num_bytes)
6352 {
6353 /* Check the mode is sensible. */
6354 gcc_assert (GET_MODE (x) == VOIDmode
6355 ? is_a <scalar_int_mode> (mode)
6356 : mode == GET_MODE (x));
6357
6358 if (GET_CODE (x) == CONST_VECTOR)
6359 {
6360 /* CONST_VECTOR_ELT follows target memory order, so no shuffling
6361 is necessary. The only complication is that MODE_VECTOR_BOOL
6362 vectors can have several elements per byte. */
6363 unsigned int elt_bits = vector_element_size (GET_MODE_BITSIZE (mode),
6364 GET_MODE_NUNITS (mode));
6365 unsigned int elt = first_byte * BITS_PER_UNIT / elt_bits;
6366 if (elt_bits < BITS_PER_UNIT)
6367 {
6368 /* This is the only case in which elements can be smaller than
6369 a byte. */
6370 gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
6371 for (unsigned int i = 0; i < num_bytes; ++i)
6372 {
6373 target_unit value = 0;
6374 for (unsigned int j = 0; j < BITS_PER_UNIT; j += elt_bits)
6375 {
6376 value |= (INTVAL (CONST_VECTOR_ELT (x, elt)) & 1) << j;
6377 elt += 1;
6378 }
6379 bytes.quick_push (value);
6380 }
6381 return true;
6382 }
6383
6384 unsigned int start = bytes.length ();
6385 unsigned int elt_bytes = GET_MODE_UNIT_SIZE (mode);
6386 /* Make FIRST_BYTE relative to ELT. */
6387 first_byte %= elt_bytes;
6388 while (num_bytes > 0)
6389 {
6390 /* Work out how many bytes we want from element ELT. */
6391 unsigned int chunk_bytes = MIN (num_bytes, elt_bytes - first_byte);
6392 if (!native_encode_rtx (GET_MODE_INNER (mode),
6393 CONST_VECTOR_ELT (x, elt), bytes,
6394 first_byte, chunk_bytes))
6395 {
6396 bytes.truncate (start);
6397 return false;
6398 }
6399 elt += 1;
6400 first_byte = 0;
6401 num_bytes -= chunk_bytes;
6402 }
6403 return true;
6404 }
6405
6406 /* All subsequent cases are limited to scalars. */
6407 scalar_mode smode;
6408 if (!is_a <scalar_mode> (mode, &smode))
6409 return false;
6410
6411 /* Make sure that the region is in range. */
6412 unsigned int end_byte = first_byte + num_bytes;
6413 unsigned int mode_bytes = GET_MODE_SIZE (smode);
6414 gcc_assert (end_byte <= mode_bytes);
6415
6416 if (CONST_SCALAR_INT_P (x))
6417 {
6418 /* The target memory layout is affected by both BYTES_BIG_ENDIAN
6419 and WORDS_BIG_ENDIAN. Use the subreg machinery to get the lsb
6420 position of each byte. */
6421 rtx_mode_t value (x, smode);
6422 wide_int_ref value_wi (value);
6423 for (unsigned int byte = first_byte; byte < end_byte; ++byte)
6424 {
6425 /* Always constant because the inputs are. */
6426 unsigned int lsb
6427 = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
6428 /* Operate directly on the encoding rather than using
6429 wi::extract_uhwi, so that we preserve the sign or zero
6430 extension for modes that are not a whole number of bits in
6431 size. (Zero extension is only used for the combination of
6432 innermode == BImode && STORE_FLAG_VALUE == 1). */
6433 unsigned int elt = lsb / HOST_BITS_PER_WIDE_INT;
6434 unsigned int shift = lsb % HOST_BITS_PER_WIDE_INT;
6435 unsigned HOST_WIDE_INT uhwi = value_wi.elt (elt);
6436 bytes.quick_push (uhwi >> shift);
6437 }
6438 return true;
6439 }
6440
6441 if (CONST_DOUBLE_P (x))
6442 {
6443 /* real_to_target produces an array of integers in target memory order.
6444 All integers before the last one have 32 bits; the last one may
6445 have 32 bits or fewer, depending on whether the mode bitsize
6446 is divisible by 32. Each of these integers is then laid out
6447 in target memory as any other integer would be. */
6448 long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
6449 real_to_target (el32, CONST_DOUBLE_REAL_VALUE (x), smode);
6450
6451 /* The (maximum) number of target bytes per element of el32. */
6452 unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
6453 gcc_assert (bytes_per_el32 != 0);
6454
6455 /* Build up the integers in a similar way to the CONST_SCALAR_INT_P
6456 handling above. */
6457 for (unsigned int byte = first_byte; byte < end_byte; ++byte)
6458 {
6459 unsigned int index = byte / bytes_per_el32;
6460 unsigned int subbyte = byte % bytes_per_el32;
6461 unsigned int int_bytes = MIN (bytes_per_el32,
6462 mode_bytes - index * bytes_per_el32);
6463 /* Always constant because the inputs are. */
6464 unsigned int lsb
6465 = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
6466 bytes.quick_push ((unsigned long) el32[index] >> lsb);
6467 }
6468 return true;
6469 }
6470
6471 if (GET_CODE (x) == CONST_FIXED)
6472 {
6473 for (unsigned int byte = first_byte; byte < end_byte; ++byte)
6474 {
6475 /* Always constant because the inputs are. */
6476 unsigned int lsb
6477 = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
6478 unsigned HOST_WIDE_INT piece = CONST_FIXED_VALUE_LOW (x);
6479 if (lsb >= HOST_BITS_PER_WIDE_INT)
6480 {
6481 lsb -= HOST_BITS_PER_WIDE_INT;
6482 piece = CONST_FIXED_VALUE_HIGH (x);
6483 }
6484 bytes.quick_push (piece >> lsb);
6485 }
6486 return true;
6487 }
6488
6489 return false;
6490 }
6491
6492 /* Read a vector of mode MODE from the target memory image given by BYTES,
6493 starting at byte FIRST_BYTE. The vector is known to be encodable using
6494 NPATTERNS interleaved patterns with NELTS_PER_PATTERN elements each,
6495 and BYTES is known to have enough bytes to supply NPATTERNS *
6496 NELTS_PER_PATTERN vector elements. Each element of BYTES contains
6497 BITS_PER_UNIT bits and the bytes are in target memory order.
6498
6499 Return the vector on success, otherwise return NULL_RTX. */
6500
6501 rtx
native_decode_vector_rtx(machine_mode mode,vec<target_unit> bytes,unsigned int first_byte,unsigned int npatterns,unsigned int nelts_per_pattern)6502 native_decode_vector_rtx (machine_mode mode, vec<target_unit> bytes,
6503 unsigned int first_byte, unsigned int npatterns,
6504 unsigned int nelts_per_pattern)
6505 {
6506 rtx_vector_builder builder (mode, npatterns, nelts_per_pattern);
6507
6508 unsigned int elt_bits = vector_element_size (GET_MODE_BITSIZE (mode),
6509 GET_MODE_NUNITS (mode));
6510 if (elt_bits < BITS_PER_UNIT)
6511 {
6512 /* This is the only case in which elements can be smaller than a byte.
6513 Element 0 is always in the lsb of the containing byte. */
6514 gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
6515 for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
6516 {
6517 unsigned int bit_index = first_byte * BITS_PER_UNIT + i * elt_bits;
6518 unsigned int byte_index = bit_index / BITS_PER_UNIT;
6519 unsigned int lsb = bit_index % BITS_PER_UNIT;
6520 builder.quick_push (bytes[byte_index] & (1 << lsb)
6521 ? CONST1_RTX (BImode)
6522 : CONST0_RTX (BImode));
6523 }
6524 }
6525 else
6526 {
6527 for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
6528 {
6529 rtx x = native_decode_rtx (GET_MODE_INNER (mode), bytes, first_byte);
6530 if (!x)
6531 return NULL_RTX;
6532 builder.quick_push (x);
6533 first_byte += elt_bits / BITS_PER_UNIT;
6534 }
6535 }
6536 return builder.build ();
6537 }
6538
6539 /* Read an rtx of mode MODE from the target memory image given by BYTES,
6540 starting at byte FIRST_BYTE. Each element of BYTES contains BITS_PER_UNIT
6541 bits and the bytes are in target memory order. The image has enough
6542 values to specify all bytes of MODE.
6543
6544 Return the rtx on success, otherwise return NULL_RTX. */
6545
6546 rtx
native_decode_rtx(machine_mode mode,vec<target_unit> bytes,unsigned int first_byte)6547 native_decode_rtx (machine_mode mode, vec<target_unit> bytes,
6548 unsigned int first_byte)
6549 {
6550 if (VECTOR_MODE_P (mode))
6551 {
6552 /* If we know at compile time how many elements there are,
6553 pull each element directly from BYTES. */
6554 unsigned int nelts;
6555 if (GET_MODE_NUNITS (mode).is_constant (&nelts))
6556 return native_decode_vector_rtx (mode, bytes, first_byte, nelts, 1);
6557 return NULL_RTX;
6558 }
6559
6560 scalar_int_mode imode;
6561 if (is_a <scalar_int_mode> (mode, &imode)
6562 && GET_MODE_PRECISION (imode) <= MAX_BITSIZE_MODE_ANY_INT)
6563 {
6564 /* Pull the bytes msb first, so that we can use simple
6565 shift-and-insert wide_int operations. */
6566 unsigned int size = GET_MODE_SIZE (imode);
6567 wide_int result (wi::zero (GET_MODE_PRECISION (imode)));
6568 for (unsigned int i = 0; i < size; ++i)
6569 {
6570 unsigned int lsb = (size - i - 1) * BITS_PER_UNIT;
6571 /* Always constant because the inputs are. */
6572 unsigned int subbyte
6573 = subreg_size_offset_from_lsb (1, size, lsb).to_constant ();
6574 result <<= BITS_PER_UNIT;
6575 result |= bytes[first_byte + subbyte];
6576 }
6577 return immed_wide_int_const (result, imode);
6578 }
6579
6580 scalar_float_mode fmode;
6581 if (is_a <scalar_float_mode> (mode, &fmode))
6582 {
6583 /* We need to build an array of integers in target memory order.
6584 All integers before the last one have 32 bits; the last one may
6585 have 32 bits or fewer, depending on whether the mode bitsize
6586 is divisible by 32. */
6587 long el32[MAX_BITSIZE_MODE_ANY_MODE / 32];
6588 unsigned int num_el32 = CEIL (GET_MODE_BITSIZE (fmode), 32);
6589 memset (el32, 0, num_el32 * sizeof (long));
6590
6591 /* The (maximum) number of target bytes per element of el32. */
6592 unsigned int bytes_per_el32 = 32 / BITS_PER_UNIT;
6593 gcc_assert (bytes_per_el32 != 0);
6594
6595 unsigned int mode_bytes = GET_MODE_SIZE (fmode);
6596 for (unsigned int byte = 0; byte < mode_bytes; ++byte)
6597 {
6598 unsigned int index = byte / bytes_per_el32;
6599 unsigned int subbyte = byte % bytes_per_el32;
6600 unsigned int int_bytes = MIN (bytes_per_el32,
6601 mode_bytes - index * bytes_per_el32);
6602 /* Always constant because the inputs are. */
6603 unsigned int lsb
6604 = subreg_size_lsb (1, int_bytes, subbyte).to_constant ();
6605 el32[index] |= (unsigned long) bytes[first_byte + byte] << lsb;
6606 }
6607 REAL_VALUE_TYPE r;
6608 real_from_target (&r, el32, fmode);
6609 return const_double_from_real_value (r, fmode);
6610 }
6611
6612 if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
6613 {
6614 scalar_mode smode = as_a <scalar_mode> (mode);
6615 FIXED_VALUE_TYPE f;
6616 f.data.low = 0;
6617 f.data.high = 0;
6618 f.mode = smode;
6619
6620 unsigned int mode_bytes = GET_MODE_SIZE (smode);
6621 for (unsigned int byte = 0; byte < mode_bytes; ++byte)
6622 {
6623 /* Always constant because the inputs are. */
6624 unsigned int lsb
6625 = subreg_size_lsb (1, mode_bytes, byte).to_constant ();
6626 unsigned HOST_WIDE_INT unit = bytes[first_byte + byte];
6627 if (lsb >= HOST_BITS_PER_WIDE_INT)
6628 f.data.high |= unit << (lsb - HOST_BITS_PER_WIDE_INT);
6629 else
6630 f.data.low |= unit << lsb;
6631 }
6632 return CONST_FIXED_FROM_FIXED_VALUE (f, mode);
6633 }
6634
6635 return NULL_RTX;
6636 }
6637
6638 /* Simplify a byte offset BYTE into CONST_VECTOR X. The main purpose
6639 is to convert a runtime BYTE value into a constant one. */
6640
6641 static poly_uint64
simplify_const_vector_byte_offset(rtx x,poly_uint64 byte)6642 simplify_const_vector_byte_offset (rtx x, poly_uint64 byte)
6643 {
6644 /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
6645 machine_mode mode = GET_MODE (x);
6646 unsigned int elt_bits = vector_element_size (GET_MODE_BITSIZE (mode),
6647 GET_MODE_NUNITS (mode));
6648 /* The number of bits needed to encode one element from each pattern. */
6649 unsigned int sequence_bits = CONST_VECTOR_NPATTERNS (x) * elt_bits;
6650
6651 /* Identify the start point in terms of a sequence number and a byte offset
6652 within that sequence. */
6653 poly_uint64 first_sequence;
6654 unsigned HOST_WIDE_INT subbit;
6655 if (can_div_trunc_p (byte * BITS_PER_UNIT, sequence_bits,
6656 &first_sequence, &subbit))
6657 {
6658 unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
6659 if (nelts_per_pattern == 1)
6660 /* This is a duplicated vector, so the value of FIRST_SEQUENCE
6661 doesn't matter. */
6662 byte = subbit / BITS_PER_UNIT;
6663 else if (nelts_per_pattern == 2 && known_gt (first_sequence, 0U))
6664 {
6665 /* The subreg drops the first element from each pattern and
6666 only uses the second element. Find the first sequence
6667 that starts on a byte boundary. */
6668 subbit += least_common_multiple (sequence_bits, BITS_PER_UNIT);
6669 byte = subbit / BITS_PER_UNIT;
6670 }
6671 }
6672 return byte;
6673 }
6674
6675 /* Subroutine of simplify_subreg in which:
6676
6677 - X is known to be a CONST_VECTOR
6678 - OUTERMODE is known to be a vector mode
6679
6680 Try to handle the subreg by operating on the CONST_VECTOR encoding
6681 rather than on each individual element of the CONST_VECTOR.
6682
6683 Return the simplified subreg on success, otherwise return NULL_RTX. */
6684
6685 static rtx
simplify_const_vector_subreg(machine_mode outermode,rtx x,machine_mode innermode,unsigned int first_byte)6686 simplify_const_vector_subreg (machine_mode outermode, rtx x,
6687 machine_mode innermode, unsigned int first_byte)
6688 {
6689 /* Paradoxical subregs of vectors have dubious semantics. */
6690 if (paradoxical_subreg_p (outermode, innermode))
6691 return NULL_RTX;
6692
6693 /* We can only preserve the semantics of a stepped pattern if the new
6694 vector element is the same as the original one. */
6695 if (CONST_VECTOR_STEPPED_P (x)
6696 && GET_MODE_INNER (outermode) != GET_MODE_INNER (innermode))
6697 return NULL_RTX;
6698
6699 /* Cope with MODE_VECTOR_BOOL by operating on bits rather than bytes. */
6700 unsigned int x_elt_bits
6701 = vector_element_size (GET_MODE_BITSIZE (innermode),
6702 GET_MODE_NUNITS (innermode));
6703 unsigned int out_elt_bits
6704 = vector_element_size (GET_MODE_BITSIZE (outermode),
6705 GET_MODE_NUNITS (outermode));
6706
6707 /* The number of bits needed to encode one element from every pattern
6708 of the original vector. */
6709 unsigned int x_sequence_bits = CONST_VECTOR_NPATTERNS (x) * x_elt_bits;
6710
6711 /* The number of bits needed to encode one element from every pattern
6712 of the result. */
6713 unsigned int out_sequence_bits
6714 = least_common_multiple (x_sequence_bits, out_elt_bits);
6715
6716 /* Work out the number of interleaved patterns in the output vector
6717 and the number of encoded elements per pattern. */
6718 unsigned int out_npatterns = out_sequence_bits / out_elt_bits;
6719 unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
6720
6721 /* The encoding scheme requires the number of elements to be a multiple
6722 of the number of patterns, so that each pattern appears at least once
6723 and so that the same number of elements appear from each pattern. */
6724 bool ok_p = multiple_p (GET_MODE_NUNITS (outermode), out_npatterns);
6725 unsigned int const_nunits;
6726 if (GET_MODE_NUNITS (outermode).is_constant (&const_nunits)
6727 && (!ok_p || out_npatterns * nelts_per_pattern > const_nunits))
6728 {
6729 /* Either the encoding is invalid, or applying it would give us
6730 more elements than we need. Just encode each element directly. */
6731 out_npatterns = const_nunits;
6732 nelts_per_pattern = 1;
6733 }
6734 else if (!ok_p)
6735 return NULL_RTX;
6736
6737 /* Get enough bytes of X to form the new encoding. */
6738 unsigned int buffer_bits = out_npatterns * nelts_per_pattern * out_elt_bits;
6739 unsigned int buffer_bytes = CEIL (buffer_bits, BITS_PER_UNIT);
6740 auto_vec<target_unit, 128> buffer (buffer_bytes);
6741 if (!native_encode_rtx (innermode, x, buffer, first_byte, buffer_bytes))
6742 return NULL_RTX;
6743
6744 /* Reencode the bytes as OUTERMODE. */
6745 return native_decode_vector_rtx (outermode, buffer, 0, out_npatterns,
6746 nelts_per_pattern);
6747 }
6748
6749 /* Try to simplify a subreg of a constant by encoding the subreg region
6750 as a sequence of target bytes and reading them back in the new mode.
6751 Return the new value on success, otherwise return null.
6752
6753 The subreg has outer mode OUTERMODE, inner mode INNERMODE, inner value X
6754 and byte offset FIRST_BYTE. */
6755
6756 static rtx
simplify_immed_subreg(fixed_size_mode outermode,rtx x,machine_mode innermode,unsigned int first_byte)6757 simplify_immed_subreg (fixed_size_mode outermode, rtx x,
6758 machine_mode innermode, unsigned int first_byte)
6759 {
6760 unsigned int buffer_bytes = GET_MODE_SIZE (outermode);
6761 auto_vec<target_unit, 128> buffer (buffer_bytes);
6762
6763 /* Some ports misuse CCmode. */
6764 if (GET_MODE_CLASS (outermode) == MODE_CC && CONST_INT_P (x))
6765 return x;
6766
6767 /* Paradoxical subregs read undefined values for bytes outside of the
6768 inner value. However, we have traditionally always sign-extended
6769 integer constants and zero-extended others. */
6770 unsigned int inner_bytes = buffer_bytes;
6771 if (paradoxical_subreg_p (outermode, innermode))
6772 {
6773 if (!GET_MODE_SIZE (innermode).is_constant (&inner_bytes))
6774 return NULL_RTX;
6775
6776 target_unit filler = 0;
6777 if (CONST_SCALAR_INT_P (x) && wi::neg_p (rtx_mode_t (x, innermode)))
6778 filler = -1;
6779
6780 /* Add any leading bytes due to big-endian layout. The number of
6781 bytes must be constant because both modes have constant size. */
6782 unsigned int leading_bytes
6783 = -byte_lowpart_offset (outermode, innermode).to_constant ();
6784 for (unsigned int i = 0; i < leading_bytes; ++i)
6785 buffer.quick_push (filler);
6786
6787 if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
6788 return NULL_RTX;
6789
6790 /* Add any trailing bytes due to little-endian layout. */
6791 while (buffer.length () < buffer_bytes)
6792 buffer.quick_push (filler);
6793 }
6794 else
6795 {
6796 if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes))
6797 return NULL_RTX;
6798 }
6799 return native_decode_rtx (outermode, buffer, 0);
6800 }
6801
6802 /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE)
6803 Return 0 if no simplifications are possible. */
6804 rtx
simplify_subreg(machine_mode outermode,rtx op,machine_mode innermode,poly_uint64 byte)6805 simplify_subreg (machine_mode outermode, rtx op,
6806 machine_mode innermode, poly_uint64 byte)
6807 {
6808 /* Little bit of sanity checking. */
6809 gcc_assert (innermode != VOIDmode);
6810 gcc_assert (outermode != VOIDmode);
6811 gcc_assert (innermode != BLKmode);
6812 gcc_assert (outermode != BLKmode);
6813
6814 gcc_assert (GET_MODE (op) == innermode
6815 || GET_MODE (op) == VOIDmode);
6816
6817 poly_uint64 outersize = GET_MODE_SIZE (outermode);
6818 if (!multiple_p (byte, outersize))
6819 return NULL_RTX;
6820
6821 poly_uint64 innersize = GET_MODE_SIZE (innermode);
6822 if (maybe_ge (byte, innersize))
6823 return NULL_RTX;
6824
6825 if (outermode == innermode && known_eq (byte, 0U))
6826 return op;
6827
6828 if (GET_CODE (op) == CONST_VECTOR)
6829 byte = simplify_const_vector_byte_offset (op, byte);
6830
6831 if (multiple_p (byte, GET_MODE_UNIT_SIZE (innermode)))
6832 {
6833 rtx elt;
6834
6835 if (VECTOR_MODE_P (outermode)
6836 && GET_MODE_INNER (outermode) == GET_MODE_INNER (innermode)
6837 && vec_duplicate_p (op, &elt))
6838 return gen_vec_duplicate (outermode, elt);
6839
6840 if (outermode == GET_MODE_INNER (innermode)
6841 && vec_duplicate_p (op, &elt))
6842 return elt;
6843 }
6844
6845 if (CONST_SCALAR_INT_P (op)
6846 || CONST_DOUBLE_AS_FLOAT_P (op)
6847 || CONST_FIXED_P (op)
6848 || GET_CODE (op) == CONST_VECTOR)
6849 {
6850 unsigned HOST_WIDE_INT cbyte;
6851 if (byte.is_constant (&cbyte))
6852 {
6853 if (GET_CODE (op) == CONST_VECTOR && VECTOR_MODE_P (outermode))
6854 {
6855 rtx tmp = simplify_const_vector_subreg (outermode, op,
6856 innermode, cbyte);
6857 if (tmp)
6858 return tmp;
6859 }
6860
6861 fixed_size_mode fs_outermode;
6862 if (is_a <fixed_size_mode> (outermode, &fs_outermode))
6863 return simplify_immed_subreg (fs_outermode, op, innermode, cbyte);
6864 }
6865 }
6866
6867 /* Changing mode twice with SUBREG => just change it once,
6868 or not at all if changing back op starting mode. */
6869 if (GET_CODE (op) == SUBREG)
6870 {
6871 machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
6872 poly_uint64 innermostsize = GET_MODE_SIZE (innermostmode);
6873 rtx newx;
6874
6875 if (outermode == innermostmode
6876 && known_eq (byte, 0U)
6877 && known_eq (SUBREG_BYTE (op), 0))
6878 return SUBREG_REG (op);
6879
6880 /* Work out the memory offset of the final OUTERMODE value relative
6881 to the inner value of OP. */
6882 poly_int64 mem_offset = subreg_memory_offset (outermode,
6883 innermode, byte);
6884 poly_int64 op_mem_offset = subreg_memory_offset (op);
6885 poly_int64 final_offset = mem_offset + op_mem_offset;
6886
6887 /* See whether resulting subreg will be paradoxical. */
6888 if (!paradoxical_subreg_p (outermode, innermostmode))
6889 {
6890 /* Bail out in case resulting subreg would be incorrect. */
6891 if (maybe_lt (final_offset, 0)
6892 || maybe_ge (poly_uint64 (final_offset), innermostsize)
6893 || !multiple_p (final_offset, outersize))
6894 return NULL_RTX;
6895 }
6896 else
6897 {
6898 poly_int64 required_offset = subreg_memory_offset (outermode,
6899 innermostmode, 0);
6900 if (maybe_ne (final_offset, required_offset))
6901 return NULL_RTX;
6902 /* Paradoxical subregs always have byte offset 0. */
6903 final_offset = 0;
6904 }
6905
6906 /* Recurse for further possible simplifications. */
6907 newx = simplify_subreg (outermode, SUBREG_REG (op), innermostmode,
6908 final_offset);
6909 if (newx)
6910 return newx;
6911 if (validate_subreg (outermode, innermostmode,
6912 SUBREG_REG (op), final_offset))
6913 {
6914 newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset);
6915 if (SUBREG_PROMOTED_VAR_P (op)
6916 && SUBREG_PROMOTED_SIGN (op) >= 0
6917 && GET_MODE_CLASS (outermode) == MODE_INT
6918 && known_ge (outersize, innersize)
6919 && known_le (outersize, innermostsize)
6920 && subreg_lowpart_p (newx))
6921 {
6922 SUBREG_PROMOTED_VAR_P (newx) = 1;
6923 SUBREG_PROMOTED_SET (newx, SUBREG_PROMOTED_GET (op));
6924 }
6925 return newx;
6926 }
6927 return NULL_RTX;
6928 }
6929
6930 /* SUBREG of a hard register => just change the register number
6931 and/or mode. If the hard register is not valid in that mode,
6932 suppress this simplification. If the hard register is the stack,
6933 frame, or argument pointer, leave this as a SUBREG. */
6934
6935 if (REG_P (op) && HARD_REGISTER_P (op))
6936 {
6937 unsigned int regno, final_regno;
6938
6939 regno = REGNO (op);
6940 final_regno = simplify_subreg_regno (regno, innermode, byte, outermode);
6941 if (HARD_REGISTER_NUM_P (final_regno))
6942 {
6943 rtx x = gen_rtx_REG_offset (op, outermode, final_regno,
6944 subreg_memory_offset (outermode,
6945 innermode, byte));
6946
6947 /* Propagate original regno. We don't have any way to specify
6948 the offset inside original regno, so do so only for lowpart.
6949 The information is used only by alias analysis that cannot
6950 grog partial register anyway. */
6951
6952 if (known_eq (subreg_lowpart_offset (outermode, innermode), byte))
6953 ORIGINAL_REGNO (x) = ORIGINAL_REGNO (op);
6954 return x;
6955 }
6956 }
6957
6958 /* If we have a SUBREG of a register that we are replacing and we are
6959 replacing it with a MEM, make a new MEM and try replacing the
6960 SUBREG with it. Don't do this if the MEM has a mode-dependent address
6961 or if we would be widening it. */
6962
6963 if (MEM_P (op)
6964 && ! mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op))
6965 /* Allow splitting of volatile memory references in case we don't
6966 have instruction to move the whole thing. */
6967 && (! MEM_VOLATILE_P (op)
6968 || ! have_insn_for (SET, innermode))
6969 && known_le (outersize, innersize))
6970 return adjust_address_nv (op, outermode, byte);
6971
6972 /* Handle complex or vector values represented as CONCAT or VEC_CONCAT
6973 of two parts. */
6974 if (GET_CODE (op) == CONCAT
6975 || GET_CODE (op) == VEC_CONCAT)
6976 {
6977 poly_uint64 final_offset;
6978 rtx part, res;
6979
6980 machine_mode part_mode = GET_MODE (XEXP (op, 0));
6981 if (part_mode == VOIDmode)
6982 part_mode = GET_MODE_INNER (GET_MODE (op));
6983 poly_uint64 part_size = GET_MODE_SIZE (part_mode);
6984 if (known_lt (byte, part_size))
6985 {
6986 part = XEXP (op, 0);
6987 final_offset = byte;
6988 }
6989 else if (known_ge (byte, part_size))
6990 {
6991 part = XEXP (op, 1);
6992 final_offset = byte - part_size;
6993 }
6994 else
6995 return NULL_RTX;
6996
6997 if (maybe_gt (final_offset + outersize, part_size))
6998 return NULL_RTX;
6999
7000 part_mode = GET_MODE (part);
7001 if (part_mode == VOIDmode)
7002 part_mode = GET_MODE_INNER (GET_MODE (op));
7003 res = simplify_subreg (outermode, part, part_mode, final_offset);
7004 if (res)
7005 return res;
7006 if (validate_subreg (outermode, part_mode, part, final_offset))
7007 return gen_rtx_SUBREG (outermode, part, final_offset);
7008 return NULL_RTX;
7009 }
7010
7011 /* Simplify
7012 (subreg (vec_merge (X)
7013 (vector)
7014 (const_int ((1 << N) | M)))
7015 (N * sizeof (outermode)))
7016 to
7017 (subreg (X) (N * sizeof (outermode)))
7018 */
7019 unsigned int idx;
7020 if (constant_multiple_p (byte, GET_MODE_SIZE (outermode), &idx)
7021 && idx < HOST_BITS_PER_WIDE_INT
7022 && GET_CODE (op) == VEC_MERGE
7023 && GET_MODE_INNER (innermode) == outermode
7024 && CONST_INT_P (XEXP (op, 2))
7025 && (UINTVAL (XEXP (op, 2)) & (HOST_WIDE_INT_1U << idx)) != 0)
7026 return simplify_gen_subreg (outermode, XEXP (op, 0), innermode, byte);
7027
7028 /* A SUBREG resulting from a zero extension may fold to zero if
7029 it extracts higher bits that the ZERO_EXTEND's source bits. */
7030 if (GET_CODE (op) == ZERO_EXTEND && SCALAR_INT_MODE_P (innermode))
7031 {
7032 poly_uint64 bitpos = subreg_lsb_1 (outermode, innermode, byte);
7033 if (known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (XEXP (op, 0)))))
7034 return CONST0_RTX (outermode);
7035 }
7036
7037 scalar_int_mode int_outermode, int_innermode;
7038 if (is_a <scalar_int_mode> (outermode, &int_outermode)
7039 && is_a <scalar_int_mode> (innermode, &int_innermode)
7040 && known_eq (byte, subreg_lowpart_offset (int_outermode, int_innermode)))
7041 {
7042 /* Handle polynomial integers. The upper bits of a paradoxical
7043 subreg are undefined, so this is safe regardless of whether
7044 we're truncating or extending. */
7045 if (CONST_POLY_INT_P (op))
7046 {
7047 poly_wide_int val
7048 = poly_wide_int::from (const_poly_int_value (op),
7049 GET_MODE_PRECISION (int_outermode),
7050 SIGNED);
7051 return immed_wide_int_const (val, int_outermode);
7052 }
7053
7054 if (GET_MODE_PRECISION (int_outermode)
7055 < GET_MODE_PRECISION (int_innermode))
7056 {
7057 rtx tem = simplify_truncation (int_outermode, op, int_innermode);
7058 if (tem)
7059 return tem;
7060 }
7061 }
7062
7063 /* If OP is a vector comparison and the subreg is not changing the
7064 number of elements or the size of the elements, change the result
7065 of the comparison to the new mode. */
7066 if (COMPARISON_P (op)
7067 && VECTOR_MODE_P (outermode)
7068 && VECTOR_MODE_P (innermode)
7069 && known_eq (GET_MODE_NUNITS (outermode), GET_MODE_NUNITS (innermode))
7070 && known_eq (GET_MODE_UNIT_SIZE (outermode),
7071 GET_MODE_UNIT_SIZE (innermode)))
7072 return simplify_gen_relational (GET_CODE (op), outermode, innermode,
7073 XEXP (op, 0), XEXP (op, 1));
7074 return NULL_RTX;
7075 }
7076
7077 /* Make a SUBREG operation or equivalent if it folds. */
7078
7079 rtx
simplify_gen_subreg(machine_mode outermode,rtx op,machine_mode innermode,poly_uint64 byte)7080 simplify_gen_subreg (machine_mode outermode, rtx op,
7081 machine_mode innermode, poly_uint64 byte)
7082 {
7083 rtx newx;
7084
7085 newx = simplify_subreg (outermode, op, innermode, byte);
7086 if (newx)
7087 return newx;
7088
7089 if (GET_CODE (op) == SUBREG
7090 || GET_CODE (op) == CONCAT
7091 || GET_MODE (op) == VOIDmode)
7092 return NULL_RTX;
7093
7094 if (validate_subreg (outermode, innermode, op, byte))
7095 return gen_rtx_SUBREG (outermode, op, byte);
7096
7097 return NULL_RTX;
7098 }
7099
7100 /* Generates a subreg to get the least significant part of EXPR (in mode
7101 INNER_MODE) to OUTER_MODE. */
7102
7103 rtx
lowpart_subreg(machine_mode outer_mode,rtx expr,machine_mode inner_mode)7104 lowpart_subreg (machine_mode outer_mode, rtx expr,
7105 machine_mode inner_mode)
7106 {
7107 return simplify_gen_subreg (outer_mode, expr, inner_mode,
7108 subreg_lowpart_offset (outer_mode, inner_mode));
7109 }
7110
7111 /* Simplify X, an rtx expression.
7112
7113 Return the simplified expression or NULL if no simplifications
7114 were possible.
7115
7116 This is the preferred entry point into the simplification routines;
7117 however, we still allow passes to call the more specific routines.
7118
7119 Right now GCC has three (yes, three) major bodies of RTL simplification
7120 code that need to be unified.
7121
7122 1. fold_rtx in cse.c. This code uses various CSE specific
7123 information to aid in RTL simplification.
7124
7125 2. simplify_rtx in combine.c. Similar to fold_rtx, except that
7126 it uses combine specific information to aid in RTL
7127 simplification.
7128
7129 3. The routines in this file.
7130
7131
7132 Long term we want to only have one body of simplification code; to
7133 get to that state I recommend the following steps:
7134
7135 1. Pour over fold_rtx & simplify_rtx and move any simplifications
7136 which are not pass dependent state into these routines.
7137
7138 2. As code is moved by #1, change fold_rtx & simplify_rtx to
7139 use this routine whenever possible.
7140
7141 3. Allow for pass dependent state to be provided to these
7142 routines and add simplifications based on the pass dependent
7143 state. Remove code from cse.c & combine.c that becomes
7144 redundant/dead.
7145
7146 It will take time, but ultimately the compiler will be easier to
7147 maintain and improve. It's totally silly that when we add a
7148 simplification that it needs to be added to 4 places (3 for RTL
7149 simplification and 1 for tree simplification. */
7150
7151 rtx
simplify_rtx(const_rtx x)7152 simplify_rtx (const_rtx x)
7153 {
7154 const enum rtx_code code = GET_CODE (x);
7155 const machine_mode mode = GET_MODE (x);
7156
7157 switch (GET_RTX_CLASS (code))
7158 {
7159 case RTX_UNARY:
7160 return simplify_unary_operation (code, mode,
7161 XEXP (x, 0), GET_MODE (XEXP (x, 0)));
7162 case RTX_COMM_ARITH:
7163 if (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1)))
7164 return simplify_gen_binary (code, mode, XEXP (x, 1), XEXP (x, 0));
7165
7166 /* Fall through. */
7167
7168 case RTX_BIN_ARITH:
7169 return simplify_binary_operation (code, mode, XEXP (x, 0), XEXP (x, 1));
7170
7171 case RTX_TERNARY:
7172 case RTX_BITFIELD_OPS:
7173 return simplify_ternary_operation (code, mode, GET_MODE (XEXP (x, 0)),
7174 XEXP (x, 0), XEXP (x, 1),
7175 XEXP (x, 2));
7176
7177 case RTX_COMPARE:
7178 case RTX_COMM_COMPARE:
7179 return simplify_relational_operation (code, mode,
7180 ((GET_MODE (XEXP (x, 0))
7181 != VOIDmode)
7182 ? GET_MODE (XEXP (x, 0))
7183 : GET_MODE (XEXP (x, 1))),
7184 XEXP (x, 0),
7185 XEXP (x, 1));
7186
7187 case RTX_EXTRA:
7188 if (code == SUBREG)
7189 return simplify_subreg (mode, SUBREG_REG (x),
7190 GET_MODE (SUBREG_REG (x)),
7191 SUBREG_BYTE (x));
7192 break;
7193
7194 case RTX_OBJ:
7195 if (code == LO_SUM)
7196 {
7197 /* Convert (lo_sum (high FOO) FOO) to FOO. */
7198 if (GET_CODE (XEXP (x, 0)) == HIGH
7199 && rtx_equal_p (XEXP (XEXP (x, 0), 0), XEXP (x, 1)))
7200 return XEXP (x, 1);
7201 }
7202 break;
7203
7204 default:
7205 break;
7206 }
7207 return NULL;
7208 }
7209
7210 #if CHECKING_P
7211
7212 namespace selftest {
7213
7214 /* Make a unique pseudo REG of mode MODE for use by selftests. */
7215
7216 static rtx
make_test_reg(machine_mode mode)7217 make_test_reg (machine_mode mode)
7218 {
7219 static int test_reg_num = LAST_VIRTUAL_REGISTER + 1;
7220
7221 return gen_rtx_REG (mode, test_reg_num++);
7222 }
7223
7224 /* Test vector simplifications involving VEC_DUPLICATE in which the
7225 operands and result have vector mode MODE. SCALAR_REG is a pseudo
7226 register that holds one element of MODE. */
7227
7228 static void
test_vector_ops_duplicate(machine_mode mode,rtx scalar_reg)7229 test_vector_ops_duplicate (machine_mode mode, rtx scalar_reg)
7230 {
7231 scalar_mode inner_mode = GET_MODE_INNER (mode);
7232 rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
7233 poly_uint64 nunits = GET_MODE_NUNITS (mode);
7234 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
7235 {
7236 /* Test some simple unary cases with VEC_DUPLICATE arguments. */
7237 rtx not_scalar_reg = gen_rtx_NOT (inner_mode, scalar_reg);
7238 rtx duplicate_not = gen_rtx_VEC_DUPLICATE (mode, not_scalar_reg);
7239 ASSERT_RTX_EQ (duplicate,
7240 simplify_unary_operation (NOT, mode,
7241 duplicate_not, mode));
7242
7243 rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
7244 rtx duplicate_neg = gen_rtx_VEC_DUPLICATE (mode, neg_scalar_reg);
7245 ASSERT_RTX_EQ (duplicate,
7246 simplify_unary_operation (NEG, mode,
7247 duplicate_neg, mode));
7248
7249 /* Test some simple binary cases with VEC_DUPLICATE arguments. */
7250 ASSERT_RTX_EQ (duplicate,
7251 simplify_binary_operation (PLUS, mode, duplicate,
7252 CONST0_RTX (mode)));
7253
7254 ASSERT_RTX_EQ (duplicate,
7255 simplify_binary_operation (MINUS, mode, duplicate,
7256 CONST0_RTX (mode)));
7257
7258 ASSERT_RTX_PTR_EQ (CONST0_RTX (mode),
7259 simplify_binary_operation (MINUS, mode, duplicate,
7260 duplicate));
7261 }
7262
7263 /* Test a scalar VEC_SELECT of a VEC_DUPLICATE. */
7264 rtx zero_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const0_rtx));
7265 ASSERT_RTX_PTR_EQ (scalar_reg,
7266 simplify_binary_operation (VEC_SELECT, inner_mode,
7267 duplicate, zero_par));
7268
7269 unsigned HOST_WIDE_INT const_nunits;
7270 if (nunits.is_constant (&const_nunits))
7271 {
7272 /* And again with the final element. */
7273 rtx last_index = gen_int_mode (const_nunits - 1, word_mode);
7274 rtx last_par = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, last_index));
7275 ASSERT_RTX_PTR_EQ (scalar_reg,
7276 simplify_binary_operation (VEC_SELECT, inner_mode,
7277 duplicate, last_par));
7278
7279 /* Test a scalar subreg of a VEC_MERGE of a VEC_DUPLICATE. */
7280 rtx vector_reg = make_test_reg (mode);
7281 for (unsigned HOST_WIDE_INT i = 0; i < const_nunits; i++)
7282 {
7283 if (i >= HOST_BITS_PER_WIDE_INT)
7284 break;
7285 rtx mask = GEN_INT ((HOST_WIDE_INT_1U << i) | (i + 1));
7286 rtx vm = gen_rtx_VEC_MERGE (mode, duplicate, vector_reg, mask);
7287 poly_uint64 offset = i * GET_MODE_SIZE (inner_mode);
7288 ASSERT_RTX_EQ (scalar_reg,
7289 simplify_gen_subreg (inner_mode, vm,
7290 mode, offset));
7291 }
7292 }
7293
7294 /* Test a scalar subreg of a VEC_DUPLICATE. */
7295 poly_uint64 offset = subreg_lowpart_offset (inner_mode, mode);
7296 ASSERT_RTX_EQ (scalar_reg,
7297 simplify_gen_subreg (inner_mode, duplicate,
7298 mode, offset));
7299
7300 machine_mode narrower_mode;
7301 if (maybe_ne (nunits, 2U)
7302 && multiple_p (nunits, 2)
7303 && mode_for_vector (inner_mode, 2).exists (&narrower_mode)
7304 && VECTOR_MODE_P (narrower_mode))
7305 {
7306 /* Test VEC_DUPLICATE of a vector. */
7307 rtx_vector_builder nbuilder (narrower_mode, 2, 1);
7308 nbuilder.quick_push (const0_rtx);
7309 nbuilder.quick_push (const1_rtx);
7310 rtx_vector_builder builder (mode, 2, 1);
7311 builder.quick_push (const0_rtx);
7312 builder.quick_push (const1_rtx);
7313 ASSERT_RTX_EQ (builder.build (),
7314 simplify_unary_operation (VEC_DUPLICATE, mode,
7315 nbuilder.build (),
7316 narrower_mode));
7317
7318 /* Test VEC_SELECT of a vector. */
7319 rtx vec_par
7320 = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, const1_rtx, const0_rtx));
7321 rtx narrower_duplicate
7322 = gen_rtx_VEC_DUPLICATE (narrower_mode, scalar_reg);
7323 ASSERT_RTX_EQ (narrower_duplicate,
7324 simplify_binary_operation (VEC_SELECT, narrower_mode,
7325 duplicate, vec_par));
7326
7327 /* Test a vector subreg of a VEC_DUPLICATE. */
7328 poly_uint64 offset = subreg_lowpart_offset (narrower_mode, mode);
7329 ASSERT_RTX_EQ (narrower_duplicate,
7330 simplify_gen_subreg (narrower_mode, duplicate,
7331 mode, offset));
7332 }
7333 }
7334
7335 /* Test vector simplifications involving VEC_SERIES in which the
7336 operands and result have vector mode MODE. SCALAR_REG is a pseudo
7337 register that holds one element of MODE. */
7338
7339 static void
test_vector_ops_series(machine_mode mode,rtx scalar_reg)7340 test_vector_ops_series (machine_mode mode, rtx scalar_reg)
7341 {
7342 /* Test unary cases with VEC_SERIES arguments. */
7343 scalar_mode inner_mode = GET_MODE_INNER (mode);
7344 rtx duplicate = gen_rtx_VEC_DUPLICATE (mode, scalar_reg);
7345 rtx neg_scalar_reg = gen_rtx_NEG (inner_mode, scalar_reg);
7346 rtx series_0_r = gen_rtx_VEC_SERIES (mode, const0_rtx, scalar_reg);
7347 rtx series_0_nr = gen_rtx_VEC_SERIES (mode, const0_rtx, neg_scalar_reg);
7348 rtx series_nr_1 = gen_rtx_VEC_SERIES (mode, neg_scalar_reg, const1_rtx);
7349 rtx series_r_m1 = gen_rtx_VEC_SERIES (mode, scalar_reg, constm1_rtx);
7350 rtx series_r_r = gen_rtx_VEC_SERIES (mode, scalar_reg, scalar_reg);
7351 rtx series_nr_nr = gen_rtx_VEC_SERIES (mode, neg_scalar_reg,
7352 neg_scalar_reg);
7353 ASSERT_RTX_EQ (series_0_r,
7354 simplify_unary_operation (NEG, mode, series_0_nr, mode));
7355 ASSERT_RTX_EQ (series_r_m1,
7356 simplify_unary_operation (NEG, mode, series_nr_1, mode));
7357 ASSERT_RTX_EQ (series_r_r,
7358 simplify_unary_operation (NEG, mode, series_nr_nr, mode));
7359
7360 /* Test that a VEC_SERIES with a zero step is simplified away. */
7361 ASSERT_RTX_EQ (duplicate,
7362 simplify_binary_operation (VEC_SERIES, mode,
7363 scalar_reg, const0_rtx));
7364
7365 /* Test PLUS and MINUS with VEC_SERIES. */
7366 rtx series_0_1 = gen_const_vec_series (mode, const0_rtx, const1_rtx);
7367 rtx series_0_m1 = gen_const_vec_series (mode, const0_rtx, constm1_rtx);
7368 rtx series_r_1 = gen_rtx_VEC_SERIES (mode, scalar_reg, const1_rtx);
7369 ASSERT_RTX_EQ (series_r_r,
7370 simplify_binary_operation (PLUS, mode, series_0_r,
7371 duplicate));
7372 ASSERT_RTX_EQ (series_r_1,
7373 simplify_binary_operation (PLUS, mode, duplicate,
7374 series_0_1));
7375 ASSERT_RTX_EQ (series_r_m1,
7376 simplify_binary_operation (PLUS, mode, duplicate,
7377 series_0_m1));
7378 ASSERT_RTX_EQ (series_0_r,
7379 simplify_binary_operation (MINUS, mode, series_r_r,
7380 duplicate));
7381 ASSERT_RTX_EQ (series_r_m1,
7382 simplify_binary_operation (MINUS, mode, duplicate,
7383 series_0_1));
7384 ASSERT_RTX_EQ (series_r_1,
7385 simplify_binary_operation (MINUS, mode, duplicate,
7386 series_0_m1));
7387 ASSERT_RTX_EQ (series_0_m1,
7388 simplify_binary_operation (VEC_SERIES, mode, const0_rtx,
7389 constm1_rtx));
7390
7391 /* Test NEG on constant vector series. */
7392 ASSERT_RTX_EQ (series_0_m1,
7393 simplify_unary_operation (NEG, mode, series_0_1, mode));
7394 ASSERT_RTX_EQ (series_0_1,
7395 simplify_unary_operation (NEG, mode, series_0_m1, mode));
7396
7397 /* Test PLUS and MINUS on constant vector series. */
7398 rtx scalar2 = gen_int_mode (2, inner_mode);
7399 rtx scalar3 = gen_int_mode (3, inner_mode);
7400 rtx series_1_1 = gen_const_vec_series (mode, const1_rtx, const1_rtx);
7401 rtx series_0_2 = gen_const_vec_series (mode, const0_rtx, scalar2);
7402 rtx series_1_3 = gen_const_vec_series (mode, const1_rtx, scalar3);
7403 ASSERT_RTX_EQ (series_1_1,
7404 simplify_binary_operation (PLUS, mode, series_0_1,
7405 CONST1_RTX (mode)));
7406 ASSERT_RTX_EQ (series_0_m1,
7407 simplify_binary_operation (PLUS, mode, CONST0_RTX (mode),
7408 series_0_m1));
7409 ASSERT_RTX_EQ (series_1_3,
7410 simplify_binary_operation (PLUS, mode, series_1_1,
7411 series_0_2));
7412 ASSERT_RTX_EQ (series_0_1,
7413 simplify_binary_operation (MINUS, mode, series_1_1,
7414 CONST1_RTX (mode)));
7415 ASSERT_RTX_EQ (series_1_1,
7416 simplify_binary_operation (MINUS, mode, CONST1_RTX (mode),
7417 series_0_m1));
7418 ASSERT_RTX_EQ (series_1_1,
7419 simplify_binary_operation (MINUS, mode, series_1_3,
7420 series_0_2));
7421
7422 /* Test MULT between constant vectors. */
7423 rtx vec2 = gen_const_vec_duplicate (mode, scalar2);
7424 rtx vec3 = gen_const_vec_duplicate (mode, scalar3);
7425 rtx scalar9 = gen_int_mode (9, inner_mode);
7426 rtx series_3_9 = gen_const_vec_series (mode, scalar3, scalar9);
7427 ASSERT_RTX_EQ (series_0_2,
7428 simplify_binary_operation (MULT, mode, series_0_1, vec2));
7429 ASSERT_RTX_EQ (series_3_9,
7430 simplify_binary_operation (MULT, mode, vec3, series_1_3));
7431 if (!GET_MODE_NUNITS (mode).is_constant ())
7432 ASSERT_FALSE (simplify_binary_operation (MULT, mode, series_0_1,
7433 series_0_1));
7434
7435 /* Test ASHIFT between constant vectors. */
7436 ASSERT_RTX_EQ (series_0_2,
7437 simplify_binary_operation (ASHIFT, mode, series_0_1,
7438 CONST1_RTX (mode)));
7439 if (!GET_MODE_NUNITS (mode).is_constant ())
7440 ASSERT_FALSE (simplify_binary_operation (ASHIFT, mode, CONST1_RTX (mode),
7441 series_0_1));
7442 }
7443
7444 /* Verify simplify_merge_mask works correctly. */
7445
7446 static void
test_vec_merge(machine_mode mode)7447 test_vec_merge (machine_mode mode)
7448 {
7449 rtx op0 = make_test_reg (mode);
7450 rtx op1 = make_test_reg (mode);
7451 rtx op2 = make_test_reg (mode);
7452 rtx op3 = make_test_reg (mode);
7453 rtx op4 = make_test_reg (mode);
7454 rtx op5 = make_test_reg (mode);
7455 rtx mask1 = make_test_reg (SImode);
7456 rtx mask2 = make_test_reg (SImode);
7457 rtx vm1 = gen_rtx_VEC_MERGE (mode, op0, op1, mask1);
7458 rtx vm2 = gen_rtx_VEC_MERGE (mode, op2, op3, mask1);
7459 rtx vm3 = gen_rtx_VEC_MERGE (mode, op4, op5, mask1);
7460
7461 /* Simple vec_merge. */
7462 ASSERT_EQ (op0, simplify_merge_mask (vm1, mask1, 0));
7463 ASSERT_EQ (op1, simplify_merge_mask (vm1, mask1, 1));
7464 ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 0));
7465 ASSERT_EQ (NULL_RTX, simplify_merge_mask (vm1, mask2, 1));
7466
7467 /* Nested vec_merge.
7468 It's tempting to make this simplify right down to opN, but we don't
7469 because all the simplify_* functions assume that the operands have
7470 already been simplified. */
7471 rtx nvm = gen_rtx_VEC_MERGE (mode, vm1, vm2, mask1);
7472 ASSERT_EQ (vm1, simplify_merge_mask (nvm, mask1, 0));
7473 ASSERT_EQ (vm2, simplify_merge_mask (nvm, mask1, 1));
7474
7475 /* Intermediate unary op. */
7476 rtx unop = gen_rtx_NOT (mode, vm1);
7477 ASSERT_RTX_EQ (gen_rtx_NOT (mode, op0),
7478 simplify_merge_mask (unop, mask1, 0));
7479 ASSERT_RTX_EQ (gen_rtx_NOT (mode, op1),
7480 simplify_merge_mask (unop, mask1, 1));
7481
7482 /* Intermediate binary op. */
7483 rtx binop = gen_rtx_PLUS (mode, vm1, vm2);
7484 ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op0, op2),
7485 simplify_merge_mask (binop, mask1, 0));
7486 ASSERT_RTX_EQ (gen_rtx_PLUS (mode, op1, op3),
7487 simplify_merge_mask (binop, mask1, 1));
7488
7489 /* Intermediate ternary op. */
7490 rtx tenop = gen_rtx_FMA (mode, vm1, vm2, vm3);
7491 ASSERT_RTX_EQ (gen_rtx_FMA (mode, op0, op2, op4),
7492 simplify_merge_mask (tenop, mask1, 0));
7493 ASSERT_RTX_EQ (gen_rtx_FMA (mode, op1, op3, op5),
7494 simplify_merge_mask (tenop, mask1, 1));
7495
7496 /* Side effects. */
7497 rtx badop0 = gen_rtx_PRE_INC (mode, op0);
7498 rtx badvm = gen_rtx_VEC_MERGE (mode, badop0, op1, mask1);
7499 ASSERT_EQ (badop0, simplify_merge_mask (badvm, mask1, 0));
7500 ASSERT_EQ (NULL_RTX, simplify_merge_mask (badvm, mask1, 1));
7501
7502 /* Called indirectly. */
7503 ASSERT_RTX_EQ (gen_rtx_VEC_MERGE (mode, op0, op3, mask1),
7504 simplify_rtx (nvm));
7505 }
7506
7507 /* Test subregs of integer vector constant X, trying elements in
7508 the range [ELT_BIAS, ELT_BIAS + constant_lower_bound (NELTS)),
7509 where NELTS is the number of elements in X. Subregs involving
7510 elements [ELT_BIAS, ELT_BIAS + FIRST_VALID) are expected to fail. */
7511
7512 static void
7513 test_vector_subregs_modes (rtx x, poly_uint64 elt_bias = 0,
7514 unsigned int first_valid = 0)
7515 {
7516 machine_mode inner_mode = GET_MODE (x);
7517 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
7518
7519 for (unsigned int modei = 0; modei < NUM_MACHINE_MODES; ++modei)
7520 {
7521 machine_mode outer_mode = (machine_mode) modei;
7522 if (!VECTOR_MODE_P (outer_mode))
7523 continue;
7524
7525 unsigned int outer_nunits;
7526 if (GET_MODE_INNER (outer_mode) == int_mode
7527 && GET_MODE_NUNITS (outer_mode).is_constant (&outer_nunits)
7528 && multiple_p (GET_MODE_NUNITS (inner_mode), outer_nunits))
7529 {
7530 /* Test subregs in which the outer mode is a smaller,
7531 constant-sized vector of the same element type. */
7532 unsigned int limit
7533 = constant_lower_bound (GET_MODE_NUNITS (inner_mode));
7534 for (unsigned int elt = 0; elt < limit; elt += outer_nunits)
7535 {
7536 rtx expected = NULL_RTX;
7537 if (elt >= first_valid)
7538 {
7539 rtx_vector_builder builder (outer_mode, outer_nunits, 1);
7540 for (unsigned int i = 0; i < outer_nunits; ++i)
7541 builder.quick_push (CONST_VECTOR_ELT (x, elt + i));
7542 expected = builder.build ();
7543 }
7544 poly_uint64 byte = (elt_bias + elt) * GET_MODE_SIZE (int_mode);
7545 ASSERT_RTX_EQ (expected,
7546 simplify_subreg (outer_mode, x,
7547 inner_mode, byte));
7548 }
7549 }
7550 else if (known_eq (GET_MODE_SIZE (outer_mode),
7551 GET_MODE_SIZE (inner_mode))
7552 && known_eq (elt_bias, 0U)
7553 && (GET_MODE_CLASS (outer_mode) != MODE_VECTOR_BOOL
7554 || known_eq (GET_MODE_BITSIZE (outer_mode),
7555 GET_MODE_NUNITS (outer_mode)))
7556 && (!FLOAT_MODE_P (outer_mode)
7557 || (FLOAT_MODE_FORMAT (outer_mode)->ieee_bits
7558 == GET_MODE_UNIT_PRECISION (outer_mode)))
7559 && (GET_MODE_SIZE (inner_mode).is_constant ()
7560 || !CONST_VECTOR_STEPPED_P (x)))
7561 {
7562 /* Try converting to OUTER_MODE and back. */
7563 rtx outer_x = simplify_subreg (outer_mode, x, inner_mode, 0);
7564 ASSERT_TRUE (outer_x != NULL_RTX);
7565 ASSERT_RTX_EQ (x, simplify_subreg (inner_mode, outer_x,
7566 outer_mode, 0));
7567 }
7568 }
7569
7570 if (BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
7571 {
7572 /* Test each byte in the element range. */
7573 unsigned int limit
7574 = constant_lower_bound (GET_MODE_SIZE (inner_mode));
7575 for (unsigned int i = 0; i < limit; ++i)
7576 {
7577 unsigned int elt = i / GET_MODE_SIZE (int_mode);
7578 rtx expected = NULL_RTX;
7579 if (elt >= first_valid)
7580 {
7581 unsigned int byte_shift = i % GET_MODE_SIZE (int_mode);
7582 if (BYTES_BIG_ENDIAN)
7583 byte_shift = GET_MODE_SIZE (int_mode) - byte_shift - 1;
7584 rtx_mode_t vec_elt (CONST_VECTOR_ELT (x, elt), int_mode);
7585 wide_int shifted_elt
7586 = wi::lrshift (vec_elt, byte_shift * BITS_PER_UNIT);
7587 expected = immed_wide_int_const (shifted_elt, QImode);
7588 }
7589 poly_uint64 byte = elt_bias * GET_MODE_SIZE (int_mode) + i;
7590 ASSERT_RTX_EQ (expected,
7591 simplify_subreg (QImode, x, inner_mode, byte));
7592 }
7593 }
7594 }
7595
7596 /* Test constant subregs of integer vector mode INNER_MODE, using 1
7597 element per pattern. */
7598
7599 static void
test_vector_subregs_repeating(machine_mode inner_mode)7600 test_vector_subregs_repeating (machine_mode inner_mode)
7601 {
7602 poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
7603 unsigned int min_nunits = constant_lower_bound (nunits);
7604 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
7605 unsigned int count = gcd (min_nunits, 8);
7606
7607 rtx_vector_builder builder (inner_mode, count, 1);
7608 for (unsigned int i = 0; i < count; ++i)
7609 builder.quick_push (gen_int_mode (8 - i, int_mode));
7610 rtx x = builder.build ();
7611
7612 test_vector_subregs_modes (x);
7613 if (!nunits.is_constant ())
7614 test_vector_subregs_modes (x, nunits - min_nunits);
7615 }
7616
7617 /* Test constant subregs of integer vector mode INNER_MODE, using 2
7618 elements per pattern. */
7619
7620 static void
test_vector_subregs_fore_back(machine_mode inner_mode)7621 test_vector_subregs_fore_back (machine_mode inner_mode)
7622 {
7623 poly_uint64 nunits = GET_MODE_NUNITS (inner_mode);
7624 unsigned int min_nunits = constant_lower_bound (nunits);
7625 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
7626 unsigned int count = gcd (min_nunits, 4);
7627
7628 rtx_vector_builder builder (inner_mode, count, 2);
7629 for (unsigned int i = 0; i < count; ++i)
7630 builder.quick_push (gen_int_mode (i, int_mode));
7631 for (unsigned int i = 0; i < count; ++i)
7632 builder.quick_push (gen_int_mode (-(int) i, int_mode));
7633 rtx x = builder.build ();
7634
7635 test_vector_subregs_modes (x);
7636 if (!nunits.is_constant ())
7637 test_vector_subregs_modes (x, nunits - min_nunits, count);
7638 }
7639
7640 /* Test constant subregs of integer vector mode INNER_MODE, using 3
7641 elements per pattern. */
7642
7643 static void
test_vector_subregs_stepped(machine_mode inner_mode)7644 test_vector_subregs_stepped (machine_mode inner_mode)
7645 {
7646 /* Build { 0, 1, 2, 3, ... }. */
7647 scalar_mode int_mode = GET_MODE_INNER (inner_mode);
7648 rtx_vector_builder builder (inner_mode, 1, 3);
7649 for (unsigned int i = 0; i < 3; ++i)
7650 builder.quick_push (gen_int_mode (i, int_mode));
7651 rtx x = builder.build ();
7652
7653 test_vector_subregs_modes (x);
7654 }
7655
7656 /* Test constant subregs of integer vector mode INNER_MODE. */
7657
7658 static void
test_vector_subregs(machine_mode inner_mode)7659 test_vector_subregs (machine_mode inner_mode)
7660 {
7661 test_vector_subregs_repeating (inner_mode);
7662 test_vector_subregs_fore_back (inner_mode);
7663 test_vector_subregs_stepped (inner_mode);
7664 }
7665
7666 /* Verify some simplifications involving vectors. */
7667
7668 static void
test_vector_ops()7669 test_vector_ops ()
7670 {
7671 for (unsigned int i = 0; i < NUM_MACHINE_MODES; ++i)
7672 {
7673 machine_mode mode = (machine_mode) i;
7674 if (VECTOR_MODE_P (mode))
7675 {
7676 rtx scalar_reg = make_test_reg (GET_MODE_INNER (mode));
7677 test_vector_ops_duplicate (mode, scalar_reg);
7678 if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
7679 && maybe_gt (GET_MODE_NUNITS (mode), 2))
7680 {
7681 test_vector_ops_series (mode, scalar_reg);
7682 test_vector_subregs (mode);
7683 }
7684 test_vec_merge (mode);
7685 }
7686 }
7687 }
7688
7689 template<unsigned int N>
7690 struct simplify_const_poly_int_tests
7691 {
7692 static void run ();
7693 };
7694
7695 template<>
7696 struct simplify_const_poly_int_tests<1>
7697 {
7698 static void run () {}
7699 };
7700
7701 /* Test various CONST_POLY_INT properties. */
7702
7703 template<unsigned int N>
7704 void
7705 simplify_const_poly_int_tests<N>::run ()
7706 {
7707 rtx x1 = gen_int_mode (poly_int64 (1, 1), QImode);
7708 rtx x2 = gen_int_mode (poly_int64 (-80, 127), QImode);
7709 rtx x3 = gen_int_mode (poly_int64 (-79, -128), QImode);
7710 rtx x4 = gen_int_mode (poly_int64 (5, 4), QImode);
7711 rtx x5 = gen_int_mode (poly_int64 (30, 24), QImode);
7712 rtx x6 = gen_int_mode (poly_int64 (20, 16), QImode);
7713 rtx x7 = gen_int_mode (poly_int64 (7, 4), QImode);
7714 rtx x8 = gen_int_mode (poly_int64 (30, 24), HImode);
7715 rtx x9 = gen_int_mode (poly_int64 (-30, -24), HImode);
7716 rtx x10 = gen_int_mode (poly_int64 (-31, -24), HImode);
7717 rtx two = GEN_INT (2);
7718 rtx six = GEN_INT (6);
7719 poly_uint64 offset = subreg_lowpart_offset (QImode, HImode);
7720
7721 /* These tests only try limited operation combinations. Fuller arithmetic
7722 testing is done directly on poly_ints. */
7723 ASSERT_EQ (simplify_unary_operation (NEG, HImode, x8, HImode), x9);
7724 ASSERT_EQ (simplify_unary_operation (NOT, HImode, x8, HImode), x10);
7725 ASSERT_EQ (simplify_unary_operation (TRUNCATE, QImode, x8, HImode), x5);
7726 ASSERT_EQ (simplify_binary_operation (PLUS, QImode, x1, x2), x3);
7727 ASSERT_EQ (simplify_binary_operation (MINUS, QImode, x3, x1), x2);
7728 ASSERT_EQ (simplify_binary_operation (MULT, QImode, x4, six), x5);
7729 ASSERT_EQ (simplify_binary_operation (MULT, QImode, six, x4), x5);
7730 ASSERT_EQ (simplify_binary_operation (ASHIFT, QImode, x4, two), x6);
7731 ASSERT_EQ (simplify_binary_operation (IOR, QImode, x4, two), x7);
7732 ASSERT_EQ (simplify_subreg (HImode, x5, QImode, 0), x8);
7733 ASSERT_EQ (simplify_subreg (QImode, x8, HImode, offset), x5);
7734 }
7735
7736 /* Run all of the selftests within this file. */
7737
7738 void
7739 simplify_rtx_c_tests ()
7740 {
7741 test_vector_ops ();
7742 simplify_const_poly_int_tests<NUM_POLY_INT_COEFFS>::run ();
7743 }
7744
7745 } // namespace selftest
7746
7747 #endif /* CHECKING_P */
7748