https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102720
--- Comment #7 from Jan Hubicka <hubicka at gcc dot gnu.org> --- simplified testcase is: typedef unsigned char uint8_t; typedef __SIZE_TYPE__ size_t; extern void* malloc (size_t); extern void* memset (void*, int, size_t); #define test(T, U) \ __attribute__((noinline)) \ U test_##T##U (T *s) \ { \ U i; \ for (i=0; s[i]; ++i); \ return i; \ } test (uint8_t, size_t) #define run(T, U, i) \ { \ T *q = p; \ q[i] = 0; \ if (test_##T##U (p) != i) __builtin_abort (); \ } int main(void) { void *p = malloc (1024); memset (p, 0xf, 1024); run (uint8_t, size_t, 1); return 0; } things goes wrong with dse2: ;; Function main (main, funcdef_no=1, decl_uid=1994, cgraph_uid=2, symbol_order=1) (executed once) Deleted dead store: MEM[(uint8_t *)p_4 + 1B] = 0; Deleted dead call: memset (p_4, 15, 1024); int main () { void * p; long unsigned int _1; <bb 2> [local count: 1073741824]: p_4 = malloc (1024); _1 = test_uint8_tsize_t (p_4); if (_1 != 1) goto <bb 3>; [0.00%] else goto <bb 4>; [100.00%] <bb 3> [count: 0]: __builtin_abort (); <bb 4> [local count: 1073741824]: return 0; } so it seems that we conlcude that the memory initialization is not needed. modref2 info seems ok: loads: Limits: 32 bases, 16 refs Base 0: alias set 0 Ref 0: alias set 0 access: Parm 0 param offset:0 offset:0 size:8 max_size:8 access: Parm 0 param offset:1 offset:0 size:-1 max_size:-1 stores: Limits: 32 bases, 16 refs parm 0 flags: direct since function is detected as pure we do not store noclobber which is implicit here. PTA solution is: ANYTHING = { ANYTHING } ESCAPED = { ESCAPED NONLOCAL } NONLOCAL = { ESCAPED NONLOCAL } same as callescape(23) STOREDANYTHING = { } INTEGER = { ANYTHING } HEAP(14) = { NULL ANYTHING } malloc = { } callescape(9) = { ESCAPED NONLOCAL } CALLUSED(10) = { ESCAPED NONLOCAL } same as callescape(9) CALLCLOBBERED(11) = { ESCAPED NONLOCAL } same as callescape(9) callarg(12) = { ESCAPED NONLOCAL } same as callescape(9) p_4 = { HEAP(14) } derefaddrtmp(15) = { NULL } test_uint8_tsize_t = { } callescape(17) = { NONLOCAL } CALLUSED(18) = { NONLOCAL HEAP(14) } CALLCLOBBERED(19) = { } callarg(20) = { HEAP(14) } _1 = { NONLOCAL HEAP(14) } same as CALLUSED(18) abort = { } callescape(23) = { ESCAPED NONLOCAL } CALLUSED(24) = { ESCAPED NONLOCAL } same as callescape(23) CALLCLOBBERED(25) = { } main = { } Alias information for main Aliased symbols Call clobber information ESCAPED, points-to non-local, points-to vars: { } Flow-insensitive points-to information p_4, points-to NULL, points-to vars: { D.2014 } We know that heap is used by the call, so I am bit confused why we optimize the store out...