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]

[PATCH][4.3] Fix PR37969, backport fix for PR37489


Same problem, other result.

Bootstrap and regtest in progress, I'll apply this to the branch and
the new testcase to the trunk afterwards.

Richard.

2008-11-06  Richard Guenther  <rguenther@suse.de>
 
 	Backport from mainline:
 	2008-09-13  H.J. Lu  <hongjiu.lu@intel.com>
 
 	PR rtl-optimization/37489
 	* cse.c (fold_rtx): Don't return const_true_rtx for float
 	compare if FLOAT_STORE_FLAG_VALUE is undefined.

 	* g++.dg/opt/cse3.C: New testcase.
	* gcc.dg/torture/pr37969.c: New testcase.

Index: cse.c
===================================================================
*** cse.c	(revision 141622)
--- cse.c	(working copy)
*************** fold_rtx (rtx x, rtx insn)
*** 3182,3198 ****
        if (const_arg0 == 0 || const_arg1 == 0)
  	{
  	  struct table_elt *p0, *p1;
! 	  rtx true_rtx = const_true_rtx, false_rtx = const0_rtx;
  	  enum machine_mode mode_arg1;
  
- #ifdef FLOAT_STORE_FLAG_VALUE
  	  if (SCALAR_FLOAT_MODE_P (mode))
  	    {
  	      true_rtx = (CONST_DOUBLE_FROM_REAL_VALUE
  			  (FLOAT_STORE_FLAG_VALUE (mode), mode));
  	      false_rtx = CONST0_RTX (mode);
  	    }
! #endif
  
  	  code = find_comparison_args (code, &folded_arg0, &folded_arg1,
  				       &mode_arg0, &mode_arg1);
--- 3182,3205 ----
        if (const_arg0 == 0 || const_arg1 == 0)
  	{
  	  struct table_elt *p0, *p1;
! 	  rtx true_rtx, false_rtx;
  	  enum machine_mode mode_arg1;
  
  	  if (SCALAR_FLOAT_MODE_P (mode))
  	    {
+ #ifdef FLOAT_STORE_FLAG_VALUE
  	      true_rtx = (CONST_DOUBLE_FROM_REAL_VALUE
  			  (FLOAT_STORE_FLAG_VALUE (mode), mode));
+ #else
+ 	      true_rtx = NULL_RTX;
+ #endif
  	      false_rtx = CONST0_RTX (mode);
  	    }
! 	  else
! 	    {
! 	      true_rtx = const_true_rtx;
! 	      false_rtx = const0_rtx;
! 	    }
  
  	  code = find_comparison_args (code, &folded_arg0, &folded_arg1,
  				       &mode_arg0, &mode_arg1);
*************** fold_rtx (rtx x, rtx insn)
*** 3300,3307 ****
  						  const_arg1))
  			      || (REG_P (folded_arg1)
  				  && (REG_QTY (REGNO (folded_arg1)) == ent->comparison_qty))))
! 			return (comparison_dominates_p (ent->comparison_code, code)
! 				? true_rtx : false_rtx);
  		    }
  		}
  	    }
--- 3307,3323 ----
  						  const_arg1))
  			      || (REG_P (folded_arg1)
  				  && (REG_QTY (REGNO (folded_arg1)) == ent->comparison_qty))))
! 			{
! 			  if (comparison_dominates_p (ent->comparison_code, code))
! 			    {
! 			      if (true_rtx)
! 				return true_rtx;
! 			      else
! 				break;
! 			    }
! 			  else
! 			    return false_rtx;
! 			}
  		    }
  		}
  	    }
Index: testsuite/g++.dg/opt/cse3.C
===================================================================
*** testsuite/g++.dg/opt/cse3.C	(revision 0)
--- testsuite/g++.dg/opt/cse3.C	(revision 0)
***************
*** 0 ****
--- 1,48 ----
+ // This testcase resulted in invalid code generation on x86_64 targets
+ // due to a bug in fold_rtx. For a "true" value, fold_rtx represented it
+ // as const_true_rtx in floating-point mode, if the FLOAT_STORE_FLAG_VALUE
+ // macro is not defined.
+ 
+ // { dg-do run }
+ // { dg-options "-O1 -fno-guess-branch-probability -fcse-follow-jumps -fgcse -frerun-cse-after-loop" }
+ 
+ class StatVal {
+ 
+  public:
+ 
+   StatVal(double ev, double va)
+     : m(ev),
+       v(va) {}
+ 
+   StatVal(const StatVal& other)
+     : m(other.m),
+       v(other.v) {}
+ 
+   StatVal& operator*=(const StatVal& other) {
+     double A = m == 0 ? 1.0 : v / (m * m);
+     double B = other.m == 0 ? 1.0 : other.v / (other.m * other.m);
+     m = m * other.m;
+     v = m * m * (A + B);
+     return *this;
+   }
+ 
+   double m;
+   double v;
+ };
+ 
+ extern "C" void abort (void);
+ 
+ const StatVal two_dot_three(2, 0.3);
+ 
+ int main(int argc, char **argv) {
+ 
+   StatVal product3(two_dot_three);
+ 
+   product3 *= two_dot_three;
+ 
+   if (product3.v > 2.5)
+   {
+     abort();
+   }
+   return 0;
+ }
Index: testsuite/gcc.dg/torture/pr37969.c
===================================================================
--- testsuite/gcc.dg/torture/pr37969.c	(revision 0)
+++ testsuite/gcc.dg/torture/pr37969.c	(revision 0)
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-funswitch-loops" } */
+
+void foo(double);
+void CreateDefaultTexture(double mnMinimum, double mnMaximum,
+			  unsigned short nCreateWhat)
+{
+  double d = 0.0;
+  for(;;)
+    {
+      if(nCreateWhat & (0x0001)
+	 && mnMinimum != 0.0)
+	d = mnMinimum;
+      if(nCreateWhat & (0x0002)
+	 && mnMaximum != 0.0)
+	d = mnMaximum;
+      foo(d);
+    }
+}
+


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