diff options
author | Richard Henderson <rth@gcc.gnu.org> | 2014-03-21 08:31:25 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2014-03-21 08:31:25 -0700 |
commit | ec6f831a27001652401b20331a5edc1c737d9fe3 (patch) | |
tree | c6bbcadd7e846ee00216aaccb8e7b22363a80483 /gcc | |
parent | 3d8d00439b8507ebb9c89949d44133bbdcde333f (diff) | |
download | gcc-ec6f831a27001652401b20331a5edc1c737d9fe3.zip gcc-ec6f831a27001652401b20331a5edc1c737d9fe3.tar.gz gcc-ec6f831a27001652401b20331a5edc1c737d9fe3.tar.bz2 |
re PR target/60598 (ICE in maybe_record_trace_start, at dwarf2cfi.c:2239)
PR target/60598
* ifcvt.c (dead_or_predicable): Return FALSE if there are any frame
related insns after epilogue_completed.
* gcc.dg/pr60598.c: New test.
From-SVN: r208749
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/ifcvt.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr60598.c | 26 |
4 files changed, 52 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 57a7688..3254036 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2014-03-21 Richard Henderson <rth@twiddle.net> + + PR target/60598 + * ifcvt.c (dead_or_predicable): Return FALSE if there are any frame + related insns after epilogue_completed. + 2014-03-21 Martin Jambor <mjambor@suse.cz> PR ipa/59176 diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 79aa2f3..0d1adce 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -4144,6 +4144,21 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb, end = PREV_INSN (end); } + /* Don't move frame-related insn across the conditional branch. This + can lead to one of the paths of the branch having wrong unwind info. */ + if (epilogue_completed) + { + rtx insn = head; + while (1) + { + if (INSN_P (insn) && RTX_FRAME_RELATED_P (insn)) + return FALSE; + if (insn == end) + break; + insn = NEXT_INSN (insn); + } + } + /* Disable handling dead code by conditional execution if the machine needs to do anything funny with the tests, etc. */ #ifndef IFCVT_MODIFY_TESTS diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9740621..a04e2d0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-03-21 Jakub Jelinek <jakub@redhat.com> + + PR target/60598 + * gcc.dg/pr60598.c: New test. + 2014-03-21 Martin Jambor <mjambor@suse.cz> PR ipa/59176 diff --git a/gcc/testsuite/gcc.dg/pr60598.c b/gcc/testsuite/gcc.dg/pr60598.c new file mode 100644 index 0000000..331e8bd --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr60598.c @@ -0,0 +1,26 @@ +/* PR target/60598 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-additional-options "-fpic" { target fpic } } */ +/* { dg-additional-options "-march=z196 -mtune=zEC12" { target s390*-*-* } } */ + +struct S { unsigned a, b[32]; }; + +void +foo (struct S *x, struct S *y) +{ + unsigned a = y->a, i; + if (x == y) + for (i = 0; i < a - 1 - i; i++) + { + unsigned t = x->b[i]; + x->b[i] = x->b[a - 1 - i]; + x->b[a - 1 - i] = t; + } + else + { + x->a = a; + for (i = 0; i < a; i++) + x->b[i] = y->b[a - 1 - i]; + } +} |