Skip to content

Commit

Permalink
initial C ABI testing for vectors
Browse files Browse the repository at this point in the history
Can't test for larger vectors (256-bit and 512-bit because of confusion
with passing on stack and passing in registers (that don'y always exist).

See #1481 (comment)

ARM uses sret for vector arguments, and those are runtime. I don't understand
what that assert was for.
  • Loading branch information
shawnl committed Nov 21, 2019
1 parent bf57996 commit 10c4c4a
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 192 deletions.
3 changes: 2 additions & 1 deletion src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2590,7 +2590,8 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns
return nullptr;
}
assert(g->cur_ret_ptr);
ir_assert(instruction->operand->value.special != ConstValSpecialRuntime, &instruction->base);
src_assert(instruction->operand->value.special != ConstValSpecialRuntime,
instruction->base.source_node);
LLVMValueRef value = ir_llvm_value(g, instruction->operand);
ZigType *return_type = instruction->operand->value.type;
gen_assign_raw(g, g->cur_ret_ptr, get_pointer_to_type(g, return_type, false), value);
Expand Down
191 changes: 0 additions & 191 deletions test/stage1/behavior/vector.zig
Original file line number Diff line number Diff line change
Expand Up @@ -704,194 +704,3 @@ test "vectors - % and @mod" {
S.doTheTest();
comptime S.doTheTest();
}

test "vectors - indxed load from vector, SIMD" {
const S = struct {
fn doTheTest() void {
var v: @Vector(4, u32) = [_]u32{5, 6, 7, 8};
const w: @Vector(2, i32) = [_]i32{1, 2};
var x = v[w];
expect(x[0] == 6);
expect(x[1] == 7);
const w2 = [_]i32{1, 2};
var x2 = v[w2];
expect(x2[0] == 6);
expect(x2[1] == 7);
}
};
S.doTheTest();
comptime S.doTheTest();
}

test "vectors - indexed assign to vector, SIMD" {
const S = struct {
fn doTheTest() void {
var v: @Vector(4, u32) = [_]u32{5, 6, 7, 8};
const w: @Vector(2, i32) = [_]i32{1, 2};
var a: @Vector(2, u32) = [_]u32{45, 46};
v[w] = a;
expect(v[0] == 5);
expect(v[1] == 45);
expect(v[2] == 46);
expect(v[3] == 8);
const w2 = [_]i32{2, 3};
v[w2] = a;
expect(v[0] == 5);
expect(v[1] == 45);
expect(v[2] == 45);
expect(v[3] == 46);
}
};
S.doTheTest();
comptime S.doTheTest();
}

test "arrays - indexed SIMD load" {
const S = struct {
fn doTheTest() void {
var v = [_]u32{5, 6, 7, 8};
const w: @Vector(2, u16) = [_]u16{1, 2};
var x = v[w];
expect(x[0] == 6);
expect(x[1] == 7);
const w2: @Vector(2, u16) = [_]u16{1, 2};
var x2 = v[w2];
expect(x2[0] == 6);
expect(x2[1] == 7);
}
};
S.doTheTest();
// Requires quite a bit of work
//comptime S.doTheTest();
}

test "arrays - indexed SIMD store" {
const S = struct {
fn doTheTest() void {
var v = [_]u32{5, 6, 7, 8};
const w: @Vector(2, u16) = [_]u16{1, 2};
var put: @Vector(2, u32) = [_]u32{56, 57};
v[w] = put;
expect(v[0] == 5);
expect(v[1] == 56);
expect(v[2] == 57);
expect(v[3] == 8);
}
};
S.doTheTest();
// Requires quite a bit of work
//comptime S.doTheTest();
}

test "vectors - % and @mod" {
const S = struct {
fn doTheTest() void {
var v: @Vector(4, u32) = [_]u32{5, 6, 7, 8};
var w: @Vector(4, u32) = [_]u32{1, 2, 3, 4};
var x: @Vector(4, u32) = v % w;
expect(x[0] == 0);
expect(x[1] == 0);
expect(x[2] == 1);
expect(x[3] == 0);
var y: @Vector(4, u32) = @mod(v, w);
expect(y[0] == 0);
expect(y[1] == 0);
expect(y[2] == 1);
expect(y[3] == 0);
}
};
S.doTheTest();
comptime S.doTheTest();
}

test "vectors - indxed load from vector, SIMD" {
const S = struct {
fn doTheTest() void {
var v: @Vector(4, u32) = [_]u32{5, 6, 7, 8};
const w: @Vector(2, i32) = [_]i32{1, 2};
var x = v[w];
expect(x[0] == 6);
expect(x[1] == 7);
const w2 = [_]i32{1, 2};
var x2 = v[w2];
expect(x2[0] == 6);
expect(x2[1] == 7);
}
};
S.doTheTest();
comptime S.doTheTest();
}

