diff options
author | Jakub Jelinek <jakub@redhat.com> | 2016-05-02 18:46:10 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-05-02 18:46:10 +0200 |
commit | dd77684f05433afcba15743ba1e2445804f9ac9f (patch) | |
tree | 5f22241d45864ce8739e25506d2dd7036092c783 /gcc/cse.c | |
parent | d40790c8ac4f81026252a119e11a104ffd49701f (diff) | |
download | gcc-dd77684f05433afcba15743ba1e2445804f9ac9f.zip gcc-dd77684f05433afcba15743ba1e2445804f9ac9f.tar.gz gcc-dd77684f05433afcba15743ba1e2445804f9ac9f.tar.bz2 |
re PR rtl-optimization/70467 (Useless "and [esp],-1" emitted on AND with uint64_t variable)
PR rtl-optimization/70467
* cse.c (cse_insn): Handle no-op MEM moves after folding.
* gcc.target/i386/pr70467-1.c: New test.
From-SVN: r235765
Diffstat (limited to 'gcc/cse.c')
-rw-r--r-- | gcc/cse.c | 28 |
1 files changed, 27 insertions, 1 deletions
@@ -4575,6 +4575,7 @@ cse_insn (rtx_insn *insn) for (i = 0; i < n_sets; i++) { bool repeat = false; + bool mem_noop_insn = false; rtx src, dest; rtx src_folded; struct table_elt *elt = 0, *p; @@ -5166,7 +5167,7 @@ cse_insn (rtx_insn *insn) } /* Avoid creation of overlapping memory moves. */ - if (MEM_P (trial) && MEM_P (SET_DEST (sets[i].rtl))) + if (MEM_P (trial) && MEM_P (dest) && !rtx_equal_p (trial, dest)) { rtx src, dest; @@ -5277,6 +5278,21 @@ cse_insn (rtx_insn *insn) break; } + /* Similarly, lots of targets don't allow no-op + (set (mem x) (mem x)) moves. */ + else if (n_sets == 1 + && MEM_P (trial) + && MEM_P (dest) + && rtx_equal_p (trial, dest) + && !side_effects_p (dest) + && (cfun->can_delete_dead_exceptions + || insn_nothrow_p (insn))) + { + SET_SRC (sets[i].rtl) = trial; + mem_noop_insn = true; + break; + } + /* Reject certain invalid forms of CONST that we create. */ else if (CONSTANT_P (trial) && GET_CODE (trial) == CONST @@ -5495,6 +5511,16 @@ cse_insn (rtx_insn *insn) sets[i].rtl = 0; } + /* Similarly for no-op MEM moves. */ + else if (mem_noop_insn) + { + if (cfun->can_throw_non_call_exceptions && can_throw_internal (insn)) + cse_cfg_altered = true; + delete_insn_and_edges (insn); + /* No more processing for this set. */ + sets[i].rtl = 0; + } + /* If this SET is now setting PC to a label, we know it used to be a conditional or computed branch. */ else if (dest == pc_rtx && GET_CODE (src) == LABEL_REF |