> Passes ought to distinguish GIMPLE values from GIMPLE invariants
> according to context.  As this test case shows, a GIMPLE invariant is
> not always the right value to replace as it cannot be used as a valid
> ARRAY_REF index.

OK, but the replacement is not made by FRE itself, but by fold:

/* Simplify the binary expression RHS, and return the result if
   simplified. */

static tree
simplify_binary_expression (tree rhs)
{
[...]
  result = fold_binary (TREE_CODE (rhs), TREE_TYPE (rhs), op0, op1);

  /* Make sure result is not a complex expression consiting
     of operators of operators (IE (a + b) + (a + c))
     Otherwise, we will end up with unbounded expressions if
     fold does anything at all.  */
  if (result)
    {
      if (is_gimple_min_invariant (result))
        return result;
      else if (SSA_VAR_P (result))
        return result;
      else if (EXPR_P (result))
[...]

We have

 TREE_CODE (rhs) = POINTER_PLUS_EXPR
 op0 = &p__name_buffer[1] with TREE_INVARIANT
 op1 = MAX_EXPR <D.738_31, 0>

At this point, op0 is_gimple_val (and valid GIMPLE) but op1 is not.  The 
problem is that, after the call to fold_binary, we have

  result = &p__name_buffer[(<unnamed-signed:32>) MAX_EXPR <D.738_31, 0> + 1]

and this is_gimple_min_invariant hence accepted by simplify_binary_expression.
Moreover, is_gimple_min_invariant => is_gimple_val so any subsequent attempt 
to gimplify will fail.

> My proposal is that we add a predicate is_gimple_const() and
> is_gimple_invariant() such that is_gimple_invariant() is implemented as:
>
> bool
> is_gimple_invariant (tree expr)
> {
>    if (is_gimple_const (expr))
>       return true;
>    else
>       return TREE_INVARIANT (expr);
> }
>
> And is_gimple_const() is the current is_gimple_min_invariant() without
> the ARRAY_REF case.

Do you mean "without the ADDR_EXPR case" or...?

> So my proposal is that PRE/FRE and the value propagators need to make
> sure that they propagate is_gimple_invariant() except inside ARRAY_REF
> indexes.

But what about fold?

> Also, we need to update the GIMPLE grammar so that ARRAY_REF and
> ARRAY_RANGE_REF take the appropriate values:
>
>       inner-compref: ...
>
>                       | ARRAY_REF
>
>                               op0 -> inner-compref
>                               op1 -> index-val
>                               op2 -> val
>                               op3 -> val
>
>       index-val: ID | CONST
>
>       val: index-val | invariant
>
>       invariant: rhs with TREE_INVARIANT set

I don't see why you're special-casing ARRAY_REF (and ARRAY_RANGE_REF).  As 
Richard pointed out, there are other rules that would need to be changed.

-- 
Eric Botcazou

Reply via email to