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