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