[PATCH] D151644: [InstCombine] Propegating `nocapture` flag to callsites
Nikita Popov via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed May 31 11:43:07 PDT 2023
nikic added a comment.
In D151644#4384923 <https://reviews.llvm.org/D151644#4384923>, @goldstein.w.n wrote:
> Alright fair enough. I think this can only occur for allocas as any other type of store with no more may-write instructions would actually capture.
I'm not entirely confident on this, but I believe it can also happen with noalias returns, aka allocators. If you write the pointer into a malloc that gets leaked, I believe that would be non-capturing, as nobody has provenance to access the captured pointer anymore.
> I guess we also need to handle returns in a similiar way. You could do:
>
> > define i32 @test(ptr noalias nocapture %p) {
> > %p2 = call ptr @return_ptr(ptr %p)
> > %v = load i32, ptr %p2
> > ret i32 %v
> > }
>
> where `p2` captures and it would also be an alias analysis issue.
> So the rule needs to update.
> I don't think we need so go so far as "any load after makes it unsafe"
> although maybe that does need to be case. How about the following case:
>
>> define i32 @test(ptr noalias nocapture %p, ptr noalias nocapture %q) {
>> %a = alloca ptr
>> store ptr %a, ptr %q
>> call void @store_p_into_alloca_in_q(ptr %q, ptr %p)
>> %p3 = load ptr, ptr %q
>> %p2 = load ptr, ptr %p3
>> %v = load i32, ptr %p2
>> ret i32 %v
>> }
>
> so `%p` is stored into `%a` through `%q` that is obviously a capture, but does that
> violate the `nocapture` in `@test` or because the temporary pointer that capture
> `%p` is no longer accesible after `@test` is it safe?
I'd say this doesn't violate nocapture on `@test`, for the reason you state.
> I was also thinking something like:
>
> > define void @test(ptr noalias nocapture %p) {
> > %p_i64 = call ptr @return_ptr_as_i64(ptr %p)
> > %p2 = ptrtoint ptr %p to i64
> > %d = sub i64 %p_64, %p2
> > %unused = udiv i64 %n, %d
> > ret void
> > }
>
> Might be an issue as was thinking if `@return_ptr_as_i64` can't capture then the return
> value must != `%p` so the `udiv` is speculatable. But I think its safe to return random
> from a function that has a nocapture argument so its possible to get the exact bit pattern
> of the pointer, it just cant be derived from the pointer itself.
Right, I don't think we can do the speculation optimization. In fact, it might be that the address has already been captured prior to the call and `return_ptr_as_i64` returns it (neither nocapture nor noalias on the argument prevent this).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D151644/new/
https://reviews.llvm.org/D151644
More information about the llvm-commits
mailing list