<div dir="ltr">There are two problems:<div>1. padding after union and call to q(), without LTO we can't remove that store.</div><div>2. shortcut which I have which ignores all instructions q() . this assume that memset to <span style="background-color:rgb(255,255,254);color:rgb(0,0,0)">acpar.match, acpar.matchinfo also useful which is not true. </span><span style="background-color:rgb(255,255,254);color:rgb(0,0,0)">I should be able to improve this case.</span></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Aug 1, 2019 at 11:29 PM Vitaly Buka <<a href="mailto:vitalybuka@google.com">vitalybuka@google.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr">On a first look case like this should nor be a problem. The tail of the memset here is unused because it's replaced immediately without reads . So it can be trimmed. I will try the patch and let you know.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Aug 1, 2019 at 9:51 AM Alexander Potapenko <<a href="mailto:glider@google.com" target="_blank">glider@google.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Thu, Aug 1, 2019 at 6:38 PM JF Bastien <<a href="mailto:jfbastien@apple.com" class="gmail-m_7332456978546243880cremed" target="_blank">jfbastien@apple.com</a>> wrote:<br>
><br>
><br>
><br>
> > On Aug 1, 2019, at 9:20 AM, Alexander Potapenko <<a href="mailto:glider@google.com" class="gmail-m_7332456978546243880cremed" target="_blank">glider@google.com</a>> wrote:<br>
> ><br>
> > On Thu, Aug 1, 2019 at 6:09 PM JF Bastien <<a href="mailto:jfbastien@apple.com" class="gmail-m_7332456978546243880cremed" target="_blank">jfbastien@apple.com</a>> wrote:<br>
> >><br>
> >> Hi Alexander,<br>
> >><br>
> >> The code doesn’t compile. Could you send a <a href="http://godbolt.org" rel="noreferrer" class="gmail-m_7332456978546243880cremed" target="_blank">godbolt.org</a> link that shows the issue?<br>
> > Sorry about that, here's the link: <a href="https://godbolt.org/z/-PinQP" rel="noreferrer" class="gmail-m_7332456978546243880cremed" target="_blank">https://godbolt.org/z/-PinQP</a><br>
> ><br>
> > Lines 4 to 8 are initializing |acpar|.<br>
> > If I'm understanding correctly, the store to 8(%rsp) at line 7 can be<br>
> > removed because of the store at line 35.<br></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">><br>
> These are in different basic blocks. IIRC there are a bunch of cases where DCE just fails when there’s any control flow. I think this is what you’re seeing here.<br>
I think Vitaly's patches (<a href="https://reviews.llvm.org/D61879" rel="noreferrer" class="gmail-m_7332456978546243880cremed" target="_blank">https://reviews.llvm.org/D61879</a>) should<br>
allow DSE to work across basic blocks. But, as you mentioned, the<br>
problem is that we only have a memset at IR level.<br>
><br>
> > Same for store to 24(%rsp), which is later overwritten at lines 11 and 16.<br>
><br>
> I’m not sure what we should do here… If it were a constant store we’d fold it in, but here both stores are variables so it’s not clear that we really should be doing much in MemCpyOptimizer.<br>
> The problem I see here is: there’s a small memset, followed by variable stores to the same location. DCE’ing requires realizing that the memset is small enough that the backend will expand it, at which point DCE will kick in. MemCpyOptimizer doesn’t know what “small” is, partly because it’s based on alignment and optimization level. Maybe it can be a target hook (“what would you do with this memset?”), that MemCpyOptimizer uses when it sees a memset followed by variable stores to the same location? We already fold in constant stores (replace the m() call by one)… but again this isn’t clearly a win: if you enable SSE you’ll get wide stores, followed by stores of smaller size. With SSE I’m not sure I’d want us to remove the MOVAPS instructions.<br>
Yes, this depends very much on the backend flags, therefore it might<br>
be too early to lower that memset before DSE.<br>
I was thinking about some kind of a peephole optimization, that<br>
deletes stores to the same memory location (at least for %rsp-based<br>
addresses) in the backend.<br>
I suspect AArch64 has something like this already, at least we don't<br>
see these redundant stores there.<br>
<br>
<br>
><br>
><br>
> >> Thanks,<br>
> >><br>
> >> JF<br>
> >><br>
> >>> On Aug 1, 2019, at 7:21 AM, Alexander Potapenko <<a href="mailto:glider@google.com" class="gmail-m_7332456978546243880cremed" target="_blank">glider@google.com</a>> wrote:<br>
> >>><br>
> >>> Hi folks,<br>
> >>><br>
> >>> When compiling the attached example with -ftrivial-auto-var-init=zero:<br>
> >>><br>
> >>> $ clang   -no-integrated-as  -mno-sse -m64 -mstack-alignment=8    -O2<br>
> >>> -ftrivial-auto-var-init=zero<br>
> >>> -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang<br>
> >>> -g  -o ipt.ll -c ipt.i -w -S -emit-llvm<br>
> >>><br>
> >>> , Clang generates an initialization memset() call for |acpar| in the IR:<br>
> >>><br>
> >>>   %0 = bitcast %struct.xt_action_param* %acpar to i8*, !dbg !27<br>
> >>>   call void @llvm.memset.p0i8.i64(i8* nonnull align 8 %0, i8 0, i64<br>
> >>> 40, i1 false), !dbg !28<br>
> >>><br>
> >>> Clang only splits memsets into series of stores under certain<br>
> >>> conditions, so it's hard to remove redundant stores on the IR level<br>
> >>> (even with the recent DSE patches: <a href="https://reviews.llvm.org/D61879" rel="noreferrer" class="gmail-m_7332456978546243880cremed" target="_blank">https://reviews.llvm.org/D61879</a>).<br>
> >>> In the resulting assembly, however, the memset is lowered into a<br>
> >>> series of MOVQ instructions (see the attached ipt.s file), of which at<br>
> >>> least the stores to 24(%rsp) and 16(%rsp) are redundant.<br>
> >>><br>
> >>> Given that at MCInst level we already know if a memset is split into a<br>
> >>> sequence of stores, can we do a better job by making the backend<br>
> >>> delete these redundant stores for us?<br>
> >>><br>
> >>> Alex<br>
> >>><br>
> >>> --<br>
> >>> Alexander Potapenko<br>
> >>> Software Engineer<br>
> >>><br>
> >>> Google Germany GmbH<br>
> >>> Erika-Mann-Straße, 33<br>
> >>> 80636 München<br>
> >>><br>
> >>> Geschäftsführer: Paul Manicle, Halimah DeLaine Prado<br>
> >>> Registergericht und -nummer: Hamburg, HRB 86891<br>
> >>> Sitz der Gesellschaft: Hamburg<br>
> >>> <ipt.i><ipt.s><br>
> >><br>
> ><br>
> ><br>
> > --<br>
> > Alexander Potapenko<br>
> > Software Engineer<br>
> ><br>
> > Google Germany GmbH<br>
> > Erika-Mann-Straße, 33<br>
> > 80636 München<br>
> ><br>
> > Geschäftsführer: Paul Manicle, Halimah DeLaine Prado<br>
> > Registergericht und -nummer: Hamburg, HRB 86891<br>
> > Sitz der Gesellschaft: Hamburg<br>
><br>
<br>
<br>
-- <br>
Alexander Potapenko<br>
Software Engineer<br>
<br>
Google Germany GmbH<br>
Erika-Mann-Straße, 33<br>
80636 München<br>
<br>
Geschäftsführer: Paul Manicle, Halimah DeLaine Prado<br>
Registergericht und -nummer: Hamburg, HRB 86891<br>
Sitz der Gesellschaft: Hamburg<br>
</blockquote></div></div>
</blockquote></div>