[LLVMdev] Question on equivalence of pointer types
Sanjoy Das
sanjoy at playingwithpointers.com
Mon Dec 8 18:12:48 PST 2014
In the example that you gave, the difference is between
load i32 addrspace(0)* null
and
load i32 addrspace(1)* null
(that the first one is UB, while the second one may be well-defined).
But my question is different, it is that are the following two different:
load i32 addrspace(0)* addrspace(0)* %p0
load i32 addrspace(1)* addrspace(0)* %p1
if %p0 == %p1 (because they're bitcasts of each other or something --
note that you don't need an addrspacecast to go from "i32
addrspace(1)* addrspace(0)*" to "i32 addrspace(0)* addrspace(0)*").
They are different in the type system because one of them produces an
"i32 addrspace(0)*" while the other produces an "i32 addrspace(1)*",
so in general they cannot be substituted by each other, but there are
edge cases as in the example I started this thread with.
In other words: the semantics of a load or store depend on the address
space of the pointer operand. But in case the *value* we're storing
is also a pointer, does the semantics depend on the value's address
space to?
I suspect the answer is no, but I may be missing something here and
wish to confirm.
-- Sanjoy
On Mon, Dec 8, 2014 at 5:33 PM, Pete Cooper <peter_cooper at apple.com> wrote:
>
> 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
>
>
More information about the llvm-dev
mailing list