<div dir="ltr"><div dir="auto"><div>I haven't followed the whole discussion here, so I'm not sure if I've understood the proposal correctly, but I'm a bit concerned.</div><div><br></div><div>In the IR generated by Clang, lifetime markers are inserted to denote the scope of the variable's storage. As such, it ought to be entirely valid to coalesce the variables x and y to a single address in the following example, <i>even though</i> the addresses both escape and are compared:</div><div><br></div><font face="monospace">int *p_x, *p_y;<br></font><div><font face="monospace">int test() {<br>  {<br>    int x = 5;<br>    p_x = &x;<br>  }<br>  {<br>    int y = 5;<br>    p_y = &y;<br>  }<br>  return p_x == p_y;<br>}<br></font></div><div><div dir="auto"><br></div><div>Although we don't  currently appear to do such coalescing, it would seem unfortunate to define the IR so as to prohibit it. </div><div><br></div><div>Furthermore, it's not clear to me that the comparison at the end is actually required to return a consistent answer. The deallocation of x and y magically transforms all pointers to them into "invalid pointer values", the use of which is implementation defined  [<a href="https://wg21.link/basic.stc">https://wg21.link/basic.stc</a>]. I think it'd be OK for the implementation to say that deallocation turns all such pointers into indeterminate values -- and, thus, to end up with (p_x == p_y) being false, and yet, for a subsequent `printf("%p %p\n", p_x, p_y);` to print the same value twice.</div><div><br></div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Jan 18, 2021, 5:05 PM Johannes Doerfert via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
On 1/12/21 4:11 PM, Michael Kruse wrote:<br>
> Am Di., 12. Jan. 2021 um 12:33 Uhr schrieb Ralf Jung via llvm-dev<br>
> <<a href="mailto:llvm-dev@lists.llvm.org" rel="noreferrer" target="_blank">llvm-dev@lists.llvm.org</a>>:<br>
>> I hope this question has not been answered yet, but I don't see how that fold<br>
>> could be legal. I asked the same question on Phabricator but it seems you prefer<br>
>> to have the discussion here. Taking your example from there and adjusting it:<br>
>><br>
>> p = malloc(1)<br>
>> q = malloc(1)<br>
>> %c = icmp eq %p, %q<br>
>> free(q)<br>
>> free(p)<br>
>><br>
>> I think there is a guarantee that c will always be "false". Every operational<br>
>> model of allocation that I have ever seen will guarantee this, and the same for<br>
>> every program logic that I can imagine. So if the compiler may fold this to<br>
>> "false", then as far as I can see, pointer comparison becomes entirely<br>
>> unpredictable. The only consistent model I can think of is "icmp on pointers may<br>
>> spuriously return 'true' at any time", which I doubt anyone wants. ;)<br>
> In my understanding of<br>
> <a href="https://timsong-cpp.github.io/cppwp/n3337/expr.rel#2.2" rel="noreferrer noreferrer" target="_blank">https://timsong-cpp.github.io/cppwp/n3337/expr.rel#2.2</a> or<br>
> <a href="http://eel.is/c++draft/expr.rel#4.3" rel="noreferrer noreferrer" target="_blank">http://eel.is/c++draft/expr.rel#4.3</a> the result of this is unspecified.<br>
> While this does not necessarily extend to LLVM-IR, LLVM-IR usually<br>
> assumes C/C++ semantics unless defined otherwise.<br>
<br>
I also thought the above is fine.<br>
<br>
<br>
> Optimizations such as <a href="https://reviews.llvm.org/D53362" rel="noreferrer noreferrer" target="_blank">https://reviews.llvm.org/D53362</a> and<br>
> <a href="https://reviews.llvm.org/D65408" rel="noreferrer noreferrer" target="_blank">https://reviews.llvm.org/D65408</a> assume the equivalence of alloca and<br>
> malloc+free. I assume that such optimizations are the reason for this<br>
> unspecifiedness, i.e. I think someone might want this. Johannes's<br>
> proposal A1 however, seems to forbid StackColoring to exploit lifetime<br>
> markers, which it currently does and I am not sure we can afford to do<br>
> that.<br>
<br>
It's not that A1 "forbid[s] StackColoring to exploit lifetime markers", but<br>
A1 says that you cannot use lifetime markers to argue about the address. So<br>
you can still use them for reasoning but only as far as they tell you the<br>
content is undef. If you want to do coalescing, you need to verify more <br>
things,<br>
especially that the addresses are not (both) observed. If they are, <br>
which they<br>
can be with lifetime markers in place as well, you end up with <br>
inconsistent views.<br>
<br>
That said, if we want to preserve the property that you cannot access <br>
outside of<br>
lifetime ranges, you could "fix" StackColoring by simply verifying one <br>
of the two<br>
allocas is not escaping. You'd still need to fix InstCombine but the fix <br>
is the same.<br>
I'm not sure we want to declare accesses outside of lifetime ranges UB <br>
or not. I imagine<br>
in practice this makes little difference anyway, given that escaping <br>
uses are a problem<br>
on their own.<br>
<br>
~ Johannes<br>
<br>
<br>
> Michael<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" rel="noreferrer" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div></div></div>
</div>