Skip to content

Commit f100b97

Browse files
committed
compiler: preserve SIMD aliases and expand vector contract tests
1 parent 2026a67 commit f100b97

2 files changed

Lines changed: 111 additions & 0 deletions

File tree

crates/compiler/src/lowering.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2053,6 +2053,34 @@ impl LoweringContext {
20532053
}
20542054
}
20552055

2056+
fn try_parse_builtin_simd_type(name: InternedString) -> Option<HirType> {
2057+
let raw = name.resolve_global()?;
2058+
let (elem_ty, lanes) = match raw.as_str() {
2059+
"f32x4" => (HirType::F32, 4),
2060+
"f64x2" => (HirType::F64, 2),
2061+
"i32x4" => (HirType::I32, 4),
2062+
"i64x2" => (HirType::I64, 2),
2063+
_ => return None,
2064+
};
2065+
Some(HirType::Vector(Box::new(elem_ty), lanes))
2066+
}
2067+
2068+
fn looks_like_simd_alias(name: InternedString) -> bool {
2069+
let Some(raw) = name.resolve_global() else {
2070+
return false;
2071+
};
2072+
let Some((prefix, lanes_str)) = raw.split_once('x') else {
2073+
return false;
2074+
};
2075+
if lanes_str.parse::<u32>().is_err() {
2076+
return false;
2077+
}
2078+
matches!(
2079+
prefix,
2080+
"f16" | "f32" | "f64" | "i8" | "i16" | "i32" | "i64" | "u8" | "u16" | "u32" | "u64"
2081+
)
2082+
}
2083+
20562084
/// Convert frontend type to HIR type
20572085
/// Convert a type to its ABI representation (for function signatures)
20582086
/// Abstract types are converted to their underlying types for zero-cost abstraction
@@ -2200,6 +2228,14 @@ impl LoweringContext {
22002228
nullability: zyntax_typed_ast::type_registry::NullabilityKind::NonNull,
22012229
};
22022230
self.convert_type(&named_type)
2231+
} else if let Some(simd_ty) = Self::try_parse_builtin_simd_type(*name) {
2232+
simd_ty
2233+
} else if Self::looks_like_simd_alias(*name) {
2234+
log::warn!(
2235+
"Unsupported SIMD alias '{}' (supported: f32x4, f64x2, i32x4, i64x2); preserving as opaque",
2236+
name.resolve_global().unwrap_or_default()
2237+
);
2238+
HirType::Opaque(*name)
22032239
} else {
22042240
log::warn!(
22052241
"Could not resolve type '{}', defaulting to I64",
@@ -5017,6 +5053,7 @@ pub mod passes {
50175053
#[cfg(test)]
50185054
mod tests {
50195055
use super::*;
5056+
use zyntax_typed_ast::AstArena;
50205057

50215058
// Test passes for topological sort
50225059
struct PassA;
@@ -5189,4 +5226,42 @@ mod tests {
51895226

51905227
pipeline.sort_passes(); // Should panic
51915228
}
5229+
5230+
#[test]
5231+
fn test_builtin_simd_aliases_convert_to_hir_vectors() {
5232+
let mut arena = AstArena::new();
5233+
5234+
let f32x4 = arena.intern_string("f32x4");
5235+
let f64x2 = arena.intern_string("f64x2");
5236+
let i32x4 = arena.intern_string("i32x4");
5237+
let i64x2 = arena.intern_string("i64x2");
5238+
5239+
assert!(matches!(
5240+
LoweringContext::try_parse_builtin_simd_type(f32x4),
5241+
Some(HirType::Vector(elem, 4)) if matches!(*elem, HirType::F32)
5242+
));
5243+
assert!(matches!(
5244+
LoweringContext::try_parse_builtin_simd_type(f64x2),
5245+
Some(HirType::Vector(elem, 2)) if matches!(*elem, HirType::F64)
5246+
));
5247+
assert!(matches!(
5248+
LoweringContext::try_parse_builtin_simd_type(i32x4),
5249+
Some(HirType::Vector(elem, 4)) if matches!(*elem, HirType::I32)
5250+
));
5251+
assert!(matches!(
5252+
LoweringContext::try_parse_builtin_simd_type(i64x2),
5253+
Some(HirType::Vector(elem, 2)) if matches!(*elem, HirType::I64)
5254+
));
5255+
}
5256+
5257+
#[test]
5258+
fn test_simd_alias_detection_for_unsupported_shapes() {
5259+
let mut arena = AstArena::new();
5260+
let unsupported = arena.intern_string("i16x8");
5261+
let nonsimd = arena.intern_string("Tensor");
5262+
5263+
assert!(LoweringContext::looks_like_simd_alias(unsupported));
5264+
assert!(LoweringContext::try_parse_builtin_simd_type(unsupported).is_none());
5265+
assert!(!LoweringContext::looks_like_simd_alias(nonsimd));
5266+
}
51925267
}

crates/compiler/tests/cranelift_backend_tests.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,42 @@ fn test_vector_f32x4_add_compilation() {
226226
.expect("Failed to compile f32x4 add function");
227227
}
228228

229+
/// Test SIMD vector arithmetic compilation (f64x2 lanes)
230+
#[test]
231+
fn test_vector_f64x2_add_compilation() {
232+
let mut backend = CraneliftBackend::new().expect("Failed to create backend");
233+
let func = create_vector_arithmetic_function("vec_f64x2_add", BinaryOp::FAdd, HirType::F64, 2);
234+
backend
235+
.compile_function(func.id, &func)
236+
.expect("Failed to compile f64x2 add function");
237+
}
238+
239+
/// Test SIMD vector arithmetic compilation (i64x2 lanes)
240+
#[test]
241+
fn test_vector_i64x2_add_compilation() {
242+
let mut backend = CraneliftBackend::new().expect("Failed to create backend");
243+
let func = create_vector_arithmetic_function("vec_i64x2_add", BinaryOp::Add, HirType::I64, 2);
244+
backend
245+
.compile_function(func.id, &func)
246+
.expect("Failed to compile i64x2 add function");
247+
}
248+
249+
/// Unsupported vector lane shapes should fail with a clear diagnostic.
250+
#[test]
251+
fn test_vector_unsupported_lane_shape_rejected() {
252+
let mut backend = CraneliftBackend::new().expect("Failed to create backend");
253+
let func = create_vector_arithmetic_function("vec_i16x8_add", BinaryOp::Add, HirType::I16, 8);
254+
let err = backend
255+
.compile_function(func.id, &func)
256+
.expect_err("Expected unsupported SIMD lane shape to be rejected");
257+
let msg = err.to_string();
258+
assert!(
259+
msg.contains("unsupported SIMD vector lane shape"),
260+
"unexpected error: {}",
261+
msg
262+
);
263+
}
264+
229265
/// Test scalar float remainder codegen (f64 + f32).
230266
#[test]
231267
fn test_scalar_float_remainder_compilation() {

0 commit comments

Comments
 (0)