[match.pd] Fix for PR35691

Prathamesh Kulkarni prathamesh.kulkarni@linaro.org
Thu Nov 3 10:21:00 GMT 2016


Hi Richard,
The attached patch tries to fix PR35691, by adding the following two
transforms to match.pd:
(x == 0 && y == 0) -> (x | typeof(x)(y)) == 0.
(x != 0 || y != 0) -> (x | typeof(x)(y)) != 0.

For GENERIC, the "and" operator is truth_andif_expr, and it seems for GIMPLE,
it gets transformed to bit_and_expr
so to match for both GENERIC and GIMPLE, I had to guard the for-stmt:

#if GENERIC
(for op (truth_andif truth_orif)
#elif GIMPLE
(for op (bit_and bit_ior)
#endif

Is that OK ?
Bootstrap+test running on x86_64-unknown-linux-gnu.

Thanks,
Prathamesh
-------------- next part --------------
2016-11-03  Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.org>

	PR middle-end/35691
	* match.pd: Add following two patterns:
	(x == 0 & y == 0) -> (x | typeof(x)(y)) == 0.
	(x != 0 | y != 0) -> (x | typeof(x)(y)) != 0.

testsuite/
	* gcc.dg/pr35691-1.c: New test-case.
	* gcc.dg/pr35691-2.c: Likewise.
	* gcc.dg/pr35691-3.c: Likewise.
	* gcc.dg/pr35691-4.c: Likewise.

diff --git a/gcc/match.pd b/gcc/match.pd
index 48f7351..65930bb 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -519,6 +519,23 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (if (TYPE_UNSIGNED (type))
     (bit_and @0 (bit_not (lshift { build_all_ones_cst (type); } @1)))))
 
+/* PR35691: Transform
+   (x == 0 & y == 0) -> (x | typeof(x)(y)) == 0.
+   (x != 0 | y != 0) -> (x | typeof(x)(y)) != 0.  */
+
+#if GENERIC
+(for op (truth_andif truth_orif)
+#elif GIMPLE
+(for op (bit_and bit_ior)
+#endif
+     cmp (eq ne)
+ (simplify
+  (op (cmp @0 integer_zerop) (cmp @1 integer_zerop))
+   (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
+       && INTEGRAL_TYPE_P (TREE_TYPE (@1))
+       && TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (TREE_TYPE (@1)))
+    (cmp (bit_ior @0 (convert @1)) { build_zero_cst (TREE_TYPE (@0)); }))))
+
 /* Fold (A & ~B) - (A & B) into (A ^ B) - B.  */
 (simplify
  (minus (bit_and:cs @0 (bit_not @1)) (bit_and:cs @0 @1))
diff --git a/gcc/testsuite/gcc.dg/pr35691-1.c b/gcc/testsuite/gcc.dg/pr35691-1.c
new file mode 100644
index 0000000..25a7ace
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr35691-1.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-gimple" } */
+
+int foo1(int z0, unsigned z1) 
+{
+  return (z0 == 0) && (z1 == 0);
+}
+
+/* { dg-final { scan-tree-dump-not "z1.\[0-9\]*_\[0-9\]* = (int) z1" "gimple" } } */
diff --git a/gcc/testsuite/gcc.dg/pr35691-2.c b/gcc/testsuite/gcc.dg/pr35691-2.c
new file mode 100644
index 0000000..5211f815
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr35691-2.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-forwprop-details" } */
+
+int foo(int z0, unsigned z1)
+{
+  int t0 = (z0 == 0);
+  int t1 = (z1 == 0);
+  int t2 = (t0 && t1);
+  return t2;
+}
+
+/* { dg-final { scan-tree-dump "gimple_simplified to _\[0-9\]* = \\(int\\) z1_\[0-9\]*\\(D\\);" "forwprop1" } } */
diff --git a/gcc/testsuite/gcc.dg/pr35691-3.c b/gcc/testsuite/gcc.dg/pr35691-3.c
new file mode 100644
index 0000000..134bbdf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr35691-3.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-gimple" } */
+
+int foo1(int z0, unsigned z1) 
+{
+  return (z0 != 0) || (z1 != 0);
+}
+
+/* { dg-final { scan-tree-dump-not "z1.\[0-9\]*_\[0-9\]* = (int) z1" "gimple" } } */
diff --git a/gcc/testsuite/gcc.dg/pr35691-4.c b/gcc/testsuite/gcc.dg/pr35691-4.c
new file mode 100644
index 0000000..90cbf6d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr35691-4.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-forwprop-details" } */
+
+int foo(int z0, unsigned z1)
+{
+  int t0 = (z0 != 0);
+  int t1 = (z1 != 0);
+  int t2 = (t0 || t1);
+  return t2;
+}
+
+/* { dg-final { scan-tree-dump "gimple_simplified to _\[0-9\]* = \\(int\\) z1_\[0-9\]*\\(D\\);" "forwprop1" } } */


More information about the Gcc-patches mailing list