Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 58d0b23

Browse files
Fix zero-sized Array GEPs
Previously GEP on zero-sized arrays, would fail. This change fixes arrays to instead emit runtime arrays. I do not know if this will lead to any runtime cost, but it fixes all the compile errors.
1 parent 1932353 commit 58d0b23

File tree

11 files changed

+98
-6
lines changed

11 files changed

+98
-6
lines changed

‎crates/rustc_codegen_spirv/src/abi.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -649,9 +649,6 @@ fn trans_aggregate<'tcx>(cx: &CodegenCx<'tcx>, span: Span, ty: TyAndLayout<'tcx>
649649
element: element_type,
650650
}
651651
.def(span, cx)
652-
} else if count == 0 {
653-
// spir-v doesn't support zero-sized arrays
654-
create_zst(cx, span, ty)
655652
} else {
656653
let count_const = cx.constant_u32(span, count as u32);
657654
let element_spv = cx.lookup_type(element_type);

‎crates/rustc_codegen_spirv/src/builder/builder_methods.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
406406
let ptr = ptr.strip_ptrcasts();
407407
let mut leaf_ty = match self.lookup_type(ptr.ty) {
408408
SpirvType::Pointer { pointee } => pointee,
409-
other => self.fatal(format!("non-pointer type: {other:?}")),
409+
SpirvType::Adt { .. } => return None,
410+
other => self.fatal(format!("adjust_pointer for non-pointer type: {other:?}")),
410411
};
411412

412413
// FIXME(eddyb) this isn't efficient, `recover_access_chain_from_offset`
@@ -528,8 +529,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
528529
let stride = ty_kind.sizeof(self)?;
529530
ty_size = MaybeSized::Sized(stride);
530531

531-
indices.push((offset.bytes() / stride.bytes()).try_into().ok()?);
532-
offset = Size::from_bytes(offset.bytes() % stride.bytes());
532+
if stride.bytes() == 0 {
533+
indices.push(0);
534+
offset = Size::from_bytes(0);
535+
} else {
536+
indices.push((offset.bytes() / stride.bytes()).try_into().ok()?);
537+
offset = Size::from_bytes(offset.bytes() % stride.bytes());
538+
}
533539
}
534540
_ => return None,
535541
}
@@ -566,6 +572,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
566572
.iter()
567573
.map(|index| {
568574
result_pointee_type = match self.lookup_type(result_pointee_type) {
575+
SpirvType::Array { count, element }
576+
if self.builder.lookup_const_u64(count) == Some(0) =>
577+
{
578+
self.fatal(format!(
579+
"Cannot index into [{}; 0], will panic at runtime.",
580+
self.debug_type(element)
581+
))
582+
}
569583
SpirvType::Array { element, .. } | SpirvType::RuntimeArray { element } => {
570584
element
571585
}

‎crates/rustc_codegen_spirv/src/codegen_cx/constant.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,10 @@ impl<'tcx> CodegenCx<'tcx> {
549549
}
550550
self.constant_composite(ty, values.into_iter())
551551
}
552+
SpirvType::Array { count, .. } if self.builder.lookup_const_u64(count) == Some(0) =>
553+
{
554+
self.undef(ty)
555+
}
552556
SpirvType::Array { element, count } => {
553557
let count = self.builder.lookup_const_u64(count).unwrap() as usize;
554558
let values = (0..count).map(|_| {

‎crates/rustc_codegen_spirv/src/spirv_type.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,9 @@ impl SpirvType<'_> {
368368
.bytes(),
369369
)
370370
.expect("alignof: Vectors must have power-of-2 size"),
371+
Self::Array { count, .. } if cx.builder.lookup_const_u64(count) == Some(0) => {
372+
Align::from_bytes(0).unwrap()
373+
}
371374
Self::Array { element, .. }
372375
| Self::RuntimeArray { element }
373376
| Self::Matrix { element, .. } => cx.lookup_type(element).alignof(cx),

‎tests/ui/lang/core/array/array_0.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![allow(unconditional_panic)]
2+
3+
// build-fail
4+
#![cfg_attr(target_arch = "spirv", no_std)]
5+
use spirv_std::spirv;
6+
7+
#[spirv(compute(threads(1, 1, 1)))]
8+
pub fn compute() {
9+
let array = [0; 0];
10+
let x = array[0];
11+
}

‎tests/ui/lang/core/array/array_0.stderr

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: Cannot index into [i32; 0], will panic at runtime.
2+
--> $DIR/array_0.rs:10:13
3+
|
4+
10 | let x = array[0];
5+
| ^^^^^^^^
6+
7+
error: aborting due to 1 previous error
8+

‎tests/ui/lang/core/array/array_zst_0.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// build-pass
2+
#![cfg_attr(target_arch = "spirv", no_std)]
3+
use spirv_std::spirv;
4+
5+
#[spirv(compute(threads(1, 1, 1)))]
6+
pub fn compute() {
7+
let mut array = [(); 0];
8+
for i in 0..array.len() {
9+
array[i] = ();
10+
}
11+
}

‎tests/ui/lang/core/array/gep0.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// build-fail
2+
3+
#![cfg_attr(target_arch = "spirv", no_std)]
4+
use spirv_std::spirv;
5+
6+
fn example<const N: usize>() {
7+
let mut array = [0; N];
8+
for i in 0..N {
9+
array[i] += i;
10+
}
11+
}
12+
13+
#[spirv(compute(threads(1, 1, 1)))]
14+
pub fn compute() {
15+
example::<0>();
16+
}

‎tests/ui/lang/core/array/gep0.stderr

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: Cannot index into [u32; 0], will panic at runtime.
2+
--> $DIR/gep0.rs:9:9
3+
|
4+
9 | array[i] += i;
5+
| ^^^^^^^^^^^^^
6+
7+
error: aborting due to 1 previous error
8+

‎tests/ui/lang/core/array/oob_0_array.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// build-fail
2+
3+
#![cfg_attr(target_arch = "spirv", no_std)]
4+
use spirv_std::spirv;
5+
6+
#[spirv(compute(threads(1, 1, 1)))]
7+
pub fn compute() {
8+
let mut array = [0; 0];
9+
array[0] = 1;
10+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /