[LLVMdev] Semantics of an Inbounds GetElementPtr
Philip Reames
listmail at philipreames.com
Tue May 12 13:45:29 PDT 2015
I think this got settled on the review, but inferring anything about
reachability from just a gep is wrong. You can (and we do), infer that
a *dereference* of a null pointer implies the path is unreachable, but
merely doing address computation with a null pointer is entirely
legitimate and common.
Going back to the original example:
define i8 @func(i8* %mem) {
%test = icmp eq i8* %mem, null
br i1 %test, label %done, label %mem.is.valid
mem.is.valid:
%1 = getelementptr inbounds i8, i8* %mem, i64 4
store i8 5, i8* %1, align 4
br label %done
done:
%after.phi = phi i8* [ %mem, %mem.is.valid ], [ null, %0 ]
%2 = getelementptr inbounds i8, i8* %after.phi, i64 4
%five = load i8, i8* %2, align 4
ret i8 %five
}
From "%five = load i8, i8* %2, align 4", we can infer that the edge
entry->done is never taken. Doing so would result in the unconditional
dereference of a null pointer. This would give us:
define i8 @func(i8* %mem) {
br label %mem.is.valid
mem.is.valid:
%1 = getelementptr inbounds i8, i8* %mem, i64 4
store i8 5, i8* %1, align 4
br label %done
done:
%2 = getelementptr inbounds i8, i8* %mem, i64 4
%five = load i8, i8* %2, align 4
ret i8 %five
}
After store-load forwarding and combining basic blocks, we'd have:
define i8 @func(i8* %mem) {
%1 = getelementptr inbounds i8, i8* %mem, i64 4
store i8 5, i8* %1, align 4
ret i8 5
}
That's as far as we can optimize that.
Well, not quite. We can infer that the argument must be non-null, which
can propagate the facts to the caller and allow simplifications there as
well. (I don't believe we currently do that, but we could.)
p.s. I haven't been really following this thread. If I've miss
something by jumping in late, feel free to correct me.
Philip
On 05/11/2015 08:07 AM, Daniel Berlin wrote:
> +Philip
> Looks pretty good. As i just said on the review, it would be really
> nice to know how often this triggers.
>
> Philip may be interested too, if they don't already have a null check
> removal pass of their own :)
>
>
> On Sat, May 9, 2015 at 6:35 AM, Nicholas White <n.j.white at gmail.com> wrote:
>> Thanks - that was very interesting. I've had a go at implementing it
>> here - http://reviews.llvm.org/D9634 - as an improvement to the SCCP
>> pass. It seems to work (see the test cases), but I had to make a few
>> compromises (making PtrUseVisitor look through phi nodes, only working
>> on CmpInst.isEquality() instructions, and making the SCCP pass
>> dependent on the PostDominatorTree pass). I think it's O(n);
>> PtrUseVisitor scans each Use at most once, and PostDominatorTree seems
>> linear in the number of predecessor blocks. It was easier to implement
>> by starting at a ptr-vs-null-checking CmpInst and analysing the code
>> forwards rather than by starting at an inbounds GEP instruction and
>> analysing the code backwards. What do you think?
>>
>> Thanks -
>>
>> Nick
More information about the llvm-dev
mailing list