[RFC][Vector] Should vector.transfer_read/transfer_write indices be treated as unsigned/non-negative?

Thank you for pointing this out! Sorry, I should have been clearer in my follow-up.

Correct me if I’m missing something here, but 0 <= pos makes sense only under a signed interpretation, while pos <_u dim is equivalent to pos >=_s 0 && pos <_s dim (assuming 0 <= dim < 2^(bitwidth-1), which holds in practice (?)), where pos = idx + lane.

My view is that each index is a signed value, and that pos is the ordinary sum idx + lane of those signed values.[1]

Under this interpretation, 0xf1 is -15, so out-of-bounds. However, in your example memref<1024xf32> can’t be indexed by an 8-bit index, so the example can’t tell the two readings apart: with a 64-bit index is out-of-bounds under both interpretations. For the start index alone, they only differ when dim >= 2^(bitwidth-1), which is what the assumption above excludes.

Under the assumption, the start index itself is the same under both interpretations (8-bit indices, dim = 127):

idx signed unsigned in-bounds if signed (0 <= idx < 127) in-bounds if unsigned (idx < 127)
0x00 0 0 yes yes
0x03 3 3 yes yes
0x7f 127 127 no no
0x80 -128 128 no no
0xfe -2 254 no no
0xff -1 255 no no

The sum, however, is not the same. With 8-bit indices, idx = 0xfe and lane = 2: read as signed, -2 + 2 = 0 (in-bounds); read as unsigned, 254 + 2 = 256 (out-of-bounds).

With this interpretation, the ugt on base + IV implements the signed reading, right?
In general, does that seem reasonable to you? :thinking:


To summarize my POV:

  1. Are the indices of transfer_read/transfer_write signed or unsigned?
    Signed, and pos is the ordinary sum idx + lane of those signed values.
  2. Is it correct to assume 0 <= dim < 2^(bitwidth-1)?
    MLIR’s integer range inference already assumes it. So why not?
  3. sgtugt, or a second >= 0 check?
    Given 1 and 2, the two are equivalent.

That said, I’m more than happy to leave a more detailed take on these points, and the final wording, to the more expert folks here :smiley:


  1. This also seems consistent with the rest of the stack: LLVM’s getelementptr treats indices as signed values, and memref.load eventually lowers to one. memref.load and tensor.extract don’t explicitly state the signedness either, so perhaps the same clarification is needed there as well. ↩︎