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 endless recursion in BIT_AND_EXPR folding (PR middle-end/40204)


Hi!

On the attached testcase we endlessly recurse between fold_binary
(BIT_AND_EXPR, ...) and fold_build2 (BIT_AND_EXPR, ...).  The problem
is in the PR29749 optimization, if op1 has a smaller precision type,
newmask might be different from mask, yet build_int_cst_type
might strip the extra bits again, yielding identical constant as arg1.

Fixed by checking for this and not recursing in that case.

Bootstrapped/regtested on x86_64-linux, ok for trunk/4.4?

2009-05-20  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/40204
	* fold-const.c (fold_binary) <case BIT_AND_EXPR>: Avoid infinite
	recursion if build_int_cst_type returns the same INTEGER_CST as
	arg1.

	* gcc.c-torture/compile/pr40204.c: New test.

--- gcc/fold-const.c.jj	2009-05-19 10:51:32.000000000 +0200
+++ gcc/fold-const.c	2009-05-20 18:18:04.000000000 +0200
@@ -11375,6 +11375,8 @@ fold_binary (enum tree_code code, tree t
 	      if (prec < HOST_BITS_PER_WIDE_INT
 		  || newmask == ~(unsigned HOST_WIDE_INT) 0)
 		{
+		  tree newmaskt;
+
 		  if (shift_type != TREE_TYPE (arg0))
 		    {
 		      tem = fold_build2 (TREE_CODE (arg0), shift_type,
@@ -11385,9 +11387,9 @@ fold_binary (enum tree_code code, tree t
 		    }
 		  else
 		    tem = op0;
-		  return fold_build2 (BIT_AND_EXPR, type, tem,
-				      build_int_cst_type (TREE_TYPE (op1),
-							  newmask));
+		  newmaskt = build_int_cst_type (TREE_TYPE (op1), newmask);
+		  if (!tree_int_cst_equal (newmaskt, arg1))
+		    return fold_build2 (BIT_AND_EXPR, type, tem, newmaskt);
 		}
 	    }
 	}
--- gcc/testsuite/gcc.c-torture/compile/pr40204.c.jj	2009-05-20 18:20:41.000000000 +0200
+++ gcc/testsuite/gcc.c-torture/compile/pr40204.c	2009-05-20 18:20:19.000000000 +0200
@@ -0,0 +1,14 @@
+/* PR middle-end/40204 */
+
+struct S
+{
+  unsigned int a : 4;
+  unsigned int b : 28;
+} s;
+char c;
+
+void
+f (void)
+{
+  s.a = (c >> 4) & ~(1 << 4);
+}

	Jakub


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