test "vectors - indexed assign to vector, SIMD" {
const S = struct {
fn doTheTest() void {
var v: @Vector(4, u32) = [_]u32{5, 6, 7, 8};
const w: @Vector(2, i32) = [_]i32{1, 2};
var a: @Vector(2, u32) = [_]u32{45, 46};
v[w] = a;
expect(v[0] == 5);
expect(v[1] == 45);
expect(v[2] == 46);
expect(v[3] == 8);
const w2 = [_]i32{2, 3};
v[w2] = a;
expect(v[0] == 5);
expect(v[1] == 45);
expect(v[2] == 45);
expect(v[3] == 46);
}
};
S.doTheTest();
comptime S.doTheTest();
}

test "arrays - indexed SIMD load" {
const S = struct {
fn doTheTest() void {
var v = [_]u32{5, 6, 7, 8};
const w: @Vector(2, u16) = [_]u16{1, 2};
var x = v[w];
expect(x[0] == 6);
expect(x[1] == 7);
const w2: @Vector(2, u16) = [_]u16{1, 2};
var x2 = v[w2];
expect(x2[0] == 6);
expect(x2[1] == 7);
}
};
S.doTheTest();
// Requires quite a bit of work
//comptime S.doTheTest();
}

test "arrays - indexed SIMD store" {
const S = struct {
fn doTheTest() void {
var v = [_]u32{5, 6, 7, 8};
const w: @Vector(2, u16) = [_]u16{1, 2};
var put: @Vector(2, u32) = [_]u32{56, 57};
v[w] = put;
expect(v[0] == 5);
expect(v[1] == 56);
expect(v[2] == 57);
expect(v[3] == 8);
}
};
S.doTheTest();
// Requires quite a bit of work
//comptime S.doTheTest();
}

test "bounds checks - loads" {
const S = struct {
fn doTheTest() void {
var v = [_]u32{7, 8};
var s: @Vector(2, usize) = [_]usize{1, 0};
var res = v[s];
expect(res[0] == 8);
expect(res[1] == 7);
}
};
S.doTheTest();
// comptime S.doTheTest();
}
20 changes: 20 additions & 0 deletions test/stage1/c_abi/cfuncs.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ void zig_split_struct_ints(struct SplitStructInts);

struct BigStruct zig_big_struct_both(struct BigStruct);

typedef unsigned v4u32 __attribute__ ((vector_size (16)));
v4u32 zig_16_vector(v4u32);

void run_c_tests(void) {
zig_u8(0xff);
zig_u16(0xfffe);
Expand Down Expand Up @@ -110,6 +113,14 @@ void run_c_tests(void) {
assert_or_panic(res.d == 23);
assert_or_panic(res.e == 24);
}
{
v4u32 s = {10, 11, 12, 13};
v4u32 res = zig_16_vector(s);
assert_or_panic(res[0] == 11);
assert_or_panic(res[1] == 12);
assert_or_panic(res[2] == 13);
assert_or_panic(res[3] == 14);
}
}

void c_u8(uint8_t x) {
Expand Down Expand Up @@ -226,3 +237,12 @@ struct BigStruct c_big_struct_both(struct BigStruct x) {
struct BigStruct y = {10, 11, 12, 13, 14};
return y;
}

v4u32 c_16_vector(v4u32 x) {
assert_or_panic(x[0] == 0);
assert_or_panic(x[1] == 1);
assert_or_panic(x[2] == 2);
assert_or_panic(x[3] == 3);
v4u32 y = {10, 11, 12, 13};
return y;
}
22 changes: 22 additions & 0 deletions test/stage1/c_abi/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -261,3 +261,25 @@ export fn zig_big_struct_both(x: BigStruct) BigStruct {
};
return s;
}

extern fn c_16_vector(@Vector(4, u32)) @Vector(4, u32);

test "C ABI vectors" {
{
var s: @Vector(4, u32) = [_]u32{0, 1, 2, 3};
var y = c_16_vector(s);
expect(y[0] == 10);
expect(y[1] == 11);
expect(y[2] == 12);
expect(y[3] == 13);
}
}

export fn zig_16_vector(x: @Vector(4, u32)) @Vector(4, u32) {
expect(x[0] == 10);
expect(x[1] == 11);
expect(x[2] == 12);
expect(x[3] == 13);
var s: @Vector(4, u32) = [_]u32{11, 12, 13, 14};
return s;
}

0 comments on commit 10c4c4a

Please sign in to comment.