On 17 Mar 2015, at 20:06, Junjie Gu <jgu222 at gmail.com> wrote:
>> I've just been debugging a related issue with regard to
commutativity of address space casts with respect to other operations. One of
the optimisers is turning an add after an address space cast into an add before
the address space cast. On our architecture, this results in different bounds
information being available on the pointer and a run-time crash. We could
represent casts with a target-specific intrinsic, but we'd rather avoid that
if possible. This is not fixed by changing isSafeToSpeculativelyExecute to
return false for AddrSpaceCast, so I'll need to dig a bit more to understand
exactly when and why it happens.
>
> Like to know what is causing this.
I should start with a disclaimer that I haven't pulled in upstream LLVM for
a couple of months, so this might already be fixed...
After SROA, we're left with this:
; Function Attrs: nounwind
define i32 @main() #0 {
entry:
%call = call i8* @malloc(i64 zeroext 168)
%0 = bitcast i8* %call to i32*
%1 = addrspacecast i32* %0 to i32 addrspace(200)*
call void @set(i32 addrspace(200)* %1)
%add.ptr = getelementptr inbounds i32 addrspace(200)* %1, i64 41
call void @test(i32 addrspace(200)* %add.ptr)
ret i32 0
}
This is correct and semantically valid for our architecture. The cast to AS200
is creating a fat pointer with base and bounds information, the GEP is
constructing a new fat pointer with the same base and bounds but a different
offset within the object. This survives for a bit, but then:
*** IR Dump After Combine redundant instructions ***
; Function Attrs: nounwind
define i32 @main() #0 {
entry:
%call = call i8* @malloc(i64 zeroext 168) #2
%0 = bitcast i8* %call to i32*
%1 = addrspacecast i32* %0 to i32 addrspace(200)*
call void @set(i32 addrspace(200)* %1) #2
%add.ptr = getelementptr inbounds i8* %call, i64 164
%2 = bitcast i8* %add.ptr to i32*
%3 = addrspacecast i32* %2 to i32 addrspace(200)*
call void @test(i32 addrspace(200)* %3) #2
ret i32 0
}
So it looks as if InstCombine is deciding that it can hoist the GEP above the
addrspacecast. Unfortunately, narrowing it down to InstCombine doesn't
actually narrow it down very much - I'll keep looking...
David