Rust-GPU/rust-gpu

`count_ones()` fails to compile for numbers other than u32, i32

Closed this issue · 2 comments

Expected Behaviour

  • count_ones works for u32 and i32, but does not for u8, u16, u64, i8, i16 and i64.
  • (count_zeros just calls count_ones(!value))
  • reverse_bits also errors with cast errors

Example & Steps To Reproduce

// build-pass

use spirv_std::spirv;

#[spirv(fragment)]
pub fn main(#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] x: &mut [u32]) {
    x[0] = u8::count_ones(0x12);
    x[1] = u16::count_ones(0x12);
    x[2] = u32::count_ones(0x12); // u32 works
    x[3] = u64::count_ones(0x12);

    x[5] = i8::count_ones(0x12);
    x[6] = i16::count_ones(0x12);
    x[7] = i32::count_ones(0x12); // i32 works
    x[8] = i64::count_ones(0x12);
}
Error

error: cannot cast between pointer types
       from `*u32`
         to `*u8`
   --> /home/firestar99/.rustup/toolchains/nightly-2024-11-22-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/num/mod.rs:535:5
    |
535 | /     uint_impl! {
536 | |         Self = u8,
537 | |         ActualT = u8,
538 | |         SignedT = i8,
...   |
552 | |         bound_condition = "",
553 | |     }
    | |_____^
    |
note: used from within `<u8>::count_ones`
   --> /home/firestar99/.rustup/toolchains/nightly-2024-11-22-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/num/mod.rs:535:5
    |
535 | /     uint_impl! {
536 | |         Self = u8,
537 | |         ActualT = u8,
538 | |         SignedT = i8,
...   |
552 | |         bound_condition = "",
553 | |     }
    | |_____^
note: called by `issue_329::main`
   --> $DIR/issue-329.rs:7:12
    |
7   |     x[0] = u8::count_ones(0x12);
    |            ^^^^^^^^^^^^^^^^^^^^
note: called by `main`
   --> $DIR/issue-329.rs:6:8
    |
6   | pub fn main(#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] x: &mut [u32]) {
    |        ^^^^

error: cannot cast between pointer types
       from `*u32`
         to `*u16`
    --> /home/firestar99/.rustup/toolchains/nightly-2024-11-22-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/num/mod.rs:1151:5
     |
1151 | /     uint_impl! {
1152 | |         Self = u16,
1153 | |         ActualT = u16,
1154 | |         SignedT = i16,
...    |
1168 | |         bound_condition = "",
1169 | |     }
     | |_____^
     |
note: used from within `<u16>::count_ones`
    --> /home/firestar99/.rustup/toolchains/nightly-2024-11-22-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/num/mod.rs:1151:5
     |
1151 | /     uint_impl! {
1152 | |         Self = u16,
1153 | |         ActualT = u16,
1154 | |         SignedT = i16,
...    |
1168 | |         bound_condition = "",
1169 | |     }
     | |_____^
note: called by `issue_329::main`
    --> $DIR/issue-329.rs:8:12
     |
8    |     x[1] = u16::count_ones(0x12);
     |            ^^^^^^^^^^^^^^^^^^^^^
note: called by `main`
    --> $DIR/issue-329.rs:6:8
     |
6    | pub fn main(#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] x: &mut [u32]) {
     |        ^^^^

error: cannot cast between pointer types
       from `*u32`
         to `*u64`
    --> /home/firestar99/.rustup/toolchains/nightly-2024-11-22-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/num/mod.rs:1223:5
     |
1223 | /     uint_impl! {
1224 | |         Self = u64,
1225 | |         ActualT = u64,
1226 | |         SignedT = i64,
...    |
1240 | |         bound_condition = "",
1241 | |     }
     | |_____^
     |
note: used from within `<u64>::count_ones`
    --> /home/firestar99/.rustup/toolchains/nightly-2024-11-22-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/num/mod.rs:1223:5
     |
1223 | /     uint_impl! {
1224 | |         Self = u64,
1225 | |         ActualT = u64,
1226 | |         SignedT = i64,
...    |
1240 | |         bound_condition = "",
1241 | |     }
     | |_____^
note: called by `issue_329::main`
    --> $DIR/issue-329.rs:10:12
     |
10   |     x[3] = u64::count_ones(0x12);
     |            ^^^^^^^^^^^^^^^^^^^^^
note: called by `main`
    --> $DIR/issue-329.rs:6:8
     |
6    | pub fn main(#[spirv(descriptor_set = 0, binding = 0, storage_buffer)] x: &mut [u32]) {
     |        ^^^^

error: aborting due to 3 previous errors

System Info

Rust-gpu master 6e2c84d

new here, I was trying to debug this issue can anyone guide me if i am wrong.

Is this panic happening inside pointercast() due to this

// Defer the cast so that it has a chance to be avoided.
let original_ptr = ptr.def(self);

Isn't bitcast from rspirv should be able to handle this ?

I'm running into the same issue in #213 so I may as well try to fix it there. It's probably the intrinsic not matching the function signature exactly.