https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105769
--- Comment #10 from Richard Biener <rguenth at gcc dot gnu.org> --- (In reply to Jakub Jelinek from comment #9) > And just statements that refer to those 3 variables that (incorrectly) share > the stack slot + basic block boundaries. > grep 'bias\|D.5698\|D.5681\|:' /tmp/00 > struct struct void D.5698; > struct map_t D.5681; > struct vec bias; > <bb 2> [local count: 1073741829]: > _12 = (long unsigned int) &bias; > bias ={v} {CLOBBER}; > __ct_comp (&D.5698.__est, &D.5682); > <bb 3> [local count: 1073741824]: > MEM <vector(2) long unsigned int> [(void *)&D.5698 + 32B] = _21; > <bb 4> [local count: 1073741824]: > __ct_comp (_14, &D.5698.__est); > <bb 5> [local count: 1073741824]: > vect__16.52_79 = MEM <vector(2) long unsigned int> [(void *)&D.5698 + 32B]; > __dt_base (&MEM[(struct function *)&D.5698].D.5235); > D.5698 ={v} {CLOBBER}; > D.5698 ={v} {CLOBBER(eol)}; > MEM <char[16]> [(struct _Function_base *)&D.5681] = {}; > MEM <vector(2) long unsigned int> [(bool (*<T72d>) (union _Any_data & > {ref-all}, const union _Any_data & {ref-all}, _Manager_operation) *)&D.5681 > + 16B] = _84; > <bb 6> [count: 0]: > <L5>: > <bb 7> [count: 0]: > <L4>: > __dt_base (&MEM[(struct function *)&D.5698].D.5235); > D.5698 ={v} {CLOBBER}; > <bb 8> [local count: 429496]: > <bb 9> [local count: 1073312328]: > _19 (&D.5683.D.5217._M_functor, &D.5681); > <bb 10> [local count: 1073312328]: > __dt_base (&D.5681.D.5223); > D.5681 ={v} {CLOBBER}; > D.5681 ={v} {CLOBBER(eol)}; > bias ={v} {CLOBBER(eol)}; > <bb 11> [count: 0]: > <L0>: > __dt_base (&D.5681.D.5223); > D.5681 ={v} {CLOBBER}; > D.5681 ={v} {CLOBBER(eol)}; > <bb 12> [count: 0]: > <L2>: > D.5698 ={v} {CLOBBER}; > > Now, perhaps the sharing of stack slot between D.5681 and D.5698 is fine, > seems > D.5698 is destructed before D.5681 is constructed: > D.5698 ={v} {CLOBBER}; > D.5698 ={v} {CLOBBER(eol)}; > MEM <char[16]> [(struct _Function_base *)&D.5681] = {}; > and D.5698 is later used just in EH block reachable only from earlier basic > blocks > or just as > D.5698 ={v} {CLOBBER}; > in the last EH bb. But the sharing of the stack slot in between bias and > D.5698 looks wrong. What can be seen in the IL is: > _12 = (long unsigned int) &bias; > which has been hoisted before the > bias ={v} {CLOBBER}; > statement by the slp1 pass. > From: > ;; basic block 2, loop depth 0 > ;; pred: ENTRY > _3 = operator<< (&cout, "will do (ab)"); > endl (_3); > MEM[(struct vec *)&cov_jn] ={v} {CLOBBER}; > bias ={v} {CLOBBER}; > MEM[(struct function *)&D.5682] ={v} {CLOBBER}; > MEM <char[16]> [(struct _Function_base *)&D.5682] = {}; > MEM[(struct function *)&D.5682]._M_invoker = _M_invoke; > MEM[(struct function *)&D.5682].D.5235._M_manager = _M_manager; > __ct_comp (&D.5698.__est, &D.5682); > ;; succ: 5 > ;; 18 > > ;; basic block 5, loop depth 0 > ;; pred: 2 > D.5698.__cov = &cov_jn; > D.5698.__bias = &bias; > in dse4 to: > ;; basic block 2, loop depth 0 > ;; pred: ENTRY > _12 = VIEW_CONVERT_EXPR<long unsigned int>(&bias); > _15 = VIEW_CONVERT_EXPR<long unsigned int>(&cov_jn); > _21 = {_15, _12}; > _9 = VIEW_CONVERT_EXPR<long unsigned int>(_M_invoke); > _10 = VIEW_CONVERT_EXPR<long unsigned int>(_M_manager); > _8 = {_10, _9}; > _3 = operator<< (&cout, "will do (ab)"); > endl (_3); > MEM[(struct vec *)&cov_jn] ={v} {CLOBBER}; > bias ={v} {CLOBBER}; > MEM[(struct function *)&D.5682] ={v} {CLOBBER}; > MEM <char[16]> [(struct _Function_base *)&D.5682] = {}; > MEM <vector(2) long unsigned int> [(bool (*<T72d>) (union _Any_data & > {ref-all}, const union _Any_data & {ref-all}, _Manager_operation) *)&D.5682 > + 16B] = _8; > __ct_comp (&D.5698.__est, &D.5682); > ;; succ: 5 > ;; 18 > > ;; basic block 5, loop depth 0 > ;; pred: 2 > MEM <vector(2) long unsigned int> [(void *)&D.5698 + 32B] = _21; > in slp1. > > Is that what is incorrect? And we should never hoist taking of addresses > before a clobber on that var? I think that's the usual pattern for the two other stack-slot sharing PRs we have. The liveness analysis makes wrong assumptions about CLOBBER and CLOBBER isn't a barrier for address-takens (and we don't have birth CLOBBERs). But why does -fstack-reuse=none not help?