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] Fix i++ << 16 << 16 folding (PR c/39855)


Hi!

When fold_binary optimizes two shifts together bigger or equal to precision
into 0, it forgot to evaluate any side-effects.

Fixed thusly, bootstrapped/regtested on x86_64-linux, ok for trunk/4.4?

2009-04-22  Jakub Jelinek  <jakub@redhat.com>

	PR c/39855
	* fold-const.c (fold_binary) <case LSHIFT_EXPR>: When optimizing
	into 0, use omit_one_operand.

	* gcc.dg/torture/pr39855.c: New test.

--- gcc/fold-const.c.jj	2009-04-14 16:33:54.000000000 +0200
+++ gcc/fold-const.c	2009-04-22 22:21:37.000000000 +0200
@@ -11862,7 +11862,8 @@ fold_binary (enum tree_code code, tree t
 	      if (code == LROTATE_EXPR || code == RROTATE_EXPR)
 	        low = low % TYPE_PRECISION (type);
 	      else if (TYPE_UNSIGNED (type) || code == LSHIFT_EXPR)
-	        return build_int_cst (type, 0);
+		return omit_one_operand (type, build_int_cst (type, 0),
+					 TREE_OPERAND (arg0, 0));
 	      else
 		low = TYPE_PRECISION (type) - 1;
 	    }
--- gcc/testsuite/gcc.dg/torture/pr39855.c.jj	2009-04-22 22:13:37.000000000 +0200
+++ gcc/testsuite/gcc.dg/torture/pr39855.c	2009-04-22 22:23:06.000000000 +0200
@@ -0,0 +1,24 @@
+/* PR c/39855 */
+/* { dg-do run { target { int32plus } } } */
+
+extern void abort (void);
+
+int i, j, k;
+
+int
+foo (void)
+{
+  return ++i;
+}
+
+int
+main ()
+{
+  if (__CHAR_BIT__ != 8 || sizeof (int) != 4)
+    return 0;
+  j = foo () << 30 << 2;
+  k = (unsigned) foo () >> 16 >> 16;
+  if (i != 2 || j != 0 || k != 0)
+    abort ();
+  return 0;
+}

	Jakub


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