Masked intrinsics and non-default address spaces

Masked load/store are overloaded intrinsics, the only generic type is the type of the value being loaded/stored. The signature of the intrinsic is generated based on this type. The type of the pointer argument is generated as a pointer to the return type with default addrspace. E.g.:

declare <8 x i32> @llvm.masked.load.v8i32(<8 x i32>*, i32, <8 x i1>, <8 x i32>)

The problem occurs when loop-vectorize tries to use @llvm.masked.load/store intrinsic for a non-default addrspace pointer. It fails with “Calling a function with a bad signature!” assertion in CallInst constructor because it tries to pass a non-default addrspace pointer to the pointer argument which has default addrspace.

My proposal to fix the problem is to add another overloaded type parameter for the intrinsics - the pointer type, which can be any pointer with underlying type being a data type. In this case the signature of the intrinsic above would be:

declare <8 x i32> @llvm.masked.load.v8i32.p1v8i32(<8 x i32> addrspace(1)*, i32, <8 x i1>, <8 x i32>)

Corresponding patch is posted on phabricator: http://reviews.llvm.org/D17270

Any comments, objections or alternatives?

Artur

+1. I don’t particularly care about this set of intrinsics, but there are a handful of other memory intrinsics that currently suffer from the same problem of being arbitrarily restricted to addrspace(0). -Matt

How would the “typeless” pointer interact with this? Would the problem be solved?
(just curious)

From: "Mehdi Amini via llvm-dev" <llvm-dev@lists.llvm.org>
To: "Artur Pilipenko" <apilipenko@azulsystems.com>
Cc: "llvm-dev" <llvm-dev@lists.llvm.org>
Sent: Monday, February 15, 2016 2:55:30 PM
Subject: Re: [llvm-dev] Masked intrinsics and non-default address
spaces

> Masked load/store are overloaded intrinsics, the only generic type
> is
> the type of the value being loaded/stored. The signature of the
> intrinsic is generated based on this type. The type of the pointer
> argument is generated as a pointer to the return type with default
> addrspace. E.g.:

> declare <8 x i32> @llvm.masked.load.v8i32(<8 x i32>*, i32, <8 x
> i1>,
> <8 x i32>)

How would the "typeless" pointer interact with this? Would the
problem be solved?
(just curious)

I'm under the impression that even typeless pointers will still have address spaces. Assuming I'm right about that, the proposed fix here makes sense to me.

-Hal

I don’t think you need to change the signatures to get what you want.

The current definition is:
def int_masked_store : Intrinsic<, [llvm_anyvector_ty, LLVMPointerTo<0>,
llvm_i32_ty,
LLVMVectorSameWidth<0, llvm_i1_ty>],
[IntrReadWriteArgMem]>;

If I’m remembering my Intrinsics.td syntax correctly, you can simply change this to:
def int_masked_store : Intrinsic<, [llvm_anyvector_ty, llvm_anyptr_ty,
llvm_i32_ty,
LLVMVectorSameWidth<0, llvm_i1_ty>],
[IntrReadWriteArgMem]>;

Philip

And… ignore me. I clearly hadn’t read your email closely enough. This is exactly what you were doing.

Philip