aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-01-08 16:59:20 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2020-01-08 16:59:20 +0100
commitb41383c8aba1e59070934a2b4592b9a34c19bb4e (patch)
tree79439f1daa9d31d6796db3ab245ef89a64e30d2c
parent7ca803f1011503334cebdc9ab5d64b3a213f315b (diff)
downloadgcc-b41383c8aba1e59070934a2b4592b9a34c19bb4e.zip
gcc-b41383c8aba1e59070934a2b4592b9a34c19bb4e.tar.gz
gcc-b41383c8aba1e59070934a2b4592b9a34c19bb4e.tar.bz2
re PR target/93187 (ICE in extract_insn, at recog.c:2294)
PR target/93187 * config/i386/i386.md (*stack_protect_set_2_<mode> peephole2, *stack_protect_set_3 peephole2): Also check that the second insns source is general_operand. * g++.dg/opt/pr93187.C: New test. From-SVN: r280012
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/i386/i386.md2
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/opt/pr93187.C77
4 files changed, 87 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cb1f7cb..ce7713f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
2020-01-08 Jakub Jelinek <jakub@redhat.com>
+ PR target/93187
+ * config/i386/i386.md (*stack_protect_set_2_<mode> peephole2,
+ *stack_protect_set_3 peephole2): Also check that the second
+ insns source is general_operand.
+
PR target/93174
* config/i386/i386.md (addcarry<mode>_0): Use nonimmediate_operand
predicate for output operand instead of register_operand.
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 3daf720..1fead5c 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -20084,6 +20084,7 @@
(set (match_operand:SI 3 "general_reg_operand")
(match_operand:SI 4))]
"REGNO (operands[2]) == REGNO (operands[3])
+ && general_operand (operands[4], SImode)
&& (general_reg_operand (operands[4], SImode)
|| memory_operand (operands[4], SImode)
|| immediate_operand (operands[4], SImode))
@@ -20128,6 +20129,7 @@
(clobber (reg:CC FLAGS_REG))])
(set (match_dup 2) (match_operand:DI 3))]
"TARGET_64BIT
+ && general_operand (operands[3], DImode)
&& (general_reg_operand (operands[3], DImode)
|| memory_operand (operands[3], DImode)
|| x86_64_zext_immediate_operand (operands[3], DImode)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8870858..e0296d2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2020-01-08 Jakub Jelinek <jakub@redhat.com>
+ PR target/93187
+ * g++.dg/opt/pr93187.C: New test.
+
PR target/93174
* gcc.c-torture/compile/pr93174.c: New test.
diff --git a/gcc/testsuite/g++.dg/opt/pr93187.C b/gcc/testsuite/g++.dg/opt/pr93187.C
new file mode 100644
index 0000000..19db5c9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr93187.C
@@ -0,0 +1,77 @@
+// PR target/93187
+// { dg-do compile { target c++11 } }
+// { dg-options "-O2" }
+// { dg-additional-options "-fstack-protector-strong" { target fstack_protector } }
+// { dg-additional-options "-fpie" { target pie } }
+
+struct A;
+struct B;
+struct C { int operator () (B, const B &); };
+struct D { typedef int *d; };
+struct E { C g; };
+struct F { F (D::d); friend bool operator==(F &, const int &); };
+template <typename T, typename> struct H {
+ typedef D *I;
+ E l;
+ I foo ();
+ T t;
+ F bar (I, const T &);
+ F baz (const T &);
+};
+template <typename T, typename U>
+F
+H<T, U>::bar (I n, const T &o)
+{
+ while (n)
+ if (l.g (t, o))
+ n = 0;
+ return 0;
+}
+template <typename T, typename U>
+F
+H<T, U>::baz (const T &n)
+{
+ D *r = foo ();
+ F p = bar (r, n);
+ return p == 0 ? 0 : p;
+}
+template <typename, typename U> struct J {
+ H<B, U> h;
+ B &q;
+ void baz () { h.baz (q); }
+};
+enum K { L };
+template <typename, K = L> struct M;
+template <int> struct G {
+ using N = J<int, A>;
+ N *operator->();
+};
+template <typename, K T> struct M : public G<T> {
+ using N = J<int, A>;
+ N *foo () { return n; }
+ N *n;
+ int o;
+};
+template <int N>
+inline typename G<N>::N *
+G<N>::operator-> ()
+{
+ N *n = static_cast<M<J<int, A>> *>(this)->foo ();
+ return n;
+}
+struct B { bool qux (); };
+struct O {
+ struct P { M<int> p; };
+ static thread_local P o;
+ int baz () const;
+};
+thread_local O::P O::o;
+B be;
+int
+O::baz () const
+{
+ do
+ o.p->baz ();
+ while (be.qux ());
+ __builtin_unreachable ();
+}