mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2024-11-24 15:54:57 +00:00
Account for signedness in memset const pat
Fixes #1061 Thanks to LegNeato
This commit is contained in:
parent
54f6978c25
commit
231ca17dc2
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
10
tests/ui/lang/core/array/init_array_i16.rs
Normal file
10
tests/ui/lang/core/array/init_array_i16.rs
Normal 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];
|
||||
}
|
10
tests/ui/lang/core/array/init_array_i32.rs
Normal file
10
tests/ui/lang/core/array/init_array_i32.rs
Normal 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];
|
||||
}
|
10
tests/ui/lang/core/array/init_array_i64.rs
Normal file
10
tests/ui/lang/core/array/init_array_i64.rs
Normal 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];
|
||||
}
|
10
tests/ui/lang/core/array/init_array_i8.rs
Normal file
10
tests/ui/lang/core/array/init_array_i8.rs
Normal 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];
|
||||
}
|
Loading…
Reference in New Issue
Block a user