[PATCH] Fix ix86_expand_int_movcc (PR target/64338)

Jakub Jelinek jakub@redhat.com
Thu Jan 8 19:17:00 GMT 2015


On Thu, Jan 08, 2015 at 07:37:44PM +0100, Uros Bizjak wrote:
> Please put std::swap at the top, above code= assignment. Cosmetic, but
> I noticed this during std::swap conversion. ;)

Ok.  Put there also the diff = -diff; assignment and cf = ct; ct = 0; swap
to keep the order that used to be there before.

> > --- gcc/testsuite/g++.dg/opt/pr64338.C.jj       2015-01-07 10:18:04.740275018 +0100
> > +++ gcc/testsuite/g++.dg/opt/pr64338.C  2015-01-07 10:17:50.000000000 +0100
> > @@ -0,0 +1,29 @@
> > +// PR target/64338
> > +// { dg-do compile }
> > +// { dg-options "-O2" }
> > +// { dg-additional-options "-mtune=generic -march=i586" { target { { i?86-*-* x86_64-*-* } && ia32 } } }
> 
> Please use -mtune=i686, generic tuning setting changes over time ...

That doesn't ICE without the patch, so I've changed it to -mtune=nehalem
instead.  So, here is what I've checked in.

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.

	* g++.dg/opt/pr64338.C: New test.

--- gcc/config/i386/i386.c.jj	2015-01-08 10:19:00.337260146 +0100
+++ gcc/config/i386/i386.c	2015-01-08 20:09:30.716001199 +0100
@@ -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)
--- gcc/testsuite/g++.dg/opt/pr64338.C.jj	2015-01-08 20:07:09.790383489 +0100
+++ gcc/testsuite/g++.dg/opt/pr64338.C	2015-01-08 20:11:26.756039590 +0100
@@ -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 ();
+}


	Jakub



More information about the Gcc-patches mailing list