summaryrefslogtreecommitdiff
path: root/gcc/cselib.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2004-03-03 10:31:36 -0800
committerRichard Henderson <rth@gcc.gnu.org>2004-03-03 10:31:36 -0800
commitb7048ab7b2b109a832081d3f2d990c17ae3cdda5 (patch)
treebd9cbe3b3591e4199a27b80524fcbe954ba79dc5 /gcc/cselib.c
parent039e3c5c4563e9530ec2aec77eed1096c9d27a0b (diff)
downloadgcc-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.c23
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++)
{