Re: Division Optimization in match and simplify

2015-11-04 Thread Marc Glisse

(I didn't read everything)

+/* Convert (A/B)/C to A/(B*C)  */
+(simplify
+ (rdiv (convert? (rdiv @0 @1)) (convert? @2))
+  (if (flag_reciprocal_math
+   && tree_nop_conversion_p (type, TREE_TYPE (@0))
+   && tree_nop_conversion_p (type, TREE_TYPE (@2)))
+   (rdiv (convert @0) (convert (mult @1 @2)

I thought we were mostly using the 'convert?' and tree_nop_conversion_p on 
integers, but I could be wrong. For floats, it seems limited to cases 
where long double has the same size as double? In any case, the 'convert?' 
on @2 seems strange, either useless or not sufficient.


+ (rdiv (REAL_CST@0) (mult (convert? @1) REAL_CST@2))

Here again, the 'convert?' seems useless, (mult @1 REAL_CST@2) would match 
just as well.


+(simplify
+ (trunc_div (bit_and (convert? @0) @1) INTEGER_CST@2)

That would probably also work for exact_div.
Again, I don't see the point of this 'convert?'.

+ (if (!TYPE_UNSIGNED (type) && integer_pow2p (@2)
+  && tree_int_cst_sgn (@2) > 0
+  && tree_nop_conversion_p (type, TREE_TYPE (@0)))
+  (with
+   { tree sum = fold_binary (PLUS_EXPR, TREE_TYPE (@2), @2, @1); }

Don't you want to require that @1 is INTEGER_CST? And then you could use 
const_binop, or even wi::add.


+   (if (sum && integer_zerop (sum))
+(rshift (convert @0) { build_int_cst (integer_type_node,
+ wi::exact_log2 (@2)); })

--
Marc Glisse


Re: Division Optimization in match and simplify

2015-11-04 Thread Hurugalawadi, Naveen
Hi,

Thanks for the review and comments.

>> I thought we were mostly using the 'convert?' 
>> and tree_nop_conversion_p on integers

Done. Cleared all instances of convert which are not required.
However, I am still confused about the use of "convert" in match
and simplify.

>> So all patterns looking at arg[01] are handling nop-conversions on their
>> outermost operands while those looking at op[01] do not.

These patterns are looking at arg[01] rather than op[01] ?
Am really sorry, If I am repeating the same thing over and over.

>> That would probably also work for exact_div.
Done.

>> Don't you want to require that @1 is INTEGER_CST? And then you could use
>> const_binop, or even wi::add.

Done. The fold-const part did not specify it as INTEGER_CST.
Although it was obvious from the PLUS_EXPR.
However, just wanted to retain as per fold-const.

Please find attached the modified patch with all review comments addressed.
Regression tested on X86_64 without any extra failures.

Thanks,
Naveendiff --git a/gcc/fold-const.c b/gcc/fold-const.c
index ee9b349..88dbbdd 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -10163,54 +10163,9 @@ fold_binary_loc (location_t loc,
 	return fold_build2_loc (loc, RDIV_EXPR, type,
 			negate_expr (arg0),
 			TREE_OPERAND (arg1, 0));
-
-  /* Convert A/B/C to A/(B*C).  */
-  if (flag_reciprocal_math
-	  && TREE_CODE (arg0) == RDIV_EXPR)
-	return fold_build2_loc (loc, RDIV_EXPR, type, TREE_OPERAND (arg0, 0),
-			fold_build2_loc (loc, MULT_EXPR, type,
-	 TREE_OPERAND (arg0, 1), arg1));
-
-  /* Convert A/(B/C) to (A/B)*C.  */
-  if (flag_reciprocal_math
-	  && TREE_CODE (arg1) == RDIV_EXPR)
-	return fold_build2_loc (loc, MULT_EXPR, type,
-			fold_build2_loc (loc, RDIV_EXPR, type, arg0,
-	 TREE_OPERAND (arg1, 0)),
-			TREE_OPERAND (arg1, 1));
-
-  /* Convert C1/(X*C2) into (C1/C2)/X.  */
-  if (flag_reciprocal_math
-	  && TREE_CODE (arg1) == MULT_EXPR
-	  && TREE_CODE (arg0) == REAL_CST
-	  && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST)
-	{
-	  tree tem = const_binop (RDIV_EXPR, arg0,
-  TREE_OPERAND (arg1, 1));
-	  if (tem)
-	return fold_build2_loc (loc, RDIV_EXPR, type, tem,
-TREE_OPERAND (arg1, 0));
-	}
-
   return NULL_TREE;
 
 case TRUNC_DIV_EXPR:
-  /* Optimize (X & (-A)) / A where A is a power of 2,
-	 to X >> log2(A) */
-  if (TREE_CODE (arg0) == BIT_AND_EXPR
-	  && !TYPE_UNSIGNED (type) && TREE_CODE (arg1) == INTEGER_CST
-	  && integer_pow2p (arg1) && tree_int_cst_sgn (arg1) > 0)
-	{
-	  tree sum = fold_binary_loc (loc, PLUS_EXPR, TREE_TYPE (arg1),
-  arg1, TREE_OPERAND (arg0, 1));
-	  if (sum && integer_zerop (sum)) {
-	tree pow2 = build_int_cst (integer_type_node,
-   wi::exact_log2 (arg1));
-	return fold_build2_loc (loc, RSHIFT_EXPR, type,
-TREE_OPERAND (arg0, 0), pow2);
-	  }
-	}
-
   /* Fall through */
   
 case FLOOR_DIV_EXPR:
diff --git a/gcc/match.pd b/gcc/match.pd
index f6c5c07..020f575 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -247,6 +247,27 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (if (!HONOR_SNANS (type))
   (negate @0)))
 
+/* Convert (A/B)/C to A/(B*C)  */
+(simplify
+ (rdiv (rdiv @0 @1) @2)
+  (if (flag_reciprocal_math)
+   (rdiv @0 (mult @1 @2
+
+/* Convert A/(B/C) to (A/B)*C  */
+(simplify
+ (rdiv @0 (rdiv @1 @2))
+  (if (flag_reciprocal_math)
+   (mult (rdiv @0 @1) @2)))
+
+/* Optimize (X & (-A)) / A where A is a power of 2, to X >> log2(A) */
+(for div (exact_div trunc_div) 
+ (simplify
+  (div (bit_and @0 INTEGER_CST@1) INTEGER_CST@2)
+  (if (!TYPE_UNSIGNED (type) && integer_pow2p (@2)
+   && tree_int_cst_sgn (@2) > 0
+   && wi::add (@2, @1) == 0)
+   (rshift @0 { build_int_cst (integer_type_node, wi::exact_log2 (@2)); }
+
 /* If ARG1 is a constant, we can convert this to a multiply by the
reciprocal.  This does not have the same rounding properties,
so only do this if -freciprocal-math.  We can actually
@@ -464,6 +485,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 (if (tem)
  (rdiv { tem; } @1)
 
+/* Convert C1/(X*C2) into (C1/C2)/X  */
+(simplify
+ (rdiv (REAL_CST@0) (mult @1 REAL_CST@2))
+  (if (flag_reciprocal_math)
+   (with
+{ tree tem = const_binop (RDIV_EXPR, type, @0, @2); }
+(if (tem)
+ (rdiv { tem; } @1)
+
 /* Simplify ~X & X as zero.  */
 (simplify
  (bit_and:c (convert? @0) (convert? (bit_not @0)))


Re: Division Optimization in match and simplify

2015-11-04 Thread Marc Glisse

On Wed, 4 Nov 2015, Hurugalawadi, Naveen wrote:


I thought we were mostly using the 'convert?'
and tree_nop_conversion_p on integers


Done. Cleared all instances of convert which are not required.
However, I am still confused about the use of "convert" in match
and simplify.


It could be that I am wrong, you'll have to wait for Richard's comments 
anyway. The one place where a convert could be useful is:

(div (convert? (bit_and @0 INTEGER_CST@1)) INTEGER_CST@2)
but I didn't check if we want it (it would probably at least require 
(convert @0) instead of plain @0 in the result so the division and the 
shift are done with the same signedness).



So all patterns looking at arg[01] are handling nop-conversions on their
outermost operands while those looking at op[01] do not.


These patterns are looking at arg[01] rather than op[01] ?


Might be a case where it doesn't really matter which one you look at, and 
the easiest one in fold-const may not be the same as in match.pd.


+/* Convert (A/B)/C to A/(B*C)  */
+(simplify
+ (rdiv (rdiv @0 @1) @2)
+  (if (flag_reciprocal_math)

I would indent this line the same as the one above.

+   (rdiv @0 (mult @1 @2
+
+/* Convert A/(B/C) to (A/B)*C  */
+(simplify
+ (rdiv @0 (rdiv @1 @2))
+  (if (flag_reciprocal_math)
+   (mult (rdiv @0 @1) @2)))

I believe you might want a :s on the inner rdiv (?).
Note that you can factor out the test on flag_reciprocal_math so you write 
it only once for 2 patterns.


I don't really remember what the tests !TYPE_UNSIGNED (type) and 
tree_int_cst_sgn are for in the other pattern, but since you are only 
moving the transformation...


--
Marc Glisse


Re: Division Optimization in match and simplify

2015-11-04 Thread Richard Biener
On Wed, Nov 4, 2015 at 12:18 PM, Marc Glisse  wrote:
> On Wed, 4 Nov 2015, Hurugalawadi, Naveen wrote:
>
 I thought we were mostly using the 'convert?'
 and tree_nop_conversion_p on integers

Yes, on floats they shouldn't be used.

>>
>> Done. Cleared all instances of convert which are not required.
>> However, I am still confused about the use of "convert" in match
>> and simplify.
>
>
> It could be that I am wrong, you'll have to wait for Richard's comments
> anyway. The one place where a convert could be useful is:
> (div (convert? (bit_and @0 INTEGER_CST@1)) INTEGER_CST@2)
> but I didn't check if we want it (it would probably at least require
> (convert @0) instead of plain @0 in the result so the division and the shift
> are done with the same signedness).
>
 So all patterns looking at arg[01] are handling nop-conversions on their
 outermost operands while those looking at op[01] do not.
>>
>>
>> These patterns are looking at arg[01] rather than op[01] ?
>
>
> Might be a case where it doesn't really matter which one you look at, and
> the easiest one in fold-const may not be the same as in match.pd.
>
> +/* Convert (A/B)/C to A/(B*C)  */
> +(simplify
> + (rdiv (rdiv @0 @1) @2)
> +  (if (flag_reciprocal_math)
>
> I would indent this line the same as the one above.

Yep.

> +   (rdiv @0 (mult @1 @2
> +
> +/* Convert A/(B/C) to (A/B)*C  */
> +(simplify
> + (rdiv @0 (rdiv @1 @2))
> +  (if (flag_reciprocal_math)
> +   (mult (rdiv @0 @1) @2)))
>
> I believe you might want a :s on the inner rdiv (?).
> Note that you can factor out the test on flag_reciprocal_math so you write
> it only once for 2 patterns.

Please use :s on both inner rdiv in both patterns.  With that the two patterns
are ok.

+/* Convert C1/(X*C2) into (C1/C2)/X  */
+(simplify
+ (rdiv (REAL_CST@0) (mult @1 REAL_CST@2))

Omit the parens around REAL_CST@0

+  (if (flag_reciprocal_math)
+   (with
+{ tree tem = const_binop (RDIV_EXPR, type, @0, @2); }
+(if (tem)
+ (rdiv { tem; } @1)

with that the pattern is ok.

>
> I don't really remember what the tests !TYPE_UNSIGNED (type) and
> tree_int_cst_sgn are for in the other pattern, but since you are only moving
> the transformation...

+/* Optimize (X & (-A)) / A where A is a power of 2, to X >> log2(A) */
+(for div (exact_div trunc_div)
+ (simplify
+  (div (bit_and @0 INTEGER_CST@1) INTEGER_CST@2)
+  (if (!TYPE_UNSIGNED (type) && integer_pow2p (@2)
+   && tree_int_cst_sgn (@2) > 0
+   && wi::add (@2, @1) == 0)
+   (rshift @0 { build_int_cst (integer_type_node, wi::exact_log2 (@2)); }

the TYPE_UNSIGNED test is because right shift of negative values is undefined,
so is a shift with a negative value.  I believe we can safely handle
conversions here
just like fold-const.c does with

 (div (convert? (bit_and @0 INTEGER_CST@1) INTEGER_CST@2)
 (if (tree_nop_conversion_p (type, TREE_TYPE (@0)))
  ...

With that the pattern looks ok to me.

Richard.


>
> --
> Marc Glisse


Re: Division Optimization in match and simplify

2015-11-04 Thread Marc Glisse

On Wed, 4 Nov 2015, Richard Biener wrote:


I don't really remember what the tests !TYPE_UNSIGNED (type) and
tree_int_cst_sgn are for in the other pattern, but since you are only moving
the transformation...


+/* Optimize (X & (-A)) / A where A is a power of 2, to X >> log2(A) */
+(for div (exact_div trunc_div)
+ (simplify
+  (div (bit_and @0 INTEGER_CST@1) INTEGER_CST@2)
+  (if (!TYPE_UNSIGNED (type) && integer_pow2p (@2)
+   && tree_int_cst_sgn (@2) > 0
+   && wi::add (@2, @1) == 0)
+   (rshift @0 { build_int_cst (integer_type_node, wi::exact_log2 (@2)); }

the TYPE_UNSIGNED test is because right shift of negative values is undefined,


tree.def: "Shift means logical shift if done on an unsigned type, arithmetic shift 
if done on a signed type."
To me, this implies that right shift of negative values is well-defined
inside gcc.
Also, the test allows *only signed types*, not unsigned.


so is a shift with a negative value.  I believe we can safely handle
conversions here
just like fold-const.c does with

(div (convert? (bit_and @0 INTEGER_CST@1) INTEGER_CST@2)
(if (tree_nop_conversion_p (type, TREE_TYPE (@0)))
 ...

With that the pattern looks ok to me.


As long as it comes with (convert @0) in the result... I think the
fold-const.c pattern is lucky that (int)(x&-4u) gets folded to
(int)x&-4, or it might ICE for ((int)(x&-4u))/4.

--
Marc Glisse


Re: Division Optimization in match and simplify

2015-11-04 Thread Richard Biener
On Wed, Nov 4, 2015 at 1:45 PM, Marc Glisse  wrote:
> On Wed, 4 Nov 2015, Richard Biener wrote:
>
>>> I don't really remember what the tests !TYPE_UNSIGNED (type) and
>>> tree_int_cst_sgn are for in the other pattern, but since you are only
>>> moving
>>> the transformation...
>>
>>
>> +/* Optimize (X & (-A)) / A where A is a power of 2, to X >> log2(A) */
>> +(for div (exact_div trunc_div)
>> + (simplify
>> +  (div (bit_and @0 INTEGER_CST@1) INTEGER_CST@2)
>> +  (if (!TYPE_UNSIGNED (type) && integer_pow2p (@2)
>> +   && tree_int_cst_sgn (@2) > 0
>> +   && wi::add (@2, @1) == 0)
>> +   (rshift @0 { build_int_cst (integer_type_node, wi::exact_log2 (@2));
>> }
>>
>> the TYPE_UNSIGNED test is because right shift of negative values is
>> undefined,
>
>
> tree.def: "Shift means logical shift if done on an unsigned type, arithmetic
> shift if done on a signed type."
> To me, this implies that right shift of negative values is well-defined
> inside gcc.

Ah, it was _left_ shift of negative values that ubsan complains about.

> Also, the test allows *only signed types*, not unsigned.

Doh.  Ok, so maybe that's because the tree_int_cst_sgn test would
"not work" otherwise (just use tree_int_cst_sign_bit (@2) == 0).

>
>> so is a shift with a negative value.  I believe we can safely handle
>> conversions here
>> just like fold-const.c does with
>>
>> (div (convert? (bit_and @0 INTEGER_CST@1) INTEGER_CST@2)
>> (if (tree_nop_conversion_p (type, TREE_TYPE (@0)))
>>  ...
>>
>> With that the pattern looks ok to me.
>
>
> As long as it comes with (convert @0) in the result... I think the
> fold-const.c pattern is lucky that (int)(x&-4u) gets folded to
> (int)x&-4, or it might ICE for ((int)(x&-4u))/4.

I think the types match ok but I might have looked too quickly (again).

Richard.

> --
> Marc Glisse


Re: Division Optimization in match and simplify

2015-11-04 Thread Hurugalawadi, Naveen
Hi,

Please find attached the modified patch as per review comments.

>> use :s on both inner rdiv in both patterns.  With that the two patterns are 
>> ok.
Done.

>> Omit the parens around REAL_CST@0
Done.

Regression tested on X86_64.

Thanks,
Naveendiff --git a/gcc/fold-const.c b/gcc/fold-const.c
index ee9b349..88dbbdd 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -10163,54 +10163,9 @@ fold_binary_loc (location_t loc,
 	return fold_build2_loc (loc, RDIV_EXPR, type,
 			negate_expr (arg0),
 			TREE_OPERAND (arg1, 0));
-
-  /* Convert A/B/C to A/(B*C).  */
-  if (flag_reciprocal_math
-	  && TREE_CODE (arg0) == RDIV_EXPR)
-	return fold_build2_loc (loc, RDIV_EXPR, type, TREE_OPERAND (arg0, 0),
-			fold_build2_loc (loc, MULT_EXPR, type,
-	 TREE_OPERAND (arg0, 1), arg1));
-
-  /* Convert A/(B/C) to (A/B)*C.  */
-  if (flag_reciprocal_math
-	  && TREE_CODE (arg1) == RDIV_EXPR)
-	return fold_build2_loc (loc, MULT_EXPR, type,
-			fold_build2_loc (loc, RDIV_EXPR, type, arg0,
-	 TREE_OPERAND (arg1, 0)),
-			TREE_OPERAND (arg1, 1));
-
-  /* Convert C1/(X*C2) into (C1/C2)/X.  */
-  if (flag_reciprocal_math
-	  && TREE_CODE (arg1) == MULT_EXPR
-	  && TREE_CODE (arg0) == REAL_CST
-	  && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST)
-	{
-	  tree tem = const_binop (RDIV_EXPR, arg0,
-  TREE_OPERAND (arg1, 1));
-	  if (tem)
-	return fold_build2_loc (loc, RDIV_EXPR, type, tem,
-TREE_OPERAND (arg1, 0));
-	}
-
   return NULL_TREE;
 
 case TRUNC_DIV_EXPR:
-  /* Optimize (X & (-A)) / A where A is a power of 2,
-	 to X >> log2(A) */
-  if (TREE_CODE (arg0) == BIT_AND_EXPR
-	  && !TYPE_UNSIGNED (type) && TREE_CODE (arg1) == INTEGER_CST
-	  && integer_pow2p (arg1) && tree_int_cst_sgn (arg1) > 0)
-	{
-	  tree sum = fold_binary_loc (loc, PLUS_EXPR, TREE_TYPE (arg1),
-  arg1, TREE_OPERAND (arg0, 1));
-	  if (sum && integer_zerop (sum)) {
-	tree pow2 = build_int_cst (integer_type_node,
-   wi::exact_log2 (arg1));
-	return fold_build2_loc (loc, RSHIFT_EXPR, type,
-TREE_OPERAND (arg0, 0), pow2);
-	  }
-	}
-
   /* Fall through */
   
 case FLOOR_DIV_EXPR:
diff --git a/gcc/match.pd b/gcc/match.pd
index f6c5c07..d11ad79 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -247,6 +247,27 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (if (!HONOR_SNANS (type))
   (negate @0)))
 
+(if (flag_reciprocal_math)
+ /* Convert (A/B)/C to A/(B*C)  */
+ (simplify
+  (rdiv (rdiv:s @0 @1) @2)
+   (rdiv @0 (mult @1 @2)))
+
+ /* Convert A/(B/C) to (A/B)*C  */
+ (simplify
+  (rdiv @0 (rdiv:s @1 @2))
+   (mult (rdiv @0 @1) @2)))
+
+/* Optimize (X & (-A)) / A where A is a power of 2, to X >> log2(A) */
+(for div (exact_div trunc_div)
+ (simplify
+  (div (convert? (bit_and @0 INTEGER_CST@1)) INTEGER_CST@2)
+  (if (integer_pow2p (@2)
+   && tree_int_cst_sign_bit (@2) == 0
+   && wi::add (@2, @1) == 0
+   && tree_nop_conversion_p (type, TREE_TYPE (@0)))
+   (rshift (convert @0) { build_int_cst (integer_type_node, wi::exact_log2 (@2)); }
+
 /* If ARG1 is a constant, we can convert this to a multiply by the
reciprocal.  This does not have the same rounding properties,
so only do this if -freciprocal-math.  We can actually
@@ -464,6 +485,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 (if (tem)
  (rdiv { tem; } @1)
 
+/* Convert C1/(X*C2) into (C1/C2)/X  */
+(simplify
+ (rdiv REAL_CST@0 (mult @1 REAL_CST@2))
+  (if (flag_reciprocal_math)
+   (with
+{ tree tem = const_binop (RDIV_EXPR, type, @0, @2); }
+(if (tem)
+ (rdiv { tem; } @1)
+
 /* Simplify ~X & X as zero.  */
 (simplify
  (bit_and:c (convert? @0) (convert? (bit_not @0)))


Re: Division Optimization in match and simplify

2015-11-04 Thread Marc Glisse

+/* Optimize (X & (-A)) / A where A is a power of 2, to X >> log2(A) */
+(for div (exact_div trunc_div)

Actually, it probably works for all integer divisions (floor_div, etc) 
since it is exact and thus does not depend on the rounding.


(sorry for giving the comments small piece by small piece, I write them as 
I think of them...)


+ (simplify
+  (div (convert? (bit_and @0 INTEGER_CST@1)) INTEGER_CST@2)
+  (if (integer_pow2p (@2)
+   && tree_int_cst_sign_bit (@2) == 0

I think the previous test tree_int_cst_sgn > 0 was better: for unsigned, 
it is ok if that bit is set, it is only for signed that we want to avoid 
-1/-1 which gives 1 (while a shift by 31 would give -1, except that 
wi::exact_log2 might return -1 so we would end up with a negative shift).


(actually, we could generate (unsigned)x>>31 in that case, but let's 
forget it for now)


+   && wi::add (@2, @1) == 0
+   && tree_nop_conversion_p (type, TREE_TYPE (@0)))
+   (rshift (convert @0) { build_int_cst (integer_type_node, wi::exact_log2 
(@2)); }

(does this fit in 80 cols?)

Note that if we port the following to match.pd from wherever it currently 
is, the 'convert?' becomes much less useful on this transformation


(simplify
 (convert (bit_and:s @0 INTEGER_CST@1))
 (if (tree_nop_conversion_p (type, TREE_TYPE (@0)))
  (bit_and (convert @0) (convert @1

--
Marc Glisse


Re: Division Optimization in match and simplify

2015-11-05 Thread Michael Matz
Hi,

On Wed, 4 Nov 2015, Richard Biener wrote:

> Ah, it was _left_ shift of negative values that ubsan complains about.

Note that this is only for the frontend definition of shifts.  I don't see 
why gimple shouldn't define it to the only sensible definition there is, 
which also happens to be the one that all CPUs in the world implement 
(well, those using two-complement representation at least).


Ciao,
Michael.


Re: Division Optimization in match and simplify

2015-11-05 Thread Richard Biener
On November 5, 2015 2:40:30 PM GMT+01:00, Michael Matz  wrote:
>Hi,
>
>On Wed, 4 Nov 2015, Richard Biener wrote:
>
>> Ah, it was _left_ shift of negative values that ubsan complains
>about.
>
>Note that this is only for the frontend definition of shifts.  I don't
>see 
>why gimple shouldn't define it to the only sensible definition there
>is, 
>which also happens to be the one that all CPUs in the world implement 
>(well, those using two-complement representation at least).

Yeah, but front ends and back end are not separated enough to have both.

Richard.

>
>Ciao,
>Michael.




Re: Division Optimization in match and simplify

2015-11-05 Thread Hurugalawadi, Naveen
Hi,

>> it probably works for all integer divisions (floor_div, etc)
>> since it is exact and thus does not depend on the rounding.

Please find attached the modified patch as per comments.

Thanks,
Naveendiff --git a/gcc/fold-const.c b/gcc/fold-const.c
index ee9b349..88dbbdd 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -10163,54 +10163,9 @@ fold_binary_loc (location_t loc,
 	return fold_build2_loc (loc, RDIV_EXPR, type,
 			negate_expr (arg0),
 			TREE_OPERAND (arg1, 0));
-
-  /* Convert A/B/C to A/(B*C).  */
-  if (flag_reciprocal_math
-	  && TREE_CODE (arg0) == RDIV_EXPR)
-	return fold_build2_loc (loc, RDIV_EXPR, type, TREE_OPERAND (arg0, 0),
-			fold_build2_loc (loc, MULT_EXPR, type,
-	 TREE_OPERAND (arg0, 1), arg1));
-
-  /* Convert A/(B/C) to (A/B)*C.  */
-  if (flag_reciprocal_math
-	  && TREE_CODE (arg1) == RDIV_EXPR)
-	return fold_build2_loc (loc, MULT_EXPR, type,
-			fold_build2_loc (loc, RDIV_EXPR, type, arg0,
-	 TREE_OPERAND (arg1, 0)),
-			TREE_OPERAND (arg1, 1));
-
-  /* Convert C1/(X*C2) into (C1/C2)/X.  */
-  if (flag_reciprocal_math
-	  && TREE_CODE (arg1) == MULT_EXPR
-	  && TREE_CODE (arg0) == REAL_CST
-	  && TREE_CODE (TREE_OPERAND (arg1, 1)) == REAL_CST)
-	{
-	  tree tem = const_binop (RDIV_EXPR, arg0,
-  TREE_OPERAND (arg1, 1));
-	  if (tem)
-	return fold_build2_loc (loc, RDIV_EXPR, type, tem,
-TREE_OPERAND (arg1, 0));
-	}
-
   return NULL_TREE;
 
 case TRUNC_DIV_EXPR:
-  /* Optimize (X & (-A)) / A where A is a power of 2,
-	 to X >> log2(A) */
-  if (TREE_CODE (arg0) == BIT_AND_EXPR
-	  && !TYPE_UNSIGNED (type) && TREE_CODE (arg1) == INTEGER_CST
-	  && integer_pow2p (arg1) && tree_int_cst_sgn (arg1) > 0)
-	{
-	  tree sum = fold_binary_loc (loc, PLUS_EXPR, TREE_TYPE (arg1),
-  arg1, TREE_OPERAND (arg0, 1));
-	  if (sum && integer_zerop (sum)) {
-	tree pow2 = build_int_cst (integer_type_node,
-   wi::exact_log2 (arg1));
-	return fold_build2_loc (loc, RSHIFT_EXPR, type,
-TREE_OPERAND (arg0, 0), pow2);
-	  }
-	}
-
   /* Fall through */
   
 case FLOOR_DIV_EXPR:
diff --git a/gcc/match.pd b/gcc/match.pd
index f6c5c07..0e658f7 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -247,6 +247,28 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (if (!HONOR_SNANS (type))
   (negate @0)))
 
+(if (flag_reciprocal_math)
+ /* Convert (A/B)/C to A/(B*C)  */
+ (simplify
+  (rdiv (rdiv:s @0 @1) @2)
+   (rdiv @0 (mult @1 @2)))
+
+ /* Convert A/(B/C) to (A/B)*C  */
+ (simplify
+  (rdiv @0 (rdiv:s @1 @2))
+   (mult (rdiv @0 @1) @2)))
+
+/* Optimize (X & (-A)) / A where A is a power of 2, to X >> log2(A) */
+(for div (trunc_div ceil_div floor_div round_div exact_div)
+ (simplify
+  (div (convert? (bit_and @0 INTEGER_CST@1)) INTEGER_CST@2)
+  (if (!TYPE_UNSIGNED (type) && integer_pow2p (@2)
+   && tree_int_cst_sgn (@2) > 0
+   && wi::add (@2, @1) == 0
+   && tree_nop_conversion_p (type, TREE_TYPE (@0)))
+   (rshift (convert @0) { build_int_cst (integer_type_node,
+	 wi::exact_log2 (@2)); }
+
 /* If ARG1 is a constant, we can convert this to a multiply by the
reciprocal.  This does not have the same rounding properties,
so only do this if -freciprocal-math.  We can actually
@@ -464,6 +486,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 (if (tem)
  (rdiv { tem; } @1)
 
+/* Convert C1/(X*C2) into (C1/C2)/X  */
+(simplify
+ (rdiv REAL_CST@0 (mult @1 REAL_CST@2))
+  (if (flag_reciprocal_math)
+   (with
+{ tree tem = const_binop (RDIV_EXPR, type, @0, @2); }
+(if (tem)
+ (rdiv { tem; } @1)
+
 /* Simplify ~X & X as zero.  */
 (simplify
  (bit_and:c (convert? @0) (convert? (bit_not @0)))


Re: Division Optimization in match and simplify

2015-11-05 Thread Marc Glisse

+/* Optimize (X & (-A)) / A where A is a power of 2, to X >> log2(A) */
+(for div (trunc_div ceil_div floor_div round_div exact_div)
+ (simplify
+  (div (convert? (bit_and @0 INTEGER_CST@1)) INTEGER_CST@2)
+  (if (!TYPE_UNSIGNED (type) && integer_pow2p (@2)
+   && tree_int_cst_sgn (@2) > 0
+   && wi::add (@2, @1) == 0
+   && tree_nop_conversion_p (type, TREE_TYPE (@0)))
+   (rshift (convert @0) { build_int_cst (integer_type_node,
+wi::exact_log2 (@2)); }

Sorry, I must be very unclear when I write :-(
I indeed like tree_int_cst_sgn (@2) > 0 better than looking at the sign 
bit, but I don't know why you re-introduced !TYPE_UNSIGNED (type) at the 
same time. The whole reason I prefer tree_int_cst_sgn is that it also 
applies when type is unsigned and @2 is 2^31.


--
Marc Glisse