On 16 Mar 2015, at 08:25, Sanjoy Das <sanjoy at playingwithpointers.com> wrote:> > The LangRef says this about addrspacecast: "Note that if the address > space conversion is legal then both result and operand refer to the > same memory location.". This brings forth two related questions: > > 1. what happens if you execute an "invalid" addrspacecast? Does this > axiom make addrspacecast non-hoistable? From a quick glance at > the code, ValueTracking seems to assume that addrspacecasts can be > speculatively executed. > > 2. even if two pointers from two different address spaces point to > the same "location", can one of them not be dereferenceable while > the other is? In other words, does dereferenceability depend on > the addrspace of the pointer given that the "location" is > dereferenceable?In our architecture, address space casts will never trap and are deterministic (unless there is some asm with unmodelled side effects). However, there are pointers that can be dereferenced in one address space but not another: speculatively performing the load would be a real bug. Ideally, this would be a target-specific decision, but having the default be to not propagate the dereferencing information and allowing targets to opt in. 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. I think there's a lot of code that still assumes that address space casts are basically bitcasts. David
> > In our architecture, address space casts will never trap and are > deterministic (unless there is some asm with unmodelled side effects). > However, there are pointers that can be dereferenced in one address space > but not another: speculatively performing the load would be a real bug. > > Ideally, this would be a target-specific decision, but having the default > be to not propagate the dereferencing information and allowing targets to > opt in. >Yes.> > 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.Thanks Junjie -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150317/db9d0244/attachment.html>
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
Maybe Matching Threads
- [LLVMdev] possible addrspacecast problem
- [LLVMdev] possible addrspacecast problem
- [InstCombine] Addrspacecast and GEP assumed commutative
- [LLVMdev] Any Optimization Suggestion to Get Rid of AddrSpaceCast around PHI
- [LLVMdev] Reducing Generic Address Space Usage