<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
</head>
<body dir="ltr">
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;" dir="ltr">
<p style="margin-top:0;margin-bottom:0">After I read the message again I think the BB0 comments were wrong. It should have been:</p>
<p style="margin-top:0;margin-bottom:0"><br>
</p>
<p style="margin-top:0;margin-bottom:0"><font size="2"><span style="font-size:11pt;">BB0:<br>
<font size="2"><span style="font-size:11pt;">  ; We know the memory at address 4 is dereferenceable here.<br>
  ; Though, that is due to the load and not the inbounds.</span></font><br>
  load %G<br>
  ; We know the memory at address 4 is dereferenceable here.<br>
  ; Though, that is due to the load and not the inbounds.<br>
  ...<br>
  br %BB1</span></font><br>
</p>
</div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> Johannes Doerfert <jdoerfert@anl.gov><br>
<b>Sent:</b> Thursday, March 7, 2019 11:52:55 AM<br>
<b>To:</b> Ralf Jung<br>
<b>Cc:</b> LLVM Dev<br>
<b>Subject:</b> Re: [llvm-dev] getelementptr inbounds with offset 0</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">Hi Ralf,<br>
<br>
I wanted to restart this discussion as it is important for my IPO<br>
attribute deduction work as well. Let me share my take on the situation,<br>
no guarantees!<br>
<br>
<br>
>From the Lang-Ref statement<br>
<br>
  "With the inbounds keyword, the result value of the GEP is undefined<br>
  if the address is outside the actual underlying allocated object and<br>
  not the address one-past-the-end."<br>
<br>
I'd argue that the actual offset value (here 0) is irrelevant. The GEP<br>
value is undefined if inbounds is present and the resulting pointer does<br>
not point into, or one-past-the-end, of an allocated object. This<br>
object, in my understanding, has to be the same one the base pointer of<br>
the GEP points into, or one-past-the-end, or you get again an undefined<br>
result.<br>
<br>
<br>
That being said, your initial "gep inbounds (int2ptr 4) 0" might cause<br>
an undefined value if 4 is not part of a valid allocation, or<br>
one-past-the-end.<br>
<br>
Now if that might cause any problems, e.g., if LLVM is able to act on<br>
this fact, depends on various factors including what you do with the<br>
GEP. Your initial problem seemed to be that LLVM "might be able to<br>
deduce dereferencable memory at location 4" but that should never be the<br>
case if you only form the aforementioned GEP, with or without the<br>
inbounds actually. Forming a pointer that has a undefined value is just<br>
that, a pointer with an undefined value. A side-effect based on the GEP<br>
will however __locally__ introduce an dereferencability assumption (in<br>
my opinion at least). Let's say the code looks like this:<br>
<br>
<br>
  %G = gep inbounds (int2ptr 4) 0<br>
  ; We don't know anything about the dereferencability of<br>
  ; the memory at address 4 here.<br>
  br %cnd, %BB0, %BB1<br>
<br>
BB0:<br>
  ; We don't know anything about the dereferencability of<br>
  ; the memory at address 4 here.<br>
  load %G<br>
  ; We know the memory at address 4 is dereferenceable here.<br>
  ; Though, that is due to the load and not the inbounds.<br>
  ...<br>
  br %BB1<br>
<br>
BB1:<br>
  ; We don't know anything about the dereferencability of<br>
  ; the memory at address 4 here.<br>
<br>
<br>
It is a different story if you start to use the GEP in other operations,<br>
e.g., to alter control flow. Then the (potential) undefined value can<br>
propagate.<br>
<br>
<br>
Any thought on this? Did I at least get your problem description right?<br>
<br>
Cheers,<br>
  Johannes<br>
<br>
<br>
<br>
P.S. Sorry if this breaks the thread and apologies that I had to remove<br>
     Bruce from the CC. It turns out replying to an email you did not<br>
     receive is complicated and getting on the LLVM-Dev list is nowadays<br>
     as well...<br>
<br>
<br>
On 02/25, Ralf Jung via llvm-dev wrote:<br>
> Hi Bruce,<br>
> <br>
> On 25.02.19 13:10, Bruce Hoult wrote:<br>
> > LLVM has no idea whether the address computed by GEP is actually<br>
> > within a legal object. The "inbounds" keyword is just you, the<br>
> > programmer, promising LLVM that you know it's ok and that you don't<br>
> > care what happens if it is actually out of bounds.<br>
> > <br>
> > <a href="https://llvm.org/docs/GetElementPtr.html#what-happens-if-an-array-index-is-out-of-bounds">
https://llvm.org/docs/GetElementPtr.html#what-happens-if-an-array-index-is-out-of-bounds</a><br>
> <br>
> The LangRef says I get a poison value when I am violating the bounds. What I am<br>
> asking is what exactly this means when the offset is 0 -- what *are* the<br>
> conditions under which an offset-by-0 is "out of bounds" and hence yields poison?<br>
> Of course LLVM cannot always statically determine this, but it relies on<br>
> (dynamically, on the "LLVM abstract machine") such things not happening, and I<br>
> am asking what exactly these dynamic conditions are.<br>
> <br>
> Kind regards,<br>
> Ralf<br>
> <br>
> > <br>
> > On Sun, Feb 24, 2019 at 9:05 AM Ralf Jung via llvm-dev<br>
> > <llvm...@lists.llvm.org> wrote:<br>
> >><br>
> >> Hi all,<br>
> >><br>
> >> What exactly are the rules for `getelementptr inbounds` with offset 0?<br>
> >><br>
> >> In Rust, we are relying on the fact that if we use, for example, `inttoptr` to<br>
> >> turn `4` into a pointer, we can then do `getelementptr inbounds` with offset 0<br>
> >> on that without LLVM deducing that there actually is any dereferencable memory<br>
> >> at location 4.  The argument is that we can think of there being a zero-sized<br>
> >> allocation. Is that a reasonable assumption?  Can something like this be<br>
> >> documented in the LangRef?<br>
> >><br>
> >> Relatedly, how does the situation change if the pointer is not created "out of<br>
> >> thin air" from a fixed integer, but is actually a dangling pointer obtained<br>
> >> previously from `malloc` (or `alloca` or whatever)?  Is getelementptr inbounds`<br>
> >> with offset 0 on such a pointer a NOP, or does it result in `poison`?  And if<br>
> >> that makes a difference, how does that square with the fact that, e.g., the<br>
> >> integer `0x4000` could well be inside such an allocation, but doing<br>
> >> `getelementptr inbounds` with offset 0 on that would fall under the first<br>
> >> question above?<br>
> >><br>
> >> Kind regards,<br>
> >> Ralf<br>
> >> _______________________________________________<br>
> >> LLVM Developers mailing list<br>
> >> llvm...@lists.llvm.org<br>
> >> <a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
> _______________________________________________<br>
> LLVM Developers mailing list<br>
> llvm...@lists.llvm.org<br>
> <a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
<br>
-- <br>
<br>
Johannes Doerfert<br>
Researcher<br>
<br>
Argonne National Laboratory<br>
Lemont, IL 60439, USA<br>
<br>
jdoerfert@anl.gov<br>
</div>
</span></font></div>
</body>
</html>