Juneyoung Lee via llvm-dev
2019-Jan-18 07:57 UTC
[llvm-dev] Reducing the number of ptrtoint/inttoptrs that are generated by LLVM
Hello Sanjoy,
Yep, combining it with propagateEquality of pointers may raise problem. :\
However I believe propagateEquality should be fixed properly, and adding
psub also suggests a solution for that. :)
It is sound to replace a pointer with another if subtraction of them is 0:
a = malloc()
free(a)
b = malloc() // Assume b == a numerically
if ((psub inbounds a b) == 0) { // a and b are pointing to different
objects, so the comparison becomes poison
use(a)
}
=>
a = malloc()
free(a)
b = malloc() // Assume b == a numerically
if ((psub inbounds a b) == 0) {
use(b)
}
Juneyoung Lee
On Fri, Jan 18, 2019 at 7:50 AM Sanjoy Das <sanjoy at
playingwithpointers.com>
wrote:
> On Mon, Jan 14, 2019 at 3:23 AM Juneyoung Lee via llvm-dev
> <llvm-dev at lists.llvm.org> wrote:
> > Patch https://reviews.llvm.org/D56598 adds llvm.psub(p1,p2) intrinsic
> function, which subtracts two pointers and returns the difference. Its
> semantic is as follows.
> >
> > If p1 and p2 point to different objects, and neither of them is based
on
> a pointer casted from an integer, `llvm.psub(p1, p2)` returns poison. For
> example,
>
> Are you proposing landing this in conjunction with some of the other
> stuff discussed in the twin allocation paper? Otherwise isn't this
> problematic with propagateEquality of pointers?
>
> a = malloc()
> free(a)
> b = malloc() // Assume b == a numerically
> if (a == b) {
> print(psub(b, b)) // prints 0
> }
>
> =>
>
> a = malloc()
> free(a)
> b = malloc() // Assume b == a numerically
> if (a == b) {
> print(psub(a, b)) // prints poison
> }
>
> Though I admit propagateEquality of pointers has many other problems like
> this.
>
>
> -- Sanjoy
>
--
Juneyoung Lee
Software Foundation Lab, Seoul National University
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20190118/8acf5329/attachment.html>
Juneyoung Lee via llvm-dev
2019-Jan-22 19:07 UTC
[llvm-dev] Reducing the number of ptrtoint/inttoptrs that are generated by LLVM
Ralf pointed out that psub cannot be used for propagating pointer equality
if pointer-cast integer is involved;
a = p
b = inttoptr(ptrtoint p)
if ((psub inbounds a b) == 0) {
use(b) // replacing b with a may be problematic, as it is essentially
folding inttoptr(ptrtoint p) -> p, which is discussed at
https://bugs.llvm.org/show_bug.cgi?id=34548
}
I'm sorry for the confusion. To propagate pointer equality, we certainly
need a better solution. :\
Juneyoung Lee
On Fri, Jan 18, 2019 at 4:57 PM Juneyoung Lee <juneyoung.lee at
sf.snu.ac.kr>
wrote:
> Hello Sanjoy,
>
> Yep, combining it with propagateEquality of pointers may raise problem. :\
>
> However I believe propagateEquality should be fixed properly, and adding
> psub also suggests a solution for that. :)
>
> It is sound to replace a pointer with another if subtraction of them is 0:
>
> a = malloc()
> free(a)
> b = malloc() // Assume b == a numerically
> if ((psub inbounds a b) == 0) { // a and b are pointing to different
> objects, so the comparison becomes poison
> use(a)
> }
>
> =>
>
> a = malloc()
> free(a)
> b = malloc() // Assume b == a numerically
> if ((psub inbounds a b) == 0) {
> use(b)
> }
>
> Juneyoung Lee
>
> On Fri, Jan 18, 2019 at 7:50 AM Sanjoy Das <sanjoy at
playingwithpointers.com>
> wrote:
>
>> On Mon, Jan 14, 2019 at 3:23 AM Juneyoung Lee via llvm-dev
>> <llvm-dev at lists.llvm.org> wrote:
>> > Patch https://reviews.llvm.org/D56598 adds llvm.psub(p1,p2)
intrinsic
>> function, which subtracts two pointers and returns the difference. Its
>> semantic is as follows.
>> >
>> > If p1 and p2 point to different objects, and neither of them is
based
>> on a pointer casted from an integer, `llvm.psub(p1, p2)` returns
poison.
>> For example,
>>
>> Are you proposing landing this in conjunction with some of the other
>> stuff discussed in the twin allocation paper? Otherwise isn't this
>> problematic with propagateEquality of pointers?
>>
>> a = malloc()
>> free(a)
>> b = malloc() // Assume b == a numerically
>> if (a == b) {
>> print(psub(b, b)) // prints 0
>> }
>>
>> =>
>>
>> a = malloc()
>> free(a)
>> b = malloc() // Assume b == a numerically
>> if (a == b) {
>> print(psub(a, b)) // prints poison
>> }
>>
>> Though I admit propagateEquality of pointers has many other problems
like
>> this.
>>
>>
>> -- Sanjoy
>>
>
>
> --
>
> Juneyoung Lee
> Software Foundation Lab, Seoul National University
>
--
Juneyoung Lee
Software Foundation Lab, Seoul National University
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20190123/a2c258ec/attachment.html>
Sanjoy Das via llvm-dev
2019-Jan-22 21:32 UTC
[llvm-dev] Reducing the number of ptrtoint/inttoptrs that are generated by LLVM
On Tue, Jan 22, 2019 at 11:07 AM Juneyoung Lee <juneyoung.lee at sf.snu.ac.kr> wrote:> Ralf pointed out that psub cannot be used for propagating pointer equality if pointer-cast integer is involved; > > a = p > b = inttoptr(ptrtoint p) > if ((psub inbounds a b) == 0) { > use(b) // replacing b with a may be problematic, as it is essentially folding inttoptr(ptrtoint p) -> p, which is discussed at https://bugs.llvm.org/show_bug.cgi?id=34548 > } > > I'm sorry for the confusion. To propagate pointer equality, we certainly need a better solution. :\I don't immediately see the problem. Firstly because we branch on (psub a b), a and b must have a common provenance. If `a` is an interior pointer to this common allocation then we're fine. So the only case where the psub will be == 0 and `a` will not be dereferenceable is if a points to one past the end of some allocation. The most obvious "full" example I can come up in this setting is: // Assume the stack layout is x followed by y int y[10]; int x[40]; int* a = &x[40] int* b = inttoptr(ptrtoint a) if ((psub inbounds a b) == 0) { *b = 9; // Sets y[0] = 9 } But this code is problematic for other reasons (so I think it has to be UB) -- if we allow assigning to y[0] like above then this breaks alias analysis on alloca's right? `y` above is not escaped, so we should be able to assume that nothing writes to it. -- Sanjoy