diff --git a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs index d86db1cbd00..1bea4fedfe7 100644 --- a/crates/rustc_codegen_spirv/src/builder/builder_methods.rs +++ b/crates/rustc_codegen_spirv/src/builder/builder_methods.rs @@ -308,6 +308,11 @@ fn memset_fill_u64(b: u8) -> u64 { | ((b as u64) << 56) } +fn memset_fill_u128(b: u8) -> u128 { + let b64 = memset_fill_u64(b) as u128; + b64 | b64 >> 64 +} + fn memset_dynamic_scalar( builder: &mut Builder<'_, '_>, fill_var: Word, @@ -387,6 +392,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { 64 => self .constant_u64(self.span(), memset_fill_u64(fill_byte)) .def(self), + 128 => self + .constant_u128(self.span(), memset_fill_u128(fill_byte)) + .def(self), _ => self.fatal(format!( "memset on integer width {width} not implemented yet" )), @@ -402,6 +410,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { 64 => self .constant_i64(self.span(), memset_fill_u64(fill_byte) as i64) .def(self), + 128 => self + .constant_u128(self.span(), memset_fill_u128(fill_byte)) + .def(self), _ => self.fatal(format!( "memset on integer width {width} not implemented yet" )), diff --git a/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs b/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs index bf874130e83..6df6993419d 100644 --- a/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs +++ b/crates/rustc_codegen_spirv/src/codegen_cx/constant.rs @@ -50,6 +50,10 @@ impl<'tcx> CodegenCx<'tcx> { self.constant_int_from_native_unsigned(span, val) } + pub fn constant_u128(&self, span: Span, val: u128) -> SpirvValue { + self.constant_int_from_native_unsigned(span, val) + } + fn constant_int_from_native_unsigned(&self, span: Span, val: impl Into) -> SpirvValue { let size = Size::from_bytes(std::mem::size_of_val(&val)); let ty = SpirvType::Integer(size.bits() as u32, false).def(span, self); diff --git a/tests/compiletests/ui/lang/core/array/init_array_i128.rs b/tests/compiletests/ui/lang/core/array/init_array_i128.rs new file mode 100644 index 00000000000..916f39258f0 --- /dev/null +++ b/tests/compiletests/ui/lang/core/array/init_array_i128.rs @@ -0,0 +1,14 @@ +// build-pass + +use spirv_std::spirv; + +pub fn u128_constant() -> [u128; 4] { + return [0x123456789ABCDEF0123456789ABCDEF; 4]; +} + +pub fn i128_constant() -> [i128; 4] { + return [0x123456789ABCDEF0123456789ABCDEF; 4]; +} + +#[spirv(fragment)] +pub fn main() {} diff --git a/tests/compiletests/ui/lang/core/array/init_array_i128_zeroed.rs b/tests/compiletests/ui/lang/core/array/init_array_i128_zeroed.rs new file mode 100644 index 00000000000..f7f4dd1be10 --- /dev/null +++ b/tests/compiletests/ui/lang/core/array/init_array_i128_zeroed.rs @@ -0,0 +1,23 @@ +// build-pass + +use spirv_std::spirv; + +/// `crypto-common` has a proc macro to implement code for u8, u16, u32, u16 and u128, +/// which means we need our codegen to handle the u128 case for the crate to even compile. +/// Specifically, this calls `memset_const_pattern` with u128. +/// +/// +/// +/// Note that the u128 path is unusable anyway as 128-bit integer are not supported in SPIR-V. +/// So if this is used nowhere in any entry point, our post-link DCE will remove the u128 code, +/// and the SPIR-V will be valid. +pub fn u128_zero_fill() -> [u128; 4] { + return [0; 4]; +} + +pub fn i128_zero_fill() -> [i128; 4] { + return [0; 4]; +} + +#[spirv(fragment)] +pub fn main() {}