mirror of
https://github.com/odin-lang/Odin.git
synced 2026-08-18 11:22:11 +00:00
5791,6748
This commit is contained in:
@@ -1305,10 +1305,6 @@ gb_internal bool check_builtin_simd_operation(CheckerContext *c, Operand *operan
|
||||
if (!check_index_value(c, x.type, false, ce->args[1], max_count, &value)) {
|
||||
return false;
|
||||
}
|
||||
if (max_count < 0) {
|
||||
error(ce->args[1], "'%.*s' expected a constant integer index, got '%lld'", LIT(builtin_name), cast(long long)value);
|
||||
return false;
|
||||
}
|
||||
|
||||
operand->mode = Addressing_Value;
|
||||
operand->type = elem;
|
||||
@@ -1330,10 +1326,6 @@ gb_internal bool check_builtin_simd_operation(CheckerContext *c, Operand *operan
|
||||
if (!check_index_value(c, x.type, false, ce->args[1], max_count, &value)) {
|
||||
return false;
|
||||
}
|
||||
if (max_count < 0) {
|
||||
error(ce->args[1], "'%.*s' expected a constant integer index, got '%lld'", LIT(builtin_name), cast(long long)value);
|
||||
return false;
|
||||
}
|
||||
|
||||
Operand y = {};
|
||||
check_expr_with_type_hint(c, &y, ce->args[2], elem); if (y.mode == Addressing_Invalid) return false;
|
||||
@@ -1801,12 +1793,13 @@ gb_internal bool check_builtin_simd_operation(CheckerContext *c, Operand *operan
|
||||
}
|
||||
Operand offset = {};
|
||||
check_expr(c, &offset, ce->args[1]); if (offset.mode == Addressing_Invalid) return false;
|
||||
convert_to_typed(c, &offset, t_i64);
|
||||
// `base:intrinsics` declares the offset as `int` and does not mark it #any_int
|
||||
convert_to_typed(c, &offset, t_int);
|
||||
if (!is_type_integer(offset.type) || offset.mode != Addressing_Constant) {
|
||||
error(offset.expr, "'%.*s' expected a constant integer offset", LIT(builtin_name));
|
||||
return false;
|
||||
}
|
||||
check_assignment(c, &offset, t_i64, builtin_name);
|
||||
check_assignment(c, &offset, t_int, builtin_name);
|
||||
|
||||
operand->type = x.type;
|
||||
operand->mode = Addressing_Value;
|
||||
|
||||
@@ -170,3 +170,36 @@ simd_pairwise_aliases_are_distinct :: proc(t: ^testing.T) {
|
||||
testing.expect_value(t, intrinsics.simd_extract(sub, 0), i32(7))
|
||||
testing.expect_value(t, intrinsics.simd_extract(sub, 1), i32(16))
|
||||
}
|
||||
|
||||
// The rotate offset is declared `$offset: int`; the checker demanded `i64`, so the declared
|
||||
// spelling did not compile. Other integer types stay rejected -- the declaration is not #any_int.
|
||||
|
||||
@(test)
|
||||
simd_lanes_rotate_offset_is_int :: proc(t: ^testing.T) {
|
||||
rot :: proc(v: #simd[4]u32, $offset: int) -> #simd[4]u32 {
|
||||
return intrinsics.simd_lanes_rotate_right(v, offset)
|
||||
}
|
||||
|
||||
v: #simd[4]u32 = {0, 1, 2, 3}
|
||||
r := rot(v, 1)
|
||||
testing.expect_value(t, intrinsics.simd_extract(r, 0), u32(3))
|
||||
testing.expect_value(t, intrinsics.simd_extract(r, 1), u32(0))
|
||||
|
||||
l := intrinsics.simd_lanes_rotate_left(v, 1)
|
||||
testing.expect_value(t, intrinsics.simd_extract(l, 0), u32(1))
|
||||
testing.expect_value(t, intrinsics.simd_extract(l, 3), u32(0))
|
||||
}
|
||||
|
||||
// `simd_extract` / `simd_replace` declare a plain `idx: uint`, so a runtime index is allowed and
|
||||
// lowers to a dynamic extractelement. Bounds are enforced only where the index is constant.
|
||||
|
||||
@(test)
|
||||
simd_extract_accepts_a_runtime_index :: proc(t: ^testing.T) {
|
||||
v: #simd[4]u32 = {10, 20, 30, 40}
|
||||
i := 2
|
||||
testing.expect_value(t, intrinsics.simd_extract(v, i), u32(30))
|
||||
|
||||
w := intrinsics.simd_replace(v, i, u32(99))
|
||||
testing.expect_value(t, intrinsics.simd_extract(w, 2), u32(99))
|
||||
testing.expect_value(t, intrinsics.simd_extract(w, 0), u32(10))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user