<div dir="ltr"><div><div><div>I believe the background for this comment is just general caution resulting from<br> - vague "both represent the same address." wording in a supported language standard, and<br></div> - the surprising situation in which pointer equality semantics are almost entirely distinct from pointer aliasing semantics<br><br></div>In general, ICmp folding shouldn't consult alias analysis or do its own alias-analysis-like things.<br><br></div>Dan<br><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Sep 24, 2015 at 11:42 AM, Hans Wennborg via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Apologies if this has come up before. I couldn't find any previous<br>
discussion, but I did find this commit.<br>
<br>
I was wondering why LLVM cannot optimize this code (which GCC does optimize):<br>
<br>
  int f(int *p) { int x; return p == &x; }<br>
<br>
it would seem that this must always return 0. (This occurs as a<br>
self-assignment check in the code I was looking at; I was hoping we<br>
could fold that check away.)<br>
<br>
I'd be interested to hear what those with a stronger understanding of<br>
the standard than myself think about this, and also if there is any<br>
example of something that could break because of this optimization. If<br>
not, I'd like us to optimize it :-)<br>
<br>
<br>
On Thu, Jan 31, 2013 at 4:49 PM, Dan Gohman <<a href="mailto:dan433584@gmail.com">dan433584@gmail.com</a>> wrote:<br>
> Author: djg<br>
> Date: Thu Jan 31 18:49:06 2013<br>
> New Revision: 174131<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=174131&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=174131&view=rev</a><br>
> Log:<br>
> Add a comment explaining an unavailable optimization.<br>
><br>
> Modified:<br>
>     llvm/trunk/lib/Analysis/InstructionSimplify.cpp<br>
><br>
> Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=174131&r1=174130&r2=174131&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=174131&r1=174130&r2=174131&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original)<br>
> +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Thu Jan 31 18:49:06 2013<br>
> @@ -1688,6 +1688,34 @@ static Value *ExtractEquivalentCondition<br>
>    return 0;<br>
>  }<br>
><br>
> +// A significant optimization not implemented here is assuming that alloca<br>
> +// addresses are not equal to incoming argument values. They don't *alias*,<br>
> +// as we say, but that doesn't mean they aren't equal, so we take a<br>
> +// conservative approach.<br>
> +//<br>
> +// This is inspired in part by C++11 5.10p1:<br>
> +//   "Two pointers of the same type compare equal if and only if they are both<br>
> +//    null, both point to the same function, or both represent the same<br>
> +//    address."<br>
> +//<br>
> +// This is pretty permissive.<br>
<br>
Indeed :-/<br>
<br>
> +// It's also partly due to C11 6.5.9p6:<br>
> +//   "Two pointers compare equal if and only if both are null pointers, both are<br>
> +//    pointers to the same object (including a pointer to an object and a<br>
> +//    subobject at its beginning) or function, both are pointers to one past the<br>
> +//    last element of the same array object, or one is a pointer to one past the<br>
> +//    end of one array object and the other is a pointer to the start of a<br>
> +//    different array object that happens to immediately follow the ï¬ rst array<br>
> +//    object in the address space.)<br>
> +//<br>
> +// C11's version is more restrictive, however there's no reason why an argument<br>
> +// couldn't be a one-past-the-end value for a stack object in the caller and be<br>
> +// equal to the beginning of a stack object in the callee.<br>
<br>
This is interesting.<br>
<br>
For the one-past-the-end pointer to point into the callee, the stack<br>
would have to be growing upwards. So this won't happen on X86. Can we<br>
turn this optimization on for downward-growing-stack targets?<br>
<br>
Second, if the stack grows upward, and the function argument does<br>
point into the callee stack frame, "p" and "&x" could have the same<br>
contents. So per the "represent the same address" part above, they<br>
should compare equal? But they're noalias? Are we allowed to write<br>
through p? It wasn't a pointer to a valid object when we made the<br>
call, but it became valid in the callee? This is all terrifying.<br>
<br>
I suppose one could store the value of &x though, and then use it<br>
again later, i.e.:<br>
<br>
  int *global;<br>
  int f(int *p) {<br>
    int x;<br>
    global = &x;<br>
    return p == &x;<br>
  }<br>
  int g() {<br>
    f(0);<br>
    return f(global);<br>
  }<br>
<br>
Is g() guaranteed to return 1 here? Maybe we could claim it's<br>
implementation dependent? GCC does not seem fold p==&x to 0 here. I<br>
suppose we could make sure to check whether &x escapes the function?<br>
<br>
 - Hans<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div><br></div>