[2/2] middle-end: replace constant_multiple_of with aff_combination_constant_multiple_p [PR114932]

Message ID ZoMOCAD/B0RXeudB@arm.com
State New
Headers
Series [1/2] middle-end: fix wide_int_constant_multiple_p when VAL and DIV are 0. [PR114932] |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gcc_check--master-arm success Test passed
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 success Test passed

Commit Message

Tamar Christina July 1, 2024, 8:14 p.m. UTC
  Hi All,

The current implementation of constant_multiple_of is doing a more limited
version of aff_combination_constant_multiple_p.

The only non-debug usage of constant_multiple_of will proceed with the values
as affine trees.  There is scope for further optimization here, namely I believe
that if constant_multiple_of returns the aff_tree after the conversion then
get_computation_aff_1 can use it instead of manually creating the aff_tree.

However I think it makes sense to first commit this smaller change and then
incrementally change things.

Bootstrapped Regtested on aarch64-none-linux-gnu,
x86_64-pc-linux-gnu -m32, -m64 and no issues.

Ok for master?

Thanks,
Tamar

gcc/ChangeLog:

	PR tree-optimization/114932
	* tree-ssa-loop-ivopts.cc (constant_multiple_of): Use
	aff_combination_constant_multiple_p instead.

---




--
  

Comments

Richard Biener July 2, 2024, 7:58 a.m. UTC | #1
On Mon, 1 Jul 2024, Tamar Christina wrote:

> Hi All,
> 
> The current implementation of constant_multiple_of is doing a more limited
> version of aff_combination_constant_multiple_p.
> 
> The only non-debug usage of constant_multiple_of will proceed with the values
> as affine trees.  There is scope for further optimization here, namely I believe
> that if constant_multiple_of returns the aff_tree after the conversion then
> get_computation_aff_1 can use it instead of manually creating the aff_tree.
> 
> However I think it makes sense to first commit this smaller change and then
> incrementally change things.
> 
> Bootstrapped Regtested on aarch64-none-linux-gnu,
> x86_64-pc-linux-gnu -m32, -m64 and no issues.
> 
> Ok for master?

OK.

Thanks,
Richard.

> Thanks,
> Tamar
> 
> gcc/ChangeLog:
> 
> 	PR tree-optimization/114932
> 	* tree-ssa-loop-ivopts.cc (constant_multiple_of): Use
> 	aff_combination_constant_multiple_p instead.
> 
> ---
> diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc
> index 7cae5bdefea3648ddde238a357af527a934a569e..c3218a3e8eedbb8d0a7f14c01eeb069cb6024c29 100644
> --- a/gcc/tree-ssa-loop-ivopts.cc
> +++ b/gcc/tree-ssa-loop-ivopts.cc
> @@ -2146,65 +2146,15 @@ idx_record_use (tree base, tree *idx,
>  static bool
>  constant_multiple_of (tree top, tree bot, widest_int *mul)
>  {
> -  tree mby;
> -  enum tree_code code;
> -  unsigned precision = TYPE_PRECISION (TREE_TYPE (top));
> -  widest_int res, p0, p1;
> -
> -  STRIP_NOPS (top);
> -  STRIP_NOPS (bot);
> -
> -  if (operand_equal_p (top, bot, 0))
> -    {
> -      *mul = 1;
> -      return true;
> -    }
> -
> -  code = TREE_CODE (top);
> -  switch (code)
> -    {
> -    case MULT_EXPR:
> -      mby = TREE_OPERAND (top, 1);
> -      if (TREE_CODE (mby) != INTEGER_CST)
> -	return false;
> -
> -      if (!constant_multiple_of (TREE_OPERAND (top, 0), bot, &res))
> -	return false;
> -
> -      *mul = wi::sext (res * wi::to_widest (mby), precision);
> -      return true;
> -
> -    case PLUS_EXPR:
> -    case MINUS_EXPR:
> -      if (!constant_multiple_of (TREE_OPERAND (top, 0), bot, &p0)
> -	  || !constant_multiple_of (TREE_OPERAND (top, 1), bot, &p1))
> -	return false;
> -
> -      if (code == MINUS_EXPR)
> -	p1 = -p1;
> -      *mul = wi::sext (p0 + p1, precision);
> -      return true;
> -
> -    case INTEGER_CST:
> -      if (TREE_CODE (bot) != INTEGER_CST)
> -	return false;
> -
> -      p0 = widest_int::from (wi::to_wide (top), SIGNED);
> -      p1 = widest_int::from (wi::to_wide (bot), SIGNED);
> -      if (p1 == 0)
> -	return false;
> -      *mul = wi::sext (wi::divmod_trunc (p0, p1, SIGNED, &res), precision);
> -      return res == 0;
> -
> -    default:
> -      if (POLY_INT_CST_P (top)
> -	  && POLY_INT_CST_P (bot)
> -	  && constant_multiple_p (wi::to_poly_widest (top),
> -				  wi::to_poly_widest (bot), mul))
> -	return true;
> +  aff_tree aff_top, aff_bot;
> +  tree_to_aff_combination (top, TREE_TYPE (top), &aff_top);
> +  tree_to_aff_combination (bot, TREE_TYPE (bot), &aff_bot);
> +  poly_widest_int poly_mul;
> +  if (aff_combination_constant_multiple_p (&aff_top, &aff_bot, &poly_mul)
> +      && poly_mul.is_constant (mul))
> +    return true;
>  
> -      return false;
> -    }
> +  return false;
>  }
>  
>  /* Return true if memory reference REF with step STEP may be unaligned.  */
> 
> 
> 
> 
>
  

Patch

diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc
index 7cae5bdefea3648ddde238a357af527a934a569e..c3218a3e8eedbb8d0a7f14c01eeb069cb6024c29 100644
--- a/gcc/tree-ssa-loop-ivopts.cc
+++ b/gcc/tree-ssa-loop-ivopts.cc
@@ -2146,65 +2146,15 @@  idx_record_use (tree base, tree *idx,
 static bool
 constant_multiple_of (tree top, tree bot, widest_int *mul)
 {
-  tree mby;
-  enum tree_code code;
-  unsigned precision = TYPE_PRECISION (TREE_TYPE (top));
-  widest_int res, p0, p1;
-
-  STRIP_NOPS (top);
-  STRIP_NOPS (bot);
-
-  if (operand_equal_p (top, bot, 0))
-    {
-      *mul = 1;
-      return true;
-    }
-
-  code = TREE_CODE (top);
-  switch (code)
-    {
-    case MULT_EXPR:
-      mby = TREE_OPERAND (top, 1);
-      if (TREE_CODE (mby) != INTEGER_CST)
-	return false;
-
-      if (!constant_multiple_of (TREE_OPERAND (top, 0), bot, &res))
-	return false;
-
-      *mul = wi::sext (res * wi::to_widest (mby), precision);
-      return true;
-
-    case PLUS_EXPR:
-    case MINUS_EXPR:
-      if (!constant_multiple_of (TREE_OPERAND (top, 0), bot, &p0)
-	  || !constant_multiple_of (TREE_OPERAND (top, 1), bot, &p1))
-	return false;
-
-      if (code == MINUS_EXPR)
-	p1 = -p1;
-      *mul = wi::sext (p0 + p1, precision);
-      return true;
-
-    case INTEGER_CST:
-      if (TREE_CODE (bot) != INTEGER_CST)
-	return false;
-
-      p0 = widest_int::from (wi::to_wide (top), SIGNED);
-      p1 = widest_int::from (wi::to_wide (bot), SIGNED);
-      if (p1 == 0)
-	return false;
-      *mul = wi::sext (wi::divmod_trunc (p0, p1, SIGNED, &res), precision);
-      return res == 0;
-
-    default:
-      if (POLY_INT_CST_P (top)
-	  && POLY_INT_CST_P (bot)
-	  && constant_multiple_p (wi::to_poly_widest (top),
-				  wi::to_poly_widest (bot), mul))
-	return true;
+  aff_tree aff_top, aff_bot;
+  tree_to_aff_combination (top, TREE_TYPE (top), &aff_top);
+  tree_to_aff_combination (bot, TREE_TYPE (bot), &aff_bot);
+  poly_widest_int poly_mul;
+  if (aff_combination_constant_multiple_p (&aff_top, &aff_bot, &poly_mul)
+      && poly_mul.is_constant (mul))
+    return true;
 
-      return false;
-    }
+  return false;
 }
 
 /* Return true if memory reference REF with step STEP may be unaligned.  */