diff options
author | Jakub Jelinek <jakub@redhat.com> | 2015-02-03 21:41:38 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2015-02-03 21:41:38 +0100 |
commit | 2a1d78d8f61d109b80402681a85d0051411f2cfe (patch) | |
tree | 1eaac6ad59091097ae8b08e988c7ffa361d92f59 /gcc/cse.c | |
parent | 3548abca0218168da1bb9f8cace29282a7495fbf (diff) | |
download | gcc-2a1d78d8f61d109b80402681a85d0051411f2cfe.zip gcc-2a1d78d8f61d109b80402681a85d0051411f2cfe.tar.gz gcc-2a1d78d8f61d109b80402681a85d0051411f2cfe.tar.bz2 |
re PR rtl-optimization/64756 (wrong code at -O3 on x86_64-linux-gnu (in 32-bit mode))
PR rtl-optimization/64756
* cse.c (invalidate_dest): New function.
(cse_insn): Use it. If dest != SET_DEST (sets[i].rtl) and
HASH (SET_DEST (sets[i].rtl), mode) computation sets do_not_record,
invalidate and do not record it.
* gcc.c-torture/execute/pr64756.c: New test.
From-SVN: r220377
Diffstat (limited to 'gcc/cse.c')
-rw-r--r-- | gcc/cse.c | 34 |
1 files changed, 26 insertions, 8 deletions
@@ -1984,6 +1984,22 @@ invalidate (rtx x, machine_mode full_mode) gcc_unreachable (); } } + +/* Invalidate DEST. Used when DEST is not going to be added + into the hash table for some reason, e.g. do_not_record + flagged on it. */ + +static void +invalidate_dest (rtx dest) +{ + if (REG_P (dest) + || GET_CODE (dest) == SUBREG + || MEM_P (dest)) + invalidate (dest, VOIDmode); + else if (GET_CODE (dest) == STRICT_LOW_PART + || GET_CODE (dest) == ZERO_EXTRACT) + invalidate (XEXP (dest, 0), GET_MODE (dest)); +} /* Remove all expressions that refer to register REGNO, since they are already invalid, and we are about to @@ -5510,18 +5526,20 @@ cse_insn (rtx_insn *insn) else if (do_not_record) { - if (REG_P (dest) || GET_CODE (dest) == SUBREG) - invalidate (dest, VOIDmode); - else if (MEM_P (dest)) - invalidate (dest, VOIDmode); - else if (GET_CODE (dest) == STRICT_LOW_PART - || GET_CODE (dest) == ZERO_EXTRACT) - invalidate (XEXP (dest, 0), GET_MODE (dest)); + invalidate_dest (dest); sets[i].rtl = 0; } if (sets[i].rtl != 0 && dest != SET_DEST (sets[i].rtl)) - sets[i].dest_hash = HASH (SET_DEST (sets[i].rtl), mode); + { + do_not_record = 0; + sets[i].dest_hash = HASH (SET_DEST (sets[i].rtl), mode); + if (do_not_record) + { + invalidate_dest (SET_DEST (sets[i].rtl)); + sets[i].rtl = 0; + } + } #ifdef HAVE_cc0 /* If setting CC0, record what it was set to, or a constant, if it |