Skip to content

Commit

Permalink
Account for signedness in memset const pat
Browse files Browse the repository at this point in the history
Fixes EmbarkStudios#1061

Thanks to LegNeato
  • Loading branch information
JulianKnodt committed Apr 12, 2024
1 parent 54f6978 commit 231ca17
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 11 deletions.
27 changes: 25 additions & 2 deletions crates/rustc_codegen_spirv/src/builder/builder_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
match *ty {
SpirvType::Void => self.fatal("memset invalid on void pattern"),
SpirvType::Bool => self.fatal("memset invalid on bool pattern"),
SpirvType::Integer(width, _signedness) => match width {
SpirvType::Integer(width, false) => match width {
8 => self.constant_u8(self.span(), fill_byte).def(self),
16 => self
.constant_u16(self.span(), memset_fill_u16(fill_byte))
Expand All @@ -205,6 +205,29 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
"memset on integer width {width} not implemented yet"
)),
},
SpirvType::Integer(width, true) => match width {
8 => self
.constant_i8(self.span(), unsafe { std::mem::transmute(fill_byte) })
.def(self),
16 => self
.constant_i16(self.span(), unsafe {
std::mem::transmute(memset_fill_u16(fill_byte))
})
.def(self),
32 => self
.constant_i32(self.span(), unsafe {
std::mem::transmute(memset_fill_u32(fill_byte))
})
.def(self),
64 => self
.constant_i64(self.span(), unsafe {
std::mem::transmute(memset_fill_u64(fill_byte))
})
.def(self),
_ => self.fatal(format!(
"memset on integer width {width} not implemented yet"
)),
},
SpirvType::Float(width) => match width {
32 => self
.constant_f32(self.span(), f32::from_bits(memset_fill_u32(fill_byte)))
Expand Down Expand Up @@ -315,7 +338,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
} else {
for index in 0..count {
let const_index = self.constant_u32(self.span(), index as u32);
let gep_ptr = self.gep(pat.ty, ptr, &[const_index]);
let gep_ptr = self.inbounds_gep(pat.ty, ptr, &[const_index]);
self.store(pat, gep_ptr, Align::from_bytes(0).unwrap());
}
}
Expand Down
26 changes: 17 additions & 9 deletions crates/rustc_codegen_spirv/src/codegen_cx/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ impl<'tcx> CodegenCx<'tcx> {
self.builder.def_constant_cx(ty, val, self)
}

pub fn constant_i8(&self, span: Span, val: i8) -> SpirvValue {
let ty = SpirvType::Integer(8, true).def(span, self);
self.def_constant(ty, SpirvConst::U32(val as u32))
}

pub fn constant_u8(&self, span: Span, val: u8) -> SpirvValue {
let ty = SpirvType::Integer(8, false).def(span, self);
self.def_constant(ty, SpirvConst::U32(val as u32))
Expand All @@ -40,6 +45,11 @@ impl<'tcx> CodegenCx<'tcx> {
self.def_constant(ty, SpirvConst::U32(val))
}

pub fn constant_i64(&self, span: Span, val: u64) -> SpirvValue {
let ty = SpirvType::Integer(64, true).def(span, self);
self.def_constant(ty, SpirvConst::U64(val))
}

pub fn constant_u64(&self, span: Span, val: u64) -> SpirvValue {
let ty = SpirvType::Integer(64, false).def(span, self);
self.def_constant(ty, SpirvConst::U64(val))
Expand All @@ -50,14 +60,12 @@ impl<'tcx> CodegenCx<'tcx> {
SpirvType::Integer(bits @ 8..=32, signed) => {
let size = Size::from_bits(bits);
let val = val as u128;
self.def_constant(
ty,
SpirvConst::U32(if signed {
size.sign_extend(val)
} else {
size.truncate(val)
} as u32),
)
let new_val = if signed {
size.sign_extend(val)
} else {
size.truncate(val)
} as u32;
self.def_constant(ty, SpirvConst::U32(new_val))
}
SpirvType::Integer(64, _) => self.def_constant(ty, SpirvConst::U64(val)),
SpirvType::Bool => match val {
Expand Down Expand Up @@ -420,7 +428,7 @@ impl<'tcx> CodegenCx<'tcx> {
// println!(
// "Creating const alloc of type {} with {} bytes",
// self.debug_type(ty),
// alloc.len()
// alloc.0.len()
// );
let mut offset = Size::ZERO;
let result = self.read_from_const_alloc(alloc, &mut offset, ty);
Expand Down
10 changes: 10 additions & 0 deletions tests/ui/lang/core/array/init_array_i16.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Test creating an array.
// build-pass

use spirv_std::macros::spirv;

#[spirv(fragment)]
pub fn main(o: &mut i16) {
let array = [0i16; 4];
*o = array[1];
}
10 changes: 10 additions & 0 deletions tests/ui/lang/core/array/init_array_i32.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Test creating an array.
// build-pass

use spirv_std::macros::spirv;

#[spirv(fragment)]
pub fn main(o: &mut i32) {
let array = [0i32; 4];
*o = array[1];
}
10 changes: 10 additions & 0 deletions tests/ui/lang/core/array/init_array_i64.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Test creating an array.
// build-pass

use spirv_std::macros::spirv;

#[spirv(fragment)]
pub fn main(o: &mut i64) {
let array = [0i64; 4];
*o = array[1];
}
10 changes: 10 additions & 0 deletions tests/ui/lang/core/array/init_array_i8.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Test creating an array.
// build-pass

use spirv_std::macros::spirv;

#[spirv(fragment)]
pub fn main(o: &mut i8) {
let array = [0i8; 4];
*o = array[1];
}

0 comments on commit 231ca17

Please sign in to comment.