[PATCH] [SCCP] Calculate Null Pointer Comparisons
Sanjoy Das
sanjoy at playingwithpointers.com
Mon May 11 11:02:00 PDT 2015
LLVM currently turns non-postdominating inbounds GEPS to
postdominating GEPS. For instance, opt -O3 will transform
define i8* @test_postdominate_2(i8* %mem, i1 %cond) {
entry:
br i1 %cond, label %left, label %right
left:
%tL = getelementptr inbounds i8, i8* %mem, i32 42
br label %merge
right:
br label %merge
merge:
%m = phi i8* [ %tL, %left ], [ null, %right ]
ret i8* %m
}
to
define i8* @test_postdominate_2(i8* readnone %mem, i1 %cond) #0 {
entry:
%tL = getelementptr inbounds i8, i8* %mem, i64 42
%m = select i1 %cond, i8* %tL, i8* null
ret i8* %m
}
attributes #0 = { nounwind readnone }
So we can go from "%tL does not postdominate X" to "%tL postdominates
X" via -O3.
IOW, if we want to rely on control dependence on inbounds GEPs then
llvm::isSafeToSpeculativelyExecute will have to return false for
inbounds GEPs. I don't think control dependence on an instruction
that may be freely moved around means anything.
-- Sanjoy
On Mon, May 11, 2015 at 10:49 AM, Daniel Berlin <dberlin at dberlin.org> wrote:
> On Mon, May 11, 2015 at 10:41 AM, Sanjoy Das
> <sanjoy at playingwithpointers.com> wrote:
>> I'm not sure that this is doing the right thing -- I don't think simply //producing// `undef` implies undefined behavior.
>
> I asked David/Nick (the two closest experts i had), and they both
> agreed that if a null check is postdominated by an inbounds GEP, it's
> fair to say the null check always comes out as "not null"
>
>>
>> For instance, in
>>
>> declare void @g()
>>
>> define i1 @test_postdominate(i8* %mem) {
>> %test = icmp eq i8* %mem, null
>> br i1 %test, label %a, label %b
>> a:
>> call void @g()
>> br label %c
>> b:
>> br label %c
>> c:
>> %join = phi i8* [ %mem, %a ], [ null, %b ]
>> %gep = getelementptr inbounds i8, i8* %join, i64 4
>> ret i1 %test
>> }
>>
>> if `%mem` is `null`, then we have to execute the call to `@g`, but this pass make the branch into `a` dead (so `@f` never calls `@g`).
>
> This is correct, as far as my experts told me.
>
>> The fact that `%gep` is `undef` (or poison) does not make this program undefined.
>> In fact, if `inbounds` GEP instructions could invoke UB, then we would not be able to hoist such instructions out of loops.
>
>
> I leave this disagreement to experts that are not me :)
>
> Note that we use exactly the same line of implication to propagate
> nsw/etc onto operands of inbounds geps (and the language ref
> explicitly says this is okay :P)
More information about the llvm-commits
mailing list