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...

Reply via email to