Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

should compiler update vl after typecast? #53

Closed
xingmingjie opened this issue Dec 9, 2020 · 6 comments
Closed

should compiler update vl after typecast? #53

xingmingjie opened this issue Dec 9, 2020 · 6 comments

Comments

@xingmingjie
Copy link
Contributor

For an example:

#include <riscv_vector.h>

unsigned short x[8] = {1, 2, 3, 4, 5, 6, 7, 8};
unsigned char y[16];

void foo() {
  vsetvl_e16m1(8); 
  vuint16m1_t vx = vle16_v_u16m1(x);
  vuint8m1_t vy = vreinterpret_v_u16m1_u8m1(vx);
  // vsetvl_e8m1(16); // should compiler update vl correctly? 
  vse8_v_u8m1(y, vy);
}

When cast from vuint16m1_t to vuint8m1_t, the element length also changes from 8 to 16. So should compiler update vl, or do it manually?

@kito-cheng
Copy link
Collaborator

When cast from vuint16m1_t to vuint8m1_t, the element length also changes from 8 to 16. So should compiler update vl, or do it manually?

No, compiler won't automatically change vl, the compiler only insert vsetvli x0, x0, e8, m1 to make sure vtype is correct (and without changing vl) before the operation.

But it's an interesting question if the vl is unchanged, it should work as expect at vector v0.9, but it will got an illegal-instruction exception, so I will suggest you should add vsetvl_e8m1(16);

https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#61-vsetvlivsetvl-instructions

...
Use of the instruction with a new SEW/LMUL ratio that would result in a
change of VLMAX is reserved. Implementations may set vill in this case.
...

See more discussion for this issue:
#52

@xingmingjie
Copy link
Contributor Author

So I think this can be taken as a narrowing type cast, thus the vector value will be truncated. The following test can show the result.

#include <stdio.h>
#include <riscv_vector.h>

unsigned short x[8] = {1, 2, 3, 4, 5, 6, 7, 8};
unsigned char y[16];

int main() {
  vsetvl_e16m1(8);
  vuint16m1_t vx = vle16_v_u16m1(x);
  vuint8m1_t vy = (vuint8m1_t)vx; // The vector value will be truncated.
  vsetvl_e8m1(16); // Even though specify the vl to 16, ...
  vse8_v_u8m1(y, vy); // ... the last 8 elements is undefined.

  for (int i = 0; i < 16; ++i) {
    printf("y[%d]=%d; ", i, y[i]);
  }
  printf("\n");
}

@nick-knight
Copy link
Collaborator

nick-knight commented Dec 10, 2020

I was under the impression that we hadn't yet defined the cast operator (type) expression for the new types defined by the RVV C dialect: #13 (comment)

@kito-cheng
Copy link
Collaborator

I was under the impression that we hadn't yet defined the cast operator (type) expression for the new types defined by the RVV C dialect: #13 (comment)

I guess just because we didn't fully check and forbid that on our GCC implementation, so there is some default one? but I think we should forbid that before we have consensus/conclusion.

@kito-cheng
Copy link
Collaborator

So I think this can be taken as a narrowing type cast, thus the vector value will be truncated. The following test can show the result.

Hmmm, I think we don't have well-define that behavior for such C casting operator, so I would suggest you using explicit intrinsic to do like vreinterpreter or vncvt.x.x.w.

@zakk0610
Copy link
Collaborator

For an example:

#include <riscv_vector.h>

unsigned short x[8] = {1, 2, 3, 4, 5, 6, 7, 8};
unsigned char y[16];

void foo() {
  vsetvl_e16m1(8); 
  vuint16m1_t vx = vle16_v_u16m1(x);
  vuint8m1_t vy = vreinterpret_v_u16m1_u8m1(vx);
  // vsetvl_e8m1(16); // should compiler update vl correctly? 
  vse8_v_u8m1(y, vy);
}

When cast from vuint16m1_t to vuint8m1_t, the element length also changes from 8 to 16. So should compiler update vl, or do it manually?

Users need to do it manually, see https://github.com/riscv/rvv-intrinsic-doc/blob/master/rvv-intrinsic-api.md#reinterpret-cast-conversion-functions
Reinterpret the contents of a data as a different type, without changing any bits and generating any RVV instructions.

You could also found reinterpret api does not have vl argument in the explicitly vl document.
https://github.com/riscv/rvv-intrinsic-doc/blob/master/rvv_intrinsic_funcs_vl/12_miscellaneous_vector_functions.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants