Is copy.0 semantically equivalent to copy.1 in the following example? define void @copy.0(i8 addrspace(1)* addrspace(1)* %src, i8 addrspace(1)* addrspace(1)* %dst) { entry: %val = load i8 addrspace(1)* addrspace(1)* %src store i8 addrspace(1)* %val, i8 addrspace(1)* addrspace(1)* %dst ret void } define void @copy.1(i8 addrspace(1)* addrspace(1)* %src, i8 addrspace(1)* addrspace(1)* %dst) { entry: %src.cast = bitcast i8 addrspace(1)* addrspace(1)* %src to i8* addrspace(1)* %dst.cast = bitcast i8 addrspace(1)* addrspace(1)* %dst to i8* addrspace(1)* %val = load i8* addrspace(1)* %src.cast store i8* %val, i8* addrspace(1)* %dst.cast ret void } -- Sanjoy
Partially answering my own question, in general these are not equivalent because LLVM allows for pointers in different address spaces to have different sizes. However, are they equivalent if pointers in addrspace(1) have the same size as pointers in addrspace(0)? In other words, assuming pointers have the same size irrespective of address spaces, is storing / loading an (not storing into / loading from) addrspace(1)* allowed to do something semantically different than storing / loading an addrspace(0)*? Thanks, -- Sanjoy On Thu, Dec 4, 2014 at 10:09 PM, Sanjoy Das <sanjoy at playingwithpointers.com> wrote:> Is copy.0 semantically equivalent to copy.1 in the following example? > > define void @copy.0(i8 addrspace(1)* addrspace(1)* %src, i8 > addrspace(1)* addrspace(1)* %dst) { > entry: > %val = load i8 addrspace(1)* addrspace(1)* %src > store i8 addrspace(1)* %val, i8 addrspace(1)* addrspace(1)* %dst > ret void > } > > define void @copy.1(i8 addrspace(1)* addrspace(1)* %src, i8 > addrspace(1)* addrspace(1)* %dst) { > entry: > %src.cast = bitcast i8 addrspace(1)* addrspace(1)* %src to i8* addrspace(1)* > %dst.cast = bitcast i8 addrspace(1)* addrspace(1)* %dst to i8* addrspace(1)* > > %val = load i8* addrspace(1)* %src.cast > store i8* %val, i8* addrspace(1)* %dst.cast > ret void > } > > -- Sanjoy
> On Dec 8, 2014, at 5:12 PM, Sanjoy Das <sanjoy at playingwithpointers.com> wrote: > > Partially answering my own question, in general these are not > equivalent because LLVM allows for pointers in different address > spaces to have different sizes. However, are they equivalent if > pointers in addrspace(1) have the same size as pointers in > addrspace(0)? > > In other words, assuming pointers have the same size irrespective of > address spaces, is storing / loading an (not storing into / loading > from) addrspace(1)* allowed to do something semantically different > than storing / loading an addrspace(0)*?It is yeah. For example, this code is in InstCombine where we assume that loading null is undefined, but only for addrspace(0). Whether other address spaces trap or give undefined behaviour on loading null is target dependent. Thanks, Pete // load(gep null, ...) -> unreachable if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(Op)) { const Value *GEPI0 = GEPI->getOperand(0); // TODO: Consider a target hook for valid address spaces for this xform. if (isa<ConstantPointerNull>(GEPI0) && GEPI->getPointerAddressSpace() == 0){ // Insert a new store to null instruction before the load to indicate // that this code is not reachable. We do this instead of inserting // an unreachable instruction directly because we cannot modify the // CFG. new StoreInst(UndefValue::get(LI.getType()), Constant::getNullValue(Op->getType()), &LI); return ReplaceInstUsesWith(LI, UndefValue::get(LI.getType())); } }> > Thanks, > -- Sanjoy > > On Thu, Dec 4, 2014 at 10:09 PM, Sanjoy Das > <sanjoy at playingwithpointers.com> wrote: >> Is copy.0 semantically equivalent to copy.1 in the following example? >> >> define void @copy.0(i8 addrspace(1)* addrspace(1)* %src, i8 >> addrspace(1)* addrspace(1)* %dst) { >> entry: >> %val = load i8 addrspace(1)* addrspace(1)* %src >> store i8 addrspace(1)* %val, i8 addrspace(1)* addrspace(1)* %dst >> ret void >> } >> >> define void @copy.1(i8 addrspace(1)* addrspace(1)* %src, i8 >> addrspace(1)* addrspace(1)* %dst) { >> entry: >> %src.cast = bitcast i8 addrspace(1)* addrspace(1)* %src to i8* addrspace(1)* >> %dst.cast = bitcast i8 addrspace(1)* addrspace(1)* %dst to i8* addrspace(1)* >> >> %val = load i8* addrspace(1)* %src.cast >> store i8* %val, i8* addrspace(1)* %dst.cast >> ret void >> } >> >> -- Sanjoy > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20141208/d77b4cbe/attachment.html>
Rafael EspĂndola
2014-Dec-09 01:35 UTC
[LLVMdev] Question on equivalence of pointer types
I think so. My understanding is that address spaces can model things like segmented memory or address regions that need special instructions. On 8 December 2014 at 20:12, Sanjoy Das <sanjoy at playingwithpointers.com> wrote:> Partially answering my own question, in general these are not > equivalent because LLVM allows for pointers in different address > spaces to have different sizes. However, are they equivalent if > pointers in addrspace(1) have the same size as pointers in > addrspace(0)? > > In other words, assuming pointers have the same size irrespective of > address spaces, is storing / loading an (not storing into / loading > from) addrspace(1)* allowed to do something semantically different > than storing / loading an addrspace(0)*? > > Thanks, > -- Sanjoy > > On Thu, Dec 4, 2014 at 10:09 PM, Sanjoy Das > <sanjoy at playingwithpointers.com> wrote: >> Is copy.0 semantically equivalent to copy.1 in the following example? >> >> define void @copy.0(i8 addrspace(1)* addrspace(1)* %src, i8 >> addrspace(1)* addrspace(1)* %dst) { >> entry: >> %val = load i8 addrspace(1)* addrspace(1)* %src >> store i8 addrspace(1)* %val, i8 addrspace(1)* addrspace(1)* %dst >> ret void >> } >> >> define void @copy.1(i8 addrspace(1)* addrspace(1)* %src, i8 >> addrspace(1)* addrspace(1)* %dst) { >> entry: >> %src.cast = bitcast i8 addrspace(1)* addrspace(1)* %src to i8* addrspace(1)* >> %dst.cast = bitcast i8 addrspace(1)* addrspace(1)* %dst to i8* addrspace(1)* >> >> %val = load i8* addrspace(1)* %src.cast >> store i8* %val, i8* addrspace(1)* %dst.cast >> ret void >> } >> >> -- Sanjoy > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev