diff mbox

Fix PR45297: handle ADDR_EXPR in interpret_rhs_expr as in follow_ssa_edge_expr.

Message ID 1291274381-26572-1-git-send-email-sebpop@gmail.com
State New
Headers show

Commit Message

Sebastian Pop Dec. 2, 2010, 7:19 a.m. UTC
Hi,

This fixes the compilation of the testcase of PR45297 on 32-bit
machines: the ICE occurs because we rewrite out-of-SSA a phi node for
which scev manages to analyze: in this code

<bb 3>:
  q_5 = &MEM[(void *)q_1 + 4294967288B];

<bb 4>:
  # q_1 = PHI <q_3(2), q_5(3)>
  if (q_1 != p_2(D))
    goto <bb 3>;
  else
    goto <bb 5>;

scev analysis is able to determine that q1 = {q_3, +, -8}_1 and in the
same time, scev fails to analyze q5.  And that triggers a rewrite of
q_5 out of SSA making the scev analysis of q1 impossible in the code
generator.

I am testing this patch on amd64-linux, ok for trunk after test?

Thanks,
Sebastian

2010-12-01  Sebastian Pop  <sebastian.pop@amd.com>

	PR middle-end/45297
	* tree-scalar-evolution.c (interpret_rhs_expr): Handle ADDR_EXPR
	with MEM_REFs as POINTER_PLUS_EXPR.
---
 gcc/ChangeLog               |    6 ++++++
 gcc/tree-scalar-evolution.c |   21 ++++++++++++++++++---
 2 files changed, 24 insertions(+), 3 deletions(-)

Comments

Richard Biener Dec. 2, 2010, 9:01 a.m. UTC | #1
On Thu, 2 Dec 2010, Sebastian Pop wrote:

> Hi,
> 
> This fixes the compilation of the testcase of PR45297 on 32-bit
> machines: the ICE occurs because we rewrite out-of-SSA a phi node for
> which scev manages to analyze: in this code
> 
> <bb 3>:
>   q_5 = &MEM[(void *)q_1 + 4294967288B];
> 
> <bb 4>:
>   # q_1 = PHI <q_3(2), q_5(3)>
>   if (q_1 != p_2(D))
>     goto <bb 3>;
>   else
>     goto <bb 5>;
> 
> scev analysis is able to determine that q1 = {q_3, +, -8}_1 and in the
> same time, scev fails to analyze q5.  And that triggers a rewrite of
> q_5 out of SSA making the scev analysis of q1 impossible in the code
> generator.
> 
> I am testing this patch on amd64-linux, ok for trunk after test?

Ok with ...

