re PR target/64338 (ICE in swap_condition, at jump.c:628)
authorJakub Jelinek <jakub@redhat.com>
Thu, 8 Jan 2015 19:15:53 +0000 (20:15 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 8 Jan 2015 19:15:53 +0000 (20:15 +0100)
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
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/pr64338.C [new file with mode: 0644]

index f9b3c55..ff6abdd 100644 (file)
@@ -1,3 +1,12 @@
+2015-01-08  Jakub Jelinek  <jakub@redhat.com>
+
+       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  <mikestump@comcast.net>
 
        * tsan.c (pass_tsan::gate): Add no_sanitize_thread support.
index dc2b7d8..340348e 100644 (file)
@@ -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)
index 5812067..4c67aa9 100644 (file)
@@ -1,3 +1,8 @@
+2015-01-08  Jakub Jelinek  <jakub@redhat.com>
+
+       PR target/64338
+       * g++.dg/opt/pr64338.C: New test.
+
 2015-01-08  Tobias Burnus  <burnus@net-b.de>
 
        * 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 (file)
index 0000000..699d38c
--- /dev/null
@@ -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 ();
+}