[PATCH] Don't simplify_conversion_from_bitmask on x & 1 (PR tree-optimization/59014)

Marek Polacek polacek@redhat.com
Thu Nov 7 15:23:00 GMT 2013


Here, forward propagation turned
  _6 = a.1_5 & 1;
  _7 = (_Bool) _6;
into
  _7 = (_Bool) a.1_5;
but that's wrong: e.g. if a = 2 then (_Bool) _6 is 0, but (_Bool) a.1_5 is 1.
If a is an odd number, this is correct, but we don't know the value
of a, so I disabled this optimization for "x & 1" cases.  For e.g. "x & 255",
this still works correctly.

In this PR, VRP created wrong ASSERT_EXPR because of this, thus we were
miscompiling the following testcase...

Regtested/bootstrapped on x86_64-linux, ok for trunk?

2013-11-07  Marek Polacek  <polacek@redhat.com>

	PR tree-optimization/59014
	* tree-ssa-forwprop.c (simplify_conversion_from_bitmask): Don't
	optimize x & 1 expressions here.
testsuite/
	* gcc.dg/torture/pr59014.c: New test.

--- gcc/testsuite/gcc.dg/torture/pr59014.c.mp	2013-11-07 14:47:38.040941144 +0100
+++ gcc/testsuite/gcc.dg/torture/pr59014.c	2013-11-07 14:49:03.646271031 +0100
@@ -0,0 +1,26 @@
+/* PR tree-optimization/59014 */
+/* { dg-do run } */
+
+int a = 2, b, c, d;
+
+int
+foo ()
+{
+  for (;; c++)
+    if ((b > 0) | (a & 1))
+      ;
+    else
+      {
+	d = a;
+	return 0;
+      }
+}
+
+int
+main ()
+{
+  foo ();
+  if (d != 2)
+    __builtin_abort ();
+  return 0;
+}
--- gcc/tree-ssa-forwprop.c.mp	2013-11-07 14:30:43.785733810 +0100
+++ gcc/tree-ssa-forwprop.c	2013-11-07 14:42:31.836765375 +0100
@@ -1199,9 +1199,16 @@ simplify_conversion_from_bitmask (gimple
       if (TREE_CODE (rhs_def_operand1) == SSA_NAME
 	  && ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs_def_operand1)
 	  && TREE_CODE (rhs_def_operand2) == INTEGER_CST
+	  /* We can't turn
+	       _6 = a & 1;
+	       _7 = (_Bool) _6;
+	     into
+	       _7 = (_Bool) a;
+	     as that's wrong if A is an even number.  */
+	  && ! integer_onep (rhs_def_operand2)
 	  && operand_equal_p (rhs_def_operand2,
 			      build_low_bits_mask (TREE_TYPE (rhs_def_operand2),
-			       			   TYPE_PRECISION (lhs_type)),
+						   TYPE_PRECISION (lhs_type)),
 						   0))
 	{
 	  /* This is an optimizable case.  Replace the source operand

	Marek



More information about the Gcc-patches mailing list