Created attachment 53156 [details] A testcase When building glibc master branch with -mavx512f, I got [hjl@gnu-tgl-2 tmp]$ gcc -O2 -march=x86-64 -S -Wall x.i -mavx512f dl-load.c: In function ‘_dl_map_object_from_fd.constprop’: dl-load.c:1158:30: warning: ‘(((char *)loadcmds.113_68 + _933 + 16))[329406144173384849].mapend’ may be used uninitialized [-Wmaybe-uninitialized] [hjl@gnu-tgl-2 tmp]$ The code looks like struct loadcmd *c = &loadcmds[nloadcmds++]; c->mapstart = ALIGN_DOWN (ph->p_vaddr, GLRO(dl_pagesize)); c->mapend = ALIGN_UP (ph->p_vaddr + ph->p_filesz, GLRO(dl_pagesize)); c->dataend = ph->p_vaddr + ph->p_filesz; c->allocend = ph->p_vaddr + ph->p_memsz; /* Remember the maximum p_align. */ if (powerof2 (ph->p_align) && ph->p_align > p_align_max) p_align_max = ph->p_align; c->mapoff = ALIGN_DOWN (ph->p_offset, GLRO(dl_pagesize)); /* Determine whether there is a gap between the last segment and this one. */ if (nloadcmds > 1 && c[-1].mapend != c->mapstart) has_holes = true; c[-1].mapend should always be initialized.
Simply change the cost of integer store makes the warnings to go away: diff --git a/gcc/config/i386/x86-tune-costs.h b/gcc/config/i386/x86-tune-costs.h index 6c9066c84cc..b83bb79c065 100644 --- a/gcc/config/i386/x86-tune-costs.h +++ b/gcc/config/i386/x86-tune-costs.h @@ -3276,7 +3276,11 @@ struct processor_costs generic_cost = { {6, 6, 6}, /* cost of loading integer registers in QImode, HImode and SImode. Relative to reg-reg move (2). */ +#if 0 {6, 6, 6}, /* cost of storing integer registers */ +#else + {8, 8, 8}, /* cost of storing integer registers */ +#endif {6, 6, 6, 10, 15}, /* cost of loading SSE register in 32bit, 64bit, 128bit, 256bit and 512bit */ {6, 6, 6, 10, 15}, /* cost of storing SSE register
GCC 11 has the same issue.
# VUSE <.MEM_699> _109 = MEM[(struct loadcmd *)_106 + -56B].mapend; my only suspicion is that we somehow isolate (and not optimize as unreachable) the nloadcmds < 1 case in the preceeding case.
(In reply to Richard Biener from comment #3) > # VUSE <.MEM_699> > _109 = MEM[(struct loadcmd *)_106 + -56B].mapend; > > my only suspicion is that we somehow isolate (and not optimize as > unreachable) > the nloadcmds < 1 case in the preceeding case. Nope the statement we are diagnosing is guarded by nloadcmds > 1. A reduced testcase looks like the following, needs -Os -fno-ivopts to reproduce the diagnostics. It is somewhat of a fundamental limit of the analysis since when walking the virtual use-def chain we look for aliases but q[-1] doesn't alias q[0] but when walking the backedge we simply arrive at the very same stmt again and interpret it as if it were within the same context. That might also be a problem for passes using walk_aliased_vdefs for other purposes than diagnostics. I think that when walking a backedge walk_aliased_vdefs would need to be more careful with interpreting the defs it runs into. int foo (int n) { int *p = __builtin_malloc (n); int nloadcmds = 0; int found = 0; do { int *q = &p[nloadcmds++]; *q = n; if (nloadcmds > 1 && q[-1] != 7) found = 1; } while (nloadcmds < n); return found; }
GCC 11.4 is being released, retargeting bugs to GCC 11.5.
GCC 11 branch is being closed.
GCC 12 branch is being closed.