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: PR middle-end/37731: [4.2/4.3/4.4 Regression] long long may not work correctly on 32bit host


When we multiple a DImode constant in CONST_DOUBLE, if
CONST_DOUBLE_HIGH (op1) == 0, the constant is positive. 
In this case, we should check CONST_DOUBLE_LOW (op1) > 0.
OK for trunk and active branches?

Thanks.


H.J.
----
gcc/

2008-10-04  H.J. Lu  <hongjiu.lu@intel.com>

	PR middle-end/37731
	* expmed.c (expand_mult): Properly check DImode constant in
	CONST_DOUBLE.

gcc/testsuite/

2008-10-04  H.J. Lu  <hongjiu.lu@intel.com>

	PR middle-end/37731
	* gcc.dg/torture/pr37731-1.c: New.
	* gcc.dg/torture/pr37731-2.c: Likewise.

--- gcc/expmed.c.ll	2008-09-29 08:37:56.000000000 -0700
+++ gcc/expmed.c	2008-10-04 13:33:26.000000000 -0700
@@ -3075,7 +3075,8 @@ expand_mult (enum machine_mode mode, rtx
 	{
 	  /* If we are multiplying in DImode, it may still be a win
 	     to try to work with shifts and adds.  */
-	  if (CONST_DOUBLE_HIGH (op1) == 0)
+	  if (CONST_DOUBLE_HIGH (op1) == 0
+	      && CONST_DOUBLE_LOW (op1) > 0)
 	    coeff = CONST_DOUBLE_LOW (op1);
 	  else if (CONST_DOUBLE_LOW (op1) == 0
 		   && EXACT_POWER_OF_2_OR_ZERO_P (CONST_DOUBLE_HIGH (op1)))
--- gcc/testsuite/gcc.dg/torture/pr37731-1.c.ll	2008-10-04 13:32:05.000000000 -0700
+++ gcc/testsuite/gcc.dg/torture/pr37731-1.c	2008-10-04 13:29:43.000000000 -0700
@@ -0,0 +1,17 @@
+/* { dg-do run } */
+
+extern void abort ();
+
+unsigned long long xh = 1;
+
+int
+main ()
+{
+  unsigned long long yh = 0xffffffffull;
+  unsigned long long z = xh * yh;
+
+  if (z != yh)
+    abort ();
+
+  return 0;
+}
--- gcc/testsuite/gcc.dg/torture/pr37731-2.c.ll	2008-10-04 13:32:09.000000000 -0700
+++ gcc/testsuite/gcc.dg/torture/pr37731-2.c	2008-10-04 13:29:34.000000000 -0700
@@ -0,0 +1,17 @@
+/* { dg-do run } */
+
+extern void abort ();
+
+long long xh = 1;
+
+int
+main ()
+{
+  long long yh = 0xffffffffll;
+  long long z = xh * yh;
+
+  if (z != yh)
+    abort ();
+
+  return 0;
+}


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