Skip to content

Conversation

LegNeato
Copy link
Collaborator

@LegNeato LegNeato commented Sep 8, 2025

(T, U) pairs in entrypoints and regular functions are now supported.

(T, U) pairs in entrypoints and regular functions are now supported.

let elem0_ty = self.scalar_pair_element_backend_type(layout, 0, false);
let elem1_ty = self.scalar_pair_element_backend_type(layout, 1, false);

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eddyb I am not sure this section is right, can you review?

@Firestar99
Copy link
Member

I'll need this PR for #380, since removing our custom #[repr(SIMD)] will turn Vec2 into a ScalarPair and fail

@LegNeato
Copy link
Collaborator Author

That is fortuitous 🤯

let elem1_ty = self.scalar_pair_element_backend_type(layout, 1, false);

let base_ptr = value_ptr.unwrap();
let ptr1 = bx.inbounds_ptradd(base_ptr, self.const_usize(b_offset.bytes()));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why use inbounds_ptradd here, when it just forwards to inbounds_gep?

fn inbounds_ptradd(&mut self, ptr: Self::Value, offset: Self::Value) -> Self::Value {
    self.inbounds_gep(self.cx().type_i8(), ptr, &[offset])
}

I'm also not so sure you want the resulting type to implicitly be an i8?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is what I am not sure about, doing pointer arithmetic is bad and I was going to switch it to gep but wanted eddyb to chime in.

@nazar-pc
Copy link
Contributor

nazar-pc commented Sep 22, 2025

(T, U) pairs in entrypoints and regular functions are now supported.

Tuple layout is not guaranteed in Rust though. So at least for entrypoints I'd prefer for it to not be supported to avoid UB, forcing user to create an explicit #[repr(C)] struct with fields in desired order. For internal functions it is fine since compiler controls both the callee and caller.

In fact, any type that is not FFI-safe should generate at least compiler warning if not error, just like when you use extern "C" fn.

@LegNeato
Copy link
Collaborator Author

Yeah, I know the repr is not guaranteed in Rust but as you can see in the example we are pushing each piece and then aggregating as a pair on the device side. I guess that is UB though?

@nazar-pc
Copy link
Contributor

That is certainly not how I'd write in an actual host-side code, I'd simply cast #[repr(C)] array or slice to a slice of bytes instead.

If manually pushing bytes in correct order and adding an extra guarantee about tuple order on shader entrypoint then it might not be UB, but it feels unnatural in Rust.

@LegNeato
Copy link
Collaborator Author

Agreed, probably best to be safe and restrict them from entrypoints.

@Firestar99
Copy link
Member

This is a much more fundamental issue. You can pass structs through buffers that are #[repr(rust)] (the default repr), which also doesn't have any layout guarantees. So I'd suggest we merge this scalar abi patch as is, that by chance also enables tuples in entry points, and move this to a new issue.

let r_mix = 8u32 ^ 16u32 ^ 0.5f32.to_bits() ^ (-2.0f32).to_bits();
out[12] = p_mix;
out[13] = q_mix;
out[14] = r_mix;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this function is computing something very specific but I don't know what it is. A brief comment would be useful.

@nnethercote in https://github.com/Rust-GPU/rust-gpu/pull/380/files/8bdec822a9382c34c96031617a3ae37189621583#r2373605856

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

Successfully merging this pull request may close these issues.

3 participants