https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104106

--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
I think DSE doesn't quite understand free() as must-def, likewise for
__builtin_stack_restore though that is _much_ more difficult to tie to
a specific alloca allocation.

It would be nice if the gimplifier would emit CLOBBERs for the VLAs
that go out of scope at the __builtin_stack_restore point, that would
fix the VLA case I think.  For

int f(char *a, unsigned n) {
    char *tmp_a = __builtin_malloc (n);

    for (unsigned i = 1; i != n; i++) tmp_a[i] = a[i];
    __builtin_free (tmp_a);
    return a[0];
}

it should already work but DSE is not set up to consider variable indexed
stores in loops that end up as pointer accesses like

*_5 = _6;

or rather stmt_kills_ref_p is too simple minded when looking at free():

          case BUILT_IN_FREE:
            {
              tree ptr = gimple_call_arg (stmt, 0);
              tree base = ao_ref_base (ref);
              if (base && TREE_CODE (base) == MEM_REF
                  && TREE_OPERAND (base, 0) == ptr)
                {
                  ++alias_stats.stmt_kills_ref_p_yes;
                  return true;
                }

it might be able to use points-to analysis or track down the base of
_5 via DR analysis but in the end I think it's DSEs job to do better
here.

With

int f(char *a, unsigned n) {
    char (*tmp_a)[n] = __builtin_malloc (n);

    for (unsigned i = 1; i != n; i++) (*tmp_a)[i] = a[i];
    __builtin_free (tmp_a);
    return a[0];
}

this issue is avoided but we then run into

          /* If we visit this PHI by following a backedge then we have to
             make sure ref->ref only refers to SSA names that are invariant
             with respect to the loop represented by this PHI node.  */
          if (dominated_by_p (CDI_DOMINATORS, gimple_bb (stmt),
                              gimple_bb (temp))
              && !for_each_index (ref->ref ? &ref->ref : &ref->base,
                                  check_name, gimple_bb (temp)))
            return DSE_STORE_LIVE;

which explicitely disables DSE of variably indexed accesses with the index
varying in the loop.  That's because of cross iteration dependences otherwise
mishandled.

Reply via email to