diff options
author | Richard Henderson <rth@redhat.com> | 2004-03-03 10:31:36 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2004-03-03 10:31:36 -0800 |
commit | b7048ab7b2b109a832081d3f2d990c17ae3cdda5 (patch) | |
tree | bd9cbe3b3591e4199a27b80524fcbe954ba79dc5 /gcc/cselib.c | |
parent | 039e3c5c4563e9530ec2aec77eed1096c9d27a0b (diff) | |
download | gcc-b7048ab7b2b109a832081d3f2d990c17ae3cdda5.tar.gz |
re PR rtl-optimization/13862 (ICE while optimizing asm)
PR opt/13862
* cselib.c (cselib_record_sets): Don't record multiple sets in
asm insns.
From-SVN: r78845
Diffstat (limited to 'gcc/cselib.c')
-rw-r--r-- | gcc/cselib.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/gcc/cselib.c b/gcc/cselib.c index 169b92706b6..7cc37f1915a 100644 --- a/gcc/cselib.c +++ b/gcc/cselib.c @@ -1293,6 +1293,29 @@ cselib_record_sets (rtx insn) locations may go away. */ note_stores (body, cselib_invalidate_rtx, NULL); + /* If this is an asm, look for duplicate sets. This can happen when the + user uses the same value as an output multiple times. This is valid + if the outputs are not actually used thereafter. Treat this case as + if the value isn't actually set. We do this by smashing the destination + to pc_rtx, so that we won't record the value later. */ + if (n_sets >= 2 && asm_noperands (body) >= 0) + { + for (i = 0; i < n_sets; i++) + { + rtx dest = sets[i].dest; + if (GET_CODE (dest) == REG || GET_CODE (dest) == MEM) + { + int j; + for (j = i + 1; j < n_sets; j++) + if (rtx_equal_p (dest, sets[j].dest)) + { + sets[i].dest = pc_rtx; + sets[j].dest = pc_rtx; + } + } + } + } + /* Now enter the equivalences in our tables. */ for (i = 0; i < n_sets; i++) { |