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.