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] Avoid creating TREE_OVERFLOW constants in convert_to_integer (PR middle-end/26729)


Hi!

convert_to_integer seems to optimize truncation (shouldn't that be solely
fold's job?), but during that can create integer overflowed constants that
mess optimizers later on.  The following patch fixes that by doing the same
that e.g. the C frontend does after calling convert - dropping the overflow
bit if it was introduced during the optimization.
Bootstrapped/regtested on x86_64-linux, ok for trunk/4.1?
I know Roger's patch might make this eventually unnecessary on the trunk,
still 4.1 branch is probably not going to have those changes.

2006-04-19  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/26729
	* convert.c (convert_to_integer): Ignore integer overflows when
	truncating.

	* gcc.c-torture/execute/20060419-1.c: New test.

--- gcc/convert.c.jj	2006-04-19 16:23:13.000000000 +0200
+++ gcc/convert.c	2006-04-19 17:11:43.000000000 +0200
@@ -616,6 +616,7 @@ convert_to_integer (tree type, tree expr
 		   (Otherwise would recurse infinitely in convert.  */
 		if (TYPE_PRECISION (typex) != inprec)
 		  {
+		    tree carg0, carg1;
 		    /* Don't do unsigned arithmetic where signed was wanted,
 		       or vice versa.
 		       Exception: if both of the original operands were
@@ -648,10 +649,29 @@ convert_to_integer (tree type, tree expr
 		      typex = lang_hooks.types.unsigned_type (typex);
 		    else
 		      typex = lang_hooks.types.signed_type (typex);
-		    return convert (type,
-				    fold_build2 (ex_form, typex,
-						 convert (typex, arg0),
-						 convert (typex, arg1)));
+		    carg0 = convert (typex, arg0);
+		    carg1 = convert (typex, arg1);
+		    /* Ignore integer overflows caused by the downcasts.  */
+		    if (TREE_CODE (carg0) == INTEGER_CST
+			&& (TREE_OVERFLOW (carg0)
+			    || TREE_CONSTANT_OVERFLOW (carg0))
+			&& (!CONSTANT_CLASS_P (arg0)
+			    || (!TREE_OVERFLOW (arg0)
+				&& !TREE_CONSTANT_OVERFLOW (arg0))))
+		      carg0 = build_int_cst_wide (typex,
+						  TREE_INT_CST_LOW (carg0),
+						  TREE_INT_CST_HIGH (carg0));
+		    if (TREE_CODE (carg1) == INTEGER_CST
+			&& (TREE_OVERFLOW (carg1)
+			    || TREE_CONSTANT_OVERFLOW (carg1))
+			&& (!CONSTANT_CLASS_P (arg1)
+			    || (!TREE_OVERFLOW (arg1)
+				&& !TREE_CONSTANT_OVERFLOW (arg1))))
+		      carg1 = build_int_cst_wide (typex,
+						  TREE_INT_CST_LOW (carg1),
+						  TREE_INT_CST_HIGH (carg1));
+		    return convert (type, fold_build2 (ex_form, typex,
+						       carg0, carg1));
 		  }
 	      }
 	  }
--- gcc/testsuite/gcc.c-torture/execute/20060419-1.c.jj	2006-04-19 17:15:12.000000000 +0200
+++ gcc/testsuite/gcc.c-torture/execute/20060419-1.c	2006-04-19 17:16:13.000000000 +0200
@@ -0,0 +1,17 @@
+/* PR middle-end/26729 */
+
+void abort (void);
+
+int
+foo (unsigned short x)
+{
+  return (x & 0x1) && (((unsigned short) (x & 0x8000)) == 0x8000);
+}
+
+int
+main (void)
+{
+  if (! foo (0x8001))
+    abort ();
+  return 0;
+}

	Jakub


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