This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

fix target/19506


Exceedingly nasty to track down, this one.

The ultimate problem is that we had

	[(set (reg:df 101)
	      (if_then_else:df (lt (reg:df 101) (reg:df 102))
		(reg:df 103)
		(reg:df 101)))
	 (clobber (reg:v2df 103))]

and the splitter clobbered the destination reg101 before using
it from the false branch of the if_then_else.

I never managed to produce a self-contained test case for this.
All attempts resulted in register assignments from reload that
didn't trigger the bug in the splitter.  But in case anyone else
wants to try, look at povray-3.6.1/source/bbox.o from before this
patch and look for "andpd %xmmN, %xmmN".

Anyway, tested on i686-linux, and with povray 3.6 with -mfpmath=sse.


r~


        * config/i386/i386.md (movsfcc_1_sse_max): Use nonimmediate_operand
        in both compare operands.
        (movdfcc_1_sse_max): Likewise.
        (movsfcc_1_sse): Likewise.  Add earlyclobber for scratch.
        (movdfcc_1_sse): Likewise.
        * config/i386/i386.c (ix86_split_sse_movcc): Emit copies into the
        scratch register as needed.

Index: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.788
diff -u -p -d -r1.788 i386.c
--- config/i386/i386.c	22 Jan 2005 22:56:11 -0000	1.788
+++ config/i386/i386.c	22 Jan 2005 23:03:21 -0000
@@ -9920,8 +9920,48 @@ ix86_split_sse_movcc (rtx operands[])
   mode = GET_MODE (dest);
   vmode = GET_MODE (scratch);
 
-  emit_insn (gen_rtx_SET (VOIDmode, dest, cmp));
+  /* We need to make sure that the TRUE and FALSE operands are out of the
+     way of the destination.  Marking the destination earlyclobber doesn't
+     work, since we want matching constraints for the actual comparison, so
+     at some point we always wind up having to do a copy ourselves here.
+     We very much prefer the TRUE value to be in SCRATCH.  If it turns out
+     that FALSE overlaps DEST, then we invert the comparison so that we
+     still only have to do one move.  */
+  if (rtx_equal_p (op_false, dest))
+    {
+      enum rtx_code code;
+
+      if (rtx_equal_p (op_true, dest))
+	{
+	  /* ??? Really ought not happen.  It means some optimizer managed
+	     to prove the operands were identical, but failed to fold the
+	     conditional move to a straight move.  Do so here, because 
+	     otherwise we'll generate incorrect code.  And since they're
+	     both already in the destination register, nothing to do.  */
+	  return;
+	}
 
+      x = gen_rtx_REG (mode, REGNO (scratch));
+      emit_move_insn (x, op_false);
+      op_false = op_true;
+      op_true = x;
+
+      code = GET_CODE (cmp);
+      code = reverse_condition_maybe_unordered (code);
+      cmp = gen_rtx_fmt_ee (code, mode, XEXP (cmp, 0), XEXP (cmp, 1));
+    }
+  else if (op_true == CONST0_RTX (mode))
+    ;
+  else if (op_false == CONST0_RTX (mode) && !rtx_equal_p (op_true, dest))
+    ;
+  else
+    {
+      x = gen_rtx_REG (mode, REGNO (scratch));
+      emit_move_insn (x, op_true);
+      op_true = x;
+    }
+
+  emit_insn (gen_rtx_SET (VOIDmode, dest, cmp));
   dest = simplify_gen_subreg (vmode, dest, mode, 0);
 
   if (op_false == CONST0_RTX (mode))
Index: config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.609
diff -u -p -d -r1.609 i386.md
--- config/i386/i386.md	22 Jan 2005 22:59:33 -0000	1.609
+++ config/i386/i386.md	22 Jan 2005 23:03:24 -0000
@@ -17443,7 +17443,7 @@
   [(set (match_operand:SF 0 "register_operand" "=x")
 	(if_then_else:SF
 	  (lt:SF (match_operand:SF 2 "nonimmediate_operand" "xm")
-		 (match_operand:SF 1 "register_operand" "0"))
+		 (match_operand:SF 1 "nonimmediate_operand" "0"))
 	  (match_dup 1)
 	  (match_dup 2)))]
   "TARGET_SSE_MATH"
@@ -17457,9 +17457,9 @@
 	  (match_operator:SF 4 "sse_comparison_operator"
 	    [(match_operand:SF 5 "register_operand" "0,0,0")
 	     (match_operand:SF 6 "nonimmediate_operand" "xm,xm,xm")])
-	  (match_operand:SF 2 "reg_or_0_operand" "C,x,1")
+	  (match_operand:SF 2 "reg_or_0_operand" "C,x,x")
 	  (match_operand:SF 3 "reg_or_0_operand" "x,C,x")))
-   (clobber (match_scratch:V4SF 1 "=X,X,x"))]
+   (clobber (match_scratch:V4SF 1 "=&x,&x,&x"))]
   "TARGET_SSE_MATH"
   "#"
   "&& reload_completed"
@@ -17512,7 +17512,7 @@
   [(set (match_operand:DF 0 "register_operand" "=x")
 	(if_then_else:DF
 	  (lt:DF (match_operand:DF 2 "nonimmediate_operand" "xm")
-		 (match_operand:DF 1 "register_operand" "0"))
+		 (match_operand:DF 1 "nonimmediate_operand" "0"))
 	  (match_dup 1)
 	  (match_dup 2)))]
   "TARGET_SSE2 && TARGET_SSE_MATH"
@@ -17526,9 +17526,9 @@
 	  (match_operator:DF 4 "sse_comparison_operator"
 	    [(match_operand:DF 5 "register_operand" "0,0,0")
 	     (match_operand:DF 6 "nonimmediate_operand" "xm,xm,xm")])
-	  (match_operand:DF 2 "reg_or_0_operand" "C,x,1")
+	  (match_operand:DF 2 "reg_or_0_operand" "C,x,x")
 	  (match_operand:DF 3 "reg_or_0_operand" "x,C,x")))
-   (clobber (match_scratch:V2DF 1 "=X,X,x"))]
+   (clobber (match_scratch:V2DF 1 "=&x,&x,&x"))]
   "TARGET_SSE2 && TARGET_SSE_MATH"
   "#"
   "&& reload_completed"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]