This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Don't cross-jump in between frame related and non-frame related insns (PR target/80102)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 20 Mar 2017 22:15:20 +0100
- Subject: [PATCH] Don't cross-jump in between frame related and non-frame related insns (PR target/80102)
- Authentication-results: sourceware.org; auth=none
- Authentication-results: ext-mx08.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com
- Authentication-results: ext-mx08.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=jakub at redhat dot com
- Dkim-filter: OpenDKIM Filter v2.11.0 mx1.redhat.com A4410C05AA59
- Dmarc-filter: OpenDMARC Filter v1.3.2 mx1.redhat.com A4410C05AA59
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
On ppc64le we ICE on the following testcase, because during jump2 we decide
to cross-jump
(insn/f 62 61 63 5 (unspec_volatile [
(const_int 0 [0])
] UNSPECV_BLOCK) "pr80102.C":9 -1
(expr_list:REG_CFA_RESTORE (reg:DI 30 30)
(nil)))
(jump_insn 63 62 90 5 (simple_return) "pr80102.C":9 -1
(nil)
with
(insn 73 72 84 8 (unspec_volatile [
(const_int 0 [0])
] UNSPECV_BLOCK) "pr80102.C":9 504 {blockage}
(nil))
(jump_insn 84 73 85 8 (simple_return) "pr80102.C":9 -1
(nil)
Note that one of the blockage insns holds CFI instructions on them, while
the other doesn't (admittedly it is very weird to attach this to an empty
insn, but that is what the rs6000 backend does).
The following patch fixes that by avoiding to cross-jump them, because
that will often read to unwind info inconsistencies.
Not really sure what we should do if both i1 and i2 are frame related, shall
we check for each of the CFA reg notes if they are available and equal?
Or punt if either of the insns is frame related?
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2017-03-20 Jakub Jelinek <jakub@redhat.com>
PR target/80102
* cfgcleanup.c (old_insns_match_p): Don't cross-jump in between /f
and non-/f instructions.
* g++.dg/opt/pr80102.C: New test.
--- gcc/cfgcleanup.c.jj 2017-01-09 22:46:03.000000000 +0100
+++ gcc/cfgcleanup.c 2017-03-20 13:55:58.823983848 +0100
@@ -1149,6 +1149,11 @@ old_insns_match_p (int mode ATTRIBUTE_UN
else if (p1 || p2)
return dir_none;
+ /* Do not allow cross-jumping between frame related insns and other
+ insns. */
+ if (RTX_FRAME_RELATED_P (i1) != RTX_FRAME_RELATED_P (i2))
+ return dir_none;
+
p1 = PATTERN (i1);
p2 = PATTERN (i2);
--- gcc/testsuite/g++.dg/opt/pr80102.C.jj 2017-03-20 14:34:01.223434828 +0100
+++ gcc/testsuite/g++.dg/opt/pr80102.C 2017-03-20 14:33:36.000000000 +0100
@@ -0,0 +1,14 @@
+// PR target/80102
+// { dg-do compile }
+// { dg-options "-fnon-call-exceptions -Os" }
+// { dg-additional-options "-mminimal-toc" { target { powerpc*-*-* && lp64 } } }
+
+struct B { float a; B (float c) { for (int g; g < c;) ++a; } };
+struct D { D (B); };
+
+int
+main ()
+{
+ B (1.0);
+ D e (0.0), f (1.0);
+}
Jakub