<div dir="ltr">So, I actually think there's two separate parts of this.<div><br></div><div>1. Pointer math is required to stay within an object if the GEP has the "inbounds" attribute. Nothing is inbounds of the null pointer, so a GEP instruction with a null pointer, and non-zero offsets, is invalid on its face, even without the load.</div><div><br></div><div><div>Now, you can tell clang to stop putting inbounds on pointer arithmetic GEPs by using -fwrapv or -fno-strict-overflow. Doing that doesn't fix the issue, because it's not actually the GEP that's being optimized in this particular case.<br></div></div><div><br></div><div>2. Separately, LLVM's pointer aliasing rules prohibit (even without the GEP marked inbounds) constructing a pointer to a random object with a GEP. (<a href="http://llvm.org/docs/LangRef.html#pointeraliasing">http://llvm.org/docs/LangRef.html#pointeraliasing</a>). This permission is used in InstCombineLoadStoreAlloca.cpp canSimplifyNullLoadOrGEP to eliminate the load based on a null pointer GEP, despite the non-zero offset to a not-inbounds GEP.</div><div><br></div><div>To the first, asking people who do crazy stuff like this to compile with -fno-strict-overflow is reasonable...they're invoking C-level undefined behavior by doing arbitrary pointer-math, so they should use the flag that tells the compiler to make arbitrary pointer-math not be UB.</div><div><br></div><div>And to the second, it seems to me that it would be fairly reasonable change to make the latter optimization dependent on the GEP being marked inbounds. (Even if the alias analysis still doesn't promise you anything here.)</div><div><br></div><div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jul 6, 2017 at 3:17 PM, Kaylor, Andrew <span dir="ltr"><<a href="mailto:andrew.kaylor@intel.com" target="_blank">andrew.kaylor@intel.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">





<div lang="EN-US">
<div class="gmail-m_8844556824433871109m_-3501768632180904014WordSection1"><span>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">> glibc does accept patches...or are you talking about two separate instances of this problem, both in glibc and something else?<u></u><u></u></span></p>
<p class="MsoNormal"><a name="m_8844556824433871109_m_-3501768632180904014__MailEndCompose"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"><u></u> <u></u></span></a></p>
</span><p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">I originally saw this in a benchmark (which it may be possible to get changed) and only afterward found the glibc idiom.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">The most recent glibc code is a bit more complicated than I represented below.  If you look up obstack.h you can see what’s there now.  Basically, they’re computing
 a pointer alignment that may be based on some non-null base pointer or may be based on null, depending on the target architecture.  I’m sure it’s possible to make it more sensible, but I’ve never interacted with the glibc community so I’m not sure how open
 they would be to changing this.  I suspect I’d need a more compelling argument than clang-compatibility (or maybe even standards compatibility).<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"><u></u> <u></u></span></p>
<p class="MsoNormal"><a name="m_8844556824433871109_m_-3501768632180904014______replyseparator"></a><b><span style="font-size:11pt;font-family:Calibri,sans-serif">From:</span></b><span style="font-size:11pt;font-family:Calibri,sans-serif"> James Y Knight [mailto:<a href="mailto:jyknight@google.com" target="_blank">jyknight@google.com</a>]
<br>
<b>Sent:</b> Thursday, July 06, 2017 12:06 PM<br>
<b>To:</b> Kaylor, Andrew <<a href="mailto:andrew.kaylor@intel.com" target="_blank">andrew.kaylor@intel.com</a>><br>
<b>Cc:</b> llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>><br>
<b>Subject:</b> Re: [llvm-dev] GEP with a null pointer base<u></u><u></u></span></p><div><div class="gmail-m_8844556824433871109h5">
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal"><u></u> <u></u></p>
<p class="MsoNormal">On Thu, Jul 6, 2017 at 2:06 PM, Kaylor, Andrew via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<u></u><u></u></p>
<blockquote style="border-top:none;border-right:none;border-bottom:none;border-left:1pt solid rgb(204,204,204);padding:0in 0in 0in 6pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal">I've got a problem that I would like some input on.  The problem basically boils down to a program that I am compiling, whose source I don't control, doing something like this:<u></u><u></u></p>
<p class="MsoNormal"> <u></u><u></u></p>
<p class="MsoNormal">  p = (char*)0 + n<u></u><u></u></p>
<p class="MsoNormal"> <u></u><u></u></p>
<p class="MsoNormal">where 'n' is an intptr_t-sized value that the program knows is actually a valid address for a pointer.<u></u><u></u></p>
<p class="MsoNormal"> <u></u><u></u></p>
<p class="MsoNormal">clang translates this as<u></u><u></u></p>
<p class="MsoNormal"> <u></u><u></u></p>
<p class="MsoNormal">  %p = getelementptr inbounds i8, i8* null, i64 %n<u></u><u></u></p>
<p class="MsoNormal"> <u></u><u></u></p>
<p class="MsoNormal">So far, so good.  The problem is that while LLVM seems to consider the above IR to be valid, we officially do not allow dereferencing a pointer constructed in this way (if I’m reading
 the rules correctly).  Consequently, if this GEP ever gets close enough to a load using the pointer, InstCombine will eliminate the GEP and the load.<u></u><u></u></p>
<p class="MsoNormal"> <u></u><u></u></p>
<p class="MsoNormal">I've been told that the '(char*)0 + n' construct is invalid according to the C standard.  However, this pattern appears in the glibc malloc implementation, so I'd like to be able
 to handle it anyway.<u></u><u></u></p>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">glibc does accept patches...or are you talking about two separate instances of this problem, both in glibc and something else?<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<div>
<div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
</div>
</div>
</div>
</div></div></div>
</div>

</blockquote></div><br></div></div></div>