> Thanks,
> Sebastian
> 
> 2010-12-01  Sebastian Pop  <sebastian.pop@amd.com>
> 
> 	PR middle-end/45297
> 	* tree-scalar-evolution.c (interpret_rhs_expr): Handle ADDR_EXPR
> 	with MEM_REFs as POINTER_PLUS_EXPR.
> ---
>  gcc/ChangeLog               |    6 ++++++
>  gcc/tree-scalar-evolution.c |   21 ++++++++++++++++++---
>  2 files changed, 24 insertions(+), 3 deletions(-)
> 
> diff --git a/gcc/ChangeLog b/gcc/ChangeLog
> index c9e7072..d38bc01 100644
> --- a/gcc/ChangeLog
> +++ b/gcc/ChangeLog
> @@ -1,5 +1,11 @@
>  2010-12-01  Sebastian Pop  <sebastian.pop@amd.com>
>  
> +	PR middle-end/45297
> +	* tree-scalar-evolution.c (interpret_rhs_expr): Handle ADDR_EXPR
> +	with MEM_REFs as POINTER_PLUS_EXPR.
> +
> +2010-12-01  Sebastian Pop  <sebastian.pop@amd.com>
> +
>  	* graphite-sese-to-poly.c (analyze_drs_in_stmts): Fix set but
>  	unused warning.
>  	(rewrite_cross_bb_scalar_deps_out_of_ssa): Same.
> diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
> index 8a5797e..b65e295 100644
> --- a/gcc/tree-scalar-evolution.c
> +++ b/gcc/tree-scalar-evolution.c
> @@ -1698,7 +1698,7 @@ static tree
>  interpret_rhs_expr (struct loop *loop, gimple at_stmt,
>  		    tree type, tree rhs1, enum tree_code code, tree rhs2)
>  {
> -  tree res, chrec1, chrec2;
> +  tree res, chrec1, chrec2, expr;
>  
>    if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS)
>      {
> @@ -1715,12 +1715,27 @@ interpret_rhs_expr (struct loop *loop, gimple at_stmt,
>  	  return chrec_convert (type, analyze_scalar_evolution (loop, rhs1),
>  				at_stmt);
>  	}
> -
> -      return chrec_dont_know;
>      }
>  
>    switch (code)
>      {
> +    case ADDR_EXPR:
> +      /* Handle &MEM[ptr + CST] which is equivalent to POINTER_PLUS_EXPR.  */
> +      if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != MEM_REF)
> +	{
> +	  res = chrec_dont_know;
> +	  break;
> +	}
> +
> +      expr = TREE_OPERAND (rhs1, 0);
> +      rhs1 = TREE_OPERAND (expr, 0);
> +      rhs2 = TREE_OPERAND (expr, 1);
> +      type = TREE_TYPE (rhs1);
> +      STRIP_USELESS_TYPE_CONVERSION (rhs1);
> +      STRIP_USELESS_TYPE_CONVERSION (rhs2);

The STRIP_USELESS_TYPE_CONVERSION removed and type retained (not
set to that of rhs1).  You can then also easily get rid of the
new expr temporary.  Thus,

        rhs1 = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0);
        rhs2 = TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1);

that should be all that is necessary.

Thanks,
Richard.
diff mbox

Patch

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c9e7072..d38bc01 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,11 @@ 
 2010-12-01  Sebastian Pop  <sebastian.pop@amd.com>
 
+	PR middle-end/45297
+	* tree-scalar-evolution.c (interpret_rhs_expr): Handle ADDR_EXPR
+	with MEM_REFs as POINTER_PLUS_EXPR.
+
+2010-12-01  Sebastian Pop  <sebastian.pop@amd.com>
+
 	* graphite-sese-to-poly.c (analyze_drs_in_stmts): Fix set but
 	unused warning.
 	(rewrite_cross_bb_scalar_deps_out_of_ssa): Same.
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index 8a5797e..b65e295 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -1698,7 +1698,7 @@  static tree
 interpret_rhs_expr (struct loop *loop, gimple at_stmt,
 		    tree type, tree rhs1, enum tree_code code, tree rhs2)
 {
-  tree res, chrec1, chrec2;
+  tree res, chrec1, chrec2, expr;
 
   if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS)
     {
@@ -1715,12 +1715,27 @@  interpret_rhs_expr (struct loop *loop, gimple at_stmt,
 	  return chrec_convert (type, analyze_scalar_evolution (loop, rhs1),
 				at_stmt);
 	}
-
-      return chrec_dont_know;
     }
 
   switch (code)
     {
+    case ADDR_EXPR:
+      /* Handle &MEM[ptr + CST] which is equivalent to POINTER_PLUS_EXPR.  */
+      if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != MEM_REF)
+	{
+	  res = chrec_dont_know;
+	  break;
+	}
+
+      expr = TREE_OPERAND (rhs1, 0);
+      rhs1 = TREE_OPERAND (expr, 0);
+      rhs2 = TREE_OPERAND (expr, 1);
+      type = TREE_TYPE (rhs1);
+      STRIP_USELESS_TYPE_CONVERSION (rhs1);
+      STRIP_USELESS_TYPE_CONVERSION (rhs2);
+
+      /* Fall through.  */
+
     case POINTER_PLUS_EXPR:
       chrec1 = analyze_scalar_evolution (loop, rhs1);
       chrec2 = analyze_scalar_evolution (loop, rhs2);