<div dir="ltr"><div dir="ltr">If the integer casted from pointer is compared, GVN may introduce a problem:<div><br></div><div>int y[10];</div><div>int x[40];</div><div>intptr_t iy = (intptr_t)&y[0];</div><div>intptr_t ix = (intptr_t)&x[40];</div><div>int *x2 = (int*)ix;</div><div><br></div><div>if ((psub inbounds &x[40], x2) == 0) {</div><div>  if (ix == iy) {</div><div>    *(int *)iy = 100; // initially, this has no UB</div><div>    // => *(int *)ix = 100; // by ix == iy</div><div>    // => *x2 = 100; // by x2 == (int*)ix</div><div>    // => x[40] = 100; // by psub; raises UB</div><div>  }</div><div>}</div><div><br></div><div>In this example, the program initially has no UB, but after optimizations it raises UB.</div><div>psub should not replace x2 with x[40] here.</div><div><br></div><div>Juneyoung Lee</div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Jan 23, 2019 at 6:33 AM Sanjoy Das <<a href="mailto:sanjoy@playingwithpointers.com">sanjoy@playingwithpointers.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">On Tue, Jan 22, 2019 at 11:07 AM Juneyoung Lee<br>
<<a href="mailto:juneyoung.lee@sf.snu.ac.kr" target="_blank">juneyoung.lee@sf.snu.ac.kr</a>> wrote:<br>
> Ralf pointed out that psub cannot be used for propagating pointer equality if pointer-cast integer is involved;<br>
><br>
> a = p<br>
> b = inttoptr(ptrtoint p)<br>
> if ((psub inbounds a b) == 0) {<br>
> use(b) // replacing b with a may be problematic, as it is essentially folding inttoptr(ptrtoint p) -> p, which is discussed at <a href="https://bugs.llvm.org/show_bug.cgi?id=34548" rel="noreferrer" target="_blank">https://bugs.llvm.org/show_bug.cgi?id=34548</a><br>
> }<br>
><br>
> I'm sorry for the confusion. To propagate pointer equality, we certainly need a better solution. :\<br>
<br>
I don't immediately see the problem.  Firstly because we branch on<br>
(psub a b), a and b must have a common provenance.  If `a` is an<br>
interior pointer to this common allocation then we're fine.  So the<br>
only case where the psub will be == 0 and `a` will not be<br>
dereferenceable is if a points to one past the end of some allocation.<br>
<br>
The most obvious "full" example I can come up in this setting is:<br>
<br>
// Assume the stack layout is x followed by y<br>
int y[10];<br>
int x[40];<br>
int* a = &x[40]<br>
int* b = inttoptr(ptrtoint a)<br>
if ((psub inbounds a b) == 0) {<br>
  *b = 9; // Sets y[0] = 9<br>
}<br>
<br>
But this code is problematic for other reasons (so I think it has to<br>
be UB) -- if we allow assigning to y[0] like above then this breaks<br>
alias analysis on alloca's right? `y` above is not escaped, so we<br>
should be able to assume that nothing writes to it.<br>
<br>
-- Sanjoy<br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><br></div><font size="1">Juneyoung Lee</font><div><font size="1">Software Foundation Lab, Seoul National University</font></div></div></div>