[LLVMdev] Indexed Load and Store Intrinsics - proposal

dag at cray.com dag at cray.com
Thu Dec 18 12:04:42 PST 2014

Nadav Rotem <nrotem at apple.com> writes:

> It looks like the proposed intrinsic is very specific to the x86
> implementation of gather/scatter. Would it be possible to remove the
> PassThrough value from the intrinsic and define the masked-out value
> to be undef? You would still be able to pattern match it if you use a
> maskedload + select. 

This makes sense to me.

> Can we remove the masked version of the intrinsic altogether and
> pattern match it using the non-masked version somehow?

I don't think that's possible.  The masking needs to be atomic with the
memory operation.  A non-masked memory operation could fault.  This:

vec = masked_gather(base, indices, mask)

is not semantically equivalent to 

vec1 = unmasked_gather(base, indices)
vec = select(mask, vec1, othervec)

The gather could fault.  It is not sufficient to pattern-match this
because some pass before isel could look at this code and assume the
gather doesn't fault, rearranging code in illegal ways.

> Can we infer the scale value based on the loaded element type?

No, I don't think we can do that.  Consider the case where Base is zero
and VectorOfIndices contains pointers.

[As an aside, LLVM does indeed have vector ptrtoint, so we could always
use that, though another intrinsic allowing vectors of pointers might be

I think requiring a multiply of the VectorOfIndices before the
gather/scatter is the most flexible course.
>     Semantics:
>     For i=0,1,…,N-1: if (Mask[i]) {VectorValue[i] = *(BaseAddr +
>     VectorOfIndices[i]*Scale) else VectorValue[i]=PassThruVal[i];}
>     void @llvm.sindex.store (BaseAddr, VectorValue, VectorOfIndices,
>     Scale)
>     void @llvm.uindex.store (BaseAddr, VectorValue, VectorOfIndices,
>     Scale)
>     void @llvm.sindex.masked.store (BaseAddr, VectorValue,
>     VectorOfIndices, Scale, Mask)
>     void @llvm.uindex.masked.store (BaseAddr, VectorValue,
>     VectorOfIndices, Scale, Mask)
>     Semantics:
>     For i=0,1,…,N-1: if (Mask[i]) {*(BaseAddr + VectorOfIndices
>     [i]*Scale) = VectorValue[i];}
>     VectorValue: any float or integer vector type.
> We should also support loading and storing pointer values. 

Yes, though ptrtoint could also be used here.

More information about the llvm-dev mailing list