public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Multiply Optimization in match and Simplify
@ 2015-10-29  8:21 Hurugalawadi, Naveen
  2015-10-30 10:08 ` Richard Biener
  0 siblings, 1 reply; 6+ messages in thread
From: Hurugalawadi, Naveen @ 2015-10-29  8:21 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1604 bytes --]

Hi,

Please find attached the patch that moves some multiply optimizations
from fold-const using simplify and match.

Please review the patch and let me know if any modifications are required.

Tested the patch on X86.

Observing following failures:-

>> FAIL: gcc.dg/fold-plusmult.c scan-tree-dump-times original "<a> \\* 4" 2

Should the testcase be changed to suit current pattern?

>> FAIL: gcc.dg/tree-ssa/vrp47.c scan-tree-dump-times vrp2 " & 1;" 0
>> FAIL: gcc.dg/tree-ssa/vrp59.c scan-tree-dump-not vrp1 " & 3;"

Its due to the following pattern. Pattern seems to be right.
Fold X & (X ^ Y) as X & ~Y
The test PASSes when we have the result as ~X & Y in some
of the following combinations which is wrong.
(bit_and (convert? (bit_xor:c @0 @1) (convert? @0) ))

Thanks,
Naveen

ChangeLog

2015-10-29  Naveen H.S  <Naveen.Hurugalawadi@caviumnetworks.com>

        * fold-const.c (fold_binary_loc) : Remove A - B -> A + (-B) if B
	is easily negatable as its already present.
	Move x * -C into -x * C if x is easily negatable to match.pd.
	Move (A + A) * C -> A * 2 * C to match.pd.
	Move Fold (X ^ Y) & Y as ~X & Y to match.pd.
	Move Fold (X ^ Y) & X as ~Y & X to match.pd.
	Move Fold X & (X ^ Y) as X & ~Y to match.pd.
	Move Fold X & (Y ^ X) as ~Y & X to match.pd.

        * match.pd (bit_and:c (convert? @0) (convert? (bit_xor:c @0 @1))):
	New simplifier.
	(mult:c (convert? negate_expr_p@0) INTEGER_CST@1): New simplifier.
	(mult:c (convert? (plus @0 @0)) (convert? @1)): New simplifier.
	(mult:c (convert? (plus @0 @0)) INTEGER_CST@1): New simplifier.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: mult-opt.patch --]
[-- Type: text/x-patch; name="mult-opt.patch", Size: 5421 bytes --]

diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index e8ff1de..0334b53 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -9695,19 +9695,6 @@ fold_binary_loc (location_t loc,
 	    }
 	}
 
-      /* A - B -> A + (-B) if B is easily negatable.  */
-      if (negate_expr_p (arg1)
-	  && !TYPE_OVERFLOW_SANITIZED (type)
-	  && ((FLOAT_TYPE_P (type)
-               /* Avoid this transformation if B is a positive REAL_CST.  */
-	       && (TREE_CODE (arg1) != REAL_CST
-		   ||  REAL_VALUE_NEGATIVE (TREE_REAL_CST (arg1))))
-	      || INTEGRAL_TYPE_P (type)))
-	return fold_build2_loc (loc, PLUS_EXPR, type,
-			    fold_convert_loc (loc, type, arg0),
-			    fold_convert_loc (loc, type,
-					      negate_expr (arg1)));
-
       /* Fold &a[i] - &a[j] to i-j.  */
       if (TREE_CODE (arg0) == ADDR_EXPR
 	  && TREE_CODE (TREE_OPERAND (arg0, 0)) == ARRAY_REF
@@ -9749,29 +9736,6 @@ fold_binary_loc (location_t loc,
     case MULT_EXPR:
       if (! FLOAT_TYPE_P (type))
 	{
-	  /* Transform x * -C into -x * C if x is easily negatable.  */
-	  if (TREE_CODE (arg1) == INTEGER_CST
-	      && tree_int_cst_sgn (arg1) == -1
-	      && negate_expr_p (arg0)
-	      && (tem = negate_expr (arg1)) != arg1
-	      && !TREE_OVERFLOW (tem))
-	    return fold_build2_loc (loc, MULT_EXPR, type,
-	    			fold_convert_loc (loc, type,
-						  negate_expr (arg0)),
-				tem);
-
-	  /* (A + A) * C -> A * 2 * C  */
-	  if (TREE_CODE (arg0) == PLUS_EXPR
-	      && TREE_CODE (arg1) == INTEGER_CST
-	      && operand_equal_p (TREE_OPERAND (arg0, 0),
-			          TREE_OPERAND (arg0, 1), 0))
-	    return fold_build2_loc (loc, MULT_EXPR, type,
-				omit_one_operand_loc (loc, type,
-						  TREE_OPERAND (arg0, 0),
-						  TREE_OPERAND (arg0, 1)),
-				fold_build2_loc (loc, MULT_EXPR, type,
-					     build_int_cst (type, 2) , arg1));
-
 	  /* ((T) (X /[ex] C)) * C cancels out if the conversion is
 	     sign-changing only.  */
 	  if (TREE_CODE (arg1) == INTEGER_CST
@@ -9961,45 +9925,6 @@ fold_binary_loc (location_t loc,
 				  build_zero_cst (TREE_TYPE (tem)));
 	}
 
-      /* Fold (X ^ Y) & Y as ~X & Y.  */
-      if (TREE_CODE (arg0) == BIT_XOR_EXPR
-	  && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
-	{
-	  tem = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));
-	  return fold_build2_loc (loc, BIT_AND_EXPR, type,
-			      fold_build1_loc (loc, BIT_NOT_EXPR, type, tem),
-			      fold_convert_loc (loc, type, arg1));
-	}
-      /* Fold (X ^ Y) & X as ~Y & X.  */
-      if (TREE_CODE (arg0) == BIT_XOR_EXPR
-	  && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
-	  && reorder_operands_p (TREE_OPERAND (arg0, 1), arg1))
-	{
-	  tem = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 1));
-	  return fold_build2_loc (loc, BIT_AND_EXPR, type,
-			      fold_build1_loc (loc, BIT_NOT_EXPR, type, tem),
-			      fold_convert_loc (loc, type, arg1));
-	}
-      /* Fold X & (X ^ Y) as X & ~Y.  */
-      if (TREE_CODE (arg1) == BIT_XOR_EXPR
-	  && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
-	{
-	  tem = fold_convert_loc (loc, type, TREE_OPERAND (arg1, 1));
-	  return fold_build2_loc (loc, BIT_AND_EXPR, type,
-			      fold_convert_loc (loc, type, arg0),
-			      fold_build1_loc (loc, BIT_NOT_EXPR, type, tem));
-	}
-      /* Fold X & (Y ^ X) as ~Y & X.  */
-      if (TREE_CODE (arg1) == BIT_XOR_EXPR
-	  && operand_equal_p (arg0, TREE_OPERAND (arg1, 1), 0)
-	  && reorder_operands_p (arg0, TREE_OPERAND (arg1, 0)))
-	{
-	  tem = fold_convert_loc (loc, type, TREE_OPERAND (arg1, 0));
-	  return fold_build2_loc (loc, BIT_AND_EXPR, type,
-			      fold_build1_loc (loc, BIT_NOT_EXPR, type, tem),
-			      fold_convert_loc (loc, type, arg0));
-	}
-
       /* Fold (X * Y) & -(1 << CST) to X * Y if Y is a constant
          multiple of 1 << CST.  */
       if (TREE_CODE (arg1) == INTEGER_CST)
diff --git a/gcc/match.pd b/gcc/match.pd
index 1d6dde1..6793f59 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -490,6 +490,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (if (wi::bit_not (@2) == @1)
   (bit_xor @0 @1)))
 
+/* Fold X & (X ^ Y) as X & ~Y.  */
+(simplify
+ (bit_and:c (convert? @0) (convert? (bit_xor:c @0 @1)))
+  (if (tree_nop_conversion_p (type, TREE_TYPE (@0)))
+   (convert (bit_and @0 (bit_not @1)))))
+
 /* X % Y is smaller than Y.  */
 (for cmp (lt ge)
  (simplify
@@ -1600,12 +1606,31 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
    (if (!TREE_OVERFLOW (tem) || !flag_trapping_math)
     (minus @0 { tem; })))))
 
+/* Convert X * -C into -X * C.  */
+(simplify
+ (mult:c (convert? negate_expr_p@0) INTEGER_CST@1)
+  (if (tree_int_cst_sgn (@1) == -1)
+   (with { tree tem = const_unop (NEGATE_EXPR, type, @1); }
+    (if (!TREE_OVERFLOW (tem) && wi::ne_p (tem, @1)
+	  && tree_nop_conversion_p (type, TREE_TYPE (@0)))
+     (mult (convert (negate @0)) @1)))))
+
 /* Convert x+x into x*2.0.  */
 (simplify
  (plus @0 @0)
  (if (SCALAR_FLOAT_TYPE_P (type))
   (mult @0 { build_real (type, dconst2); })))
 
+/* Convert (A + A) * C -> A * 2 * C.  */
+(simplify
+ (mult:c (convert? (plus @0 @0)) (convert? @1))
+  (if (tree_nop_conversion_p (TREE_TYPE (@0), type))
+   (convert (mult @0 (mult { build_int_cst (TREE_TYPE (@1), 2); } @1)))))
+(simplify
+ (mult:c (convert? (plus @0 @0)) INTEGER_CST@1)
+  (if (tree_nop_conversion_p (TREE_TYPE (@0), type))
+   (convert (mult @0 (mult { build_int_cst (TREE_TYPE (@1), 2); } @1)))))
+
 (simplify
  (minus integer_zerop @1)
  (negate @1))

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2015-11-03 15:42 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-10-29  8:21 Multiply Optimization in match and Simplify Hurugalawadi, Naveen
2015-10-30 10:08 ` Richard Biener
2015-10-30 10:44   ` Marc Glisse
2015-10-30 11:06     ` Richard Biener
2015-11-03  5:13   ` Hurugalawadi, Naveen
2015-11-03 15:42     ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).