From efa7df3c625146460d7ec345d32a4efb42be871b Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 8 Jan 2015 20:15:53 +0100 Subject: [PATCH] re PR target/64338 (ICE in swap_condition, at jump.c:628) PR target/64338 * config/i386/i386.c (ix86_expand_int_movcc): Don't reverse compare_code when it is unconditionally overwritten afterwards. Use ix86_reverse_condition instead of reverse_condition. Don't change code if *reverse_condition* returned UNKNOWN and don't swap ct/cf and negate diff in that case. * g++.dg/opt/pr64338.C: New test. From-SVN: r219356 --- gcc/ChangeLog | 9 +++++++++ gcc/config/i386/i386.c | 31 +++++++++++++++++------------- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/opt/pr64338.C | 29 ++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/g++.dg/opt/pr64338.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f9b3c559a95..ff6abddfe50 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2015-01-08 Jakub Jelinek + + PR target/64338 + * config/i386/i386.c (ix86_expand_int_movcc): Don't reverse + compare_code when it is unconditionally overwritten afterwards. + Use ix86_reverse_condition instead of reverse_condition. Don't + change code if *reverse_condition* returned UNKNOWN and don't + swap ct/cf and negate diff in that case. + 2015-01-08 Mike Stump * tsan.c (pass_tsan::gate): Add no_sanitize_thread support. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index dc2b7d80887..340348eafb0 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -20830,9 +20830,7 @@ ix86_expand_int_movcc (rtx operands[]) if (diff < 0) { machine_mode cmp_mode = GET_MODE (op0); - - std::swap (ct, cf); - diff = -diff; + enum rtx_code new_code; if (SCALAR_FLOAT_MODE_P (cmp_mode)) { @@ -20842,13 +20840,15 @@ ix86_expand_int_movcc (rtx operands[]) is not valid in general (we may convert non-trapping condition to trapping one), however on i386 we currently emit all comparisons unordered. */ - compare_code = reverse_condition_maybe_unordered (compare_code); - code = reverse_condition_maybe_unordered (code); + new_code = reverse_condition_maybe_unordered (code); } else + new_code = ix86_reverse_condition (code, cmp_mode); + if (new_code != UNKNOWN) { - compare_code = reverse_condition (compare_code); - code = reverse_condition (code); + std::swap (ct, cf); + diff = -diff; + code = new_code; } } @@ -20986,9 +20986,7 @@ ix86_expand_int_movcc (rtx operands[]) if (cf == 0) { machine_mode cmp_mode = GET_MODE (op0); - - cf = ct; - ct = 0; + enum rtx_code new_code; if (SCALAR_FLOAT_MODE_P (cmp_mode)) { @@ -20998,14 +20996,21 @@ ix86_expand_int_movcc (rtx operands[]) that is not valid in general (we may convert non-trapping condition to trapping one), however on i386 we currently emit all comparisons unordered. */ - code = reverse_condition_maybe_unordered (code); + new_code = reverse_condition_maybe_unordered (code); } else { - code = reverse_condition (code); - if (compare_code != UNKNOWN) + new_code = ix86_reverse_condition (code, cmp_mode); + if (compare_code != UNKNOWN && new_code != UNKNOWN) compare_code = reverse_condition (compare_code); } + + if (new_code != UNKNOWN) + { + cf = ct; + ct = 0; + code = new_code; + } } if (compare_code != UNKNOWN) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5812067bc76..4c67aa983fe 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-01-08 Jakub Jelinek + + PR target/64338 + * g++.dg/opt/pr64338.C: New test. + 2015-01-08 Tobias Burnus * gfortran.dg/coarray/codimension_2b.f90: New file. diff --git a/gcc/testsuite/g++.dg/opt/pr64338.C b/gcc/testsuite/g++.dg/opt/pr64338.C new file mode 100644 index 00000000000..699d38ccea1 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr64338.C @@ -0,0 +1,29 @@ +// PR target/64338 +// { dg-do compile } +// { dg-options "-O2" } +// { dg-additional-options "-mtune=nehalem -march=i586" { target { { i?86-*-* x86_64-*-* } && ia32 } } } + +enum O {}; +struct A { A (); }; +struct B { int fn1 (); }; +struct C { struct D; D *fn2 (); void fn3 (); int fn4 (); }; +struct F { void fn5 (const int & = 0); }; +struct G { F *fn6 (); }; +struct H { int h; }; +struct C::D { friend class C; G *fn7 (); }; +O a; + +void +C::fn3 () +{ + int b = a; + H c; + if (b) + fn2 ()->fn7 ()->fn6 ()->fn5 (); + double d; + if (fn4 ()) + d = c.h > 0; + A e (b ? A () : A ()); + B f; + f.fn1 () && d && fn2 (); +} -- 2.30.2