diff options
author | Jakub Jelinek <jakub@redhat.com> | 2020-02-07 09:26:54 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2020-02-07 09:26:54 +0100 |
commit | e7bec5d5edeaab404931bf599821c6c2a3023b47 (patch) | |
tree | 11d0eb3d1a85a249adedf33baed80104d4470ba2 /gcc | |
parent | bc4646410a38801029817e7951bf9b99a8c41461 (diff) | |
download | gcc-e7bec5d5edeaab404931bf599821c6c2a3023b47.zip gcc-e7bec5d5edeaab404931bf599821c6c2a3023b47.tar.gz gcc-e7bec5d5edeaab404931bf599821c6c2a3023b47.tar.bz2 |
i386: Fix splitters that call extract_insn_cached [PR93611]
The following testcase ICEs. The generated split_insns starts
with recog_data.insn = NULL and then tries to put various operands into
recog_data.operand array and checks various splitter conditions.
The problem is that some atom related tuning splitters indirectly call
extract_insn_cached on the insn they are used in. This can change
recog_data.operand, but most likely it will just keep it as is, but
sets recog_data.insn to the current instruction. If that splitter doesn't
match, we continue trying some other split conditions and modify
recog_data.operand array again. If even that doesn't find any usable
splitter, we punt, but at that point recog_data.insn says that recog_data
is valid for that particular instruction, even when recog_data.operand array
can be anything.
The safest thing would be to copy whole recog_data to a temporary object
before doing the calls that can call extract_insn_cached and restore it
afterwards, but it would be also very costly, recog_data has 1280 bytes.
So, this patch just makes sure to clear recog_data.insn if it has changed
during the extract_insn_cached call, which means if we extract_insn_cached
later, we'll extract it properly, while if we call it say from some other
context than splitter conditions, the insn is already cached, we don't reset
the cache.
2020-02-07 Jakub Jelinek <jakub@redhat.com>
PR target/93611
* config/i386/i386.c (ix86_lea_outperforms): Make sure to clear
recog_data.insn if distance_non_agu_define changed it.
* gcc.target/i386/pr93611.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 9 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr93611.c | 5 |
4 files changed, 25 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9797dd4..56090a9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2020-02-07 Jakub Jelinek <jakub@redhat.com> + + PR target/93611 + * config/i386/i386.c (ix86_lea_outperforms): Make sure to clear + recog_data.insn if distance_non_agu_define changed it. + 2020-02-06 Michael Meissner <meissner@linux.ibm.com> PR target/93569 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index ffda3e8..556ca82 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -14459,9 +14459,18 @@ ix86_lea_outperforms (rtx_insn *insn, unsigned int regno0, unsigned int regno1, return true; } + rtx_insn *rinsn = recog_data.insn; + dist_define = distance_non_agu_define (regno1, regno2, insn); dist_use = distance_agu_use (regno0, insn); + /* distance_non_agu_define can call extract_insn_cached. If this function + is called from define_split conditions, that can break insn splitting, + because split_insns works by clearing recog_data.insn and then modifying + recog_data.operand array and match the various split conditions. */ + if (recog_data.insn != rinsn) + recog_data.insn = NULL; + if (dist_define < 0 || dist_define >= LEA_MAX_STALL) { /* If there is no non AGU operand definition, no AGU diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a6fbf5b..6be609a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-02-07 Jakub Jelinek <jakub@redhat.com> + + PR target/93611 + * gcc.target/i386/pr93611.c: New test. + 2020-02-06 David Malcolm <dmalcolm@redhat.com> PR analyzer/93375 diff --git a/gcc/testsuite/gcc.target/i386/pr93611.c b/gcc/testsuite/gcc.target/i386/pr93611.c new file mode 100644 index 0000000..2a0e816 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr93611.c @@ -0,0 +1,5 @@ +/* PR target/93611 */ +/* { dg-do compile } */ +/* { dg-options "-fira-algorithm=priority -O3 -mtune=bonnell" } */ + +#include "../../gcc.dg/vect/pr58508.c" |