Account for signedness in memset const pat

Fixes #1061

Thanks to LegNeato
This commit is contained in:
julianknodt 2024-04-12 01:59:40 -07:00
parent 54f6978c25
commit 231ca17dc2
6 changed files with 82 additions and 11 deletions

View File

@ -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))
@ -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)))
@ -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());
}
}

View File

@ -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))
@ -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))
@ -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 {
@ -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);

View File

@ -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];
}

View File

@ -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];
}

View File

@ -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];
}

View File

@ -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];
}