From 8632e4fc7b6cad33b951f71298ee6ac478e133cb Mon Sep 17 00:00:00 2001 From: Evan Haas Date: Thu, 28 Jul 2022 21:04:17 -0700 Subject: [PATCH] translate-c: use correct number of initializers for vectors Fixes #12264 --- src/translate_c.zig | 30 +++++++++++++++++++------- src/translate_c/ast.zig | 8 +++++++ test/run_translated_c.zig | 44 +++++++++++++++++++-------------------- 3 files changed, 52 insertions(+), 30 deletions(-) diff --git a/src/translate_c.zig b/src/translate_c.zig index e53342990e..97e47d84f3 100644 --- a/src/translate_c.zig +++ b/src/translate_c.zig @@ -2688,16 +2688,26 @@ fn transInitListExprVector( ) TransError!Node { _ = ty; const qt = getExprQualType(c, @ptrCast(*const clang.Expr, expr)); - const vector_type = try transQualType(c, scope, qt, loc); + const vector_ty = @ptrCast(*const clang.VectorType, qualTypeCanon(qt)); + const init_count = expr.getNumInits(); + const num_elements = vector_ty.getNumElements(); + const element_qt = vector_ty.getElementType(); if (init_count == 0) { - return Tag.container_init.create(c.arena, .{ - .lhs = vector_type, - .inits = try c.arena.alloc(ast.Payload.ContainerInit.Initializer, 0), + const zero_node = try Tag.as.create(c.arena, .{ + .lhs = try transQualType(c, scope, element_qt, loc), + .rhs = Tag.zero_literal.init(), + }); + + return Tag.vector_zero_init.create(c.arena, .{ + .lhs = try transCreateNodeNumber(c, num_elements, .int), + .rhs = zero_node, }); } + const vector_type = try transQualType(c, scope, qt, loc); + var block_scope = try Scope.Block.init(c, scope, true); defer block_scope.deinit(); @@ -2716,11 +2726,15 @@ fn transInitListExprVector( try block_scope.statements.append(tmp_decl_node); } - const init_list = try c.arena.alloc(Node, init_count); + const init_list = try c.arena.alloc(Node, num_elements); for (init_list) |*init, init_index| { - const tmp_decl = block_scope.statements.items[init_index]; - const name = tmp_decl.castTag(.var_simple).?.data.name; - init.* = try Tag.identifier.create(c.arena, name); + if (init_index < init_count) { + const tmp_decl = block_scope.statements.items[init_index]; + const name = tmp_decl.castTag(.var_simple).?.data.name; + init.* = try Tag.identifier.create(c.arena, name); + } else { + init.* = Tag.undefined_literal.init(); + } } const array_init = try Tag.array_init.create(c.arena, .{ diff --git a/src/translate_c/ast.zig b/src/translate_c/ast.zig index b88b481ae7..307a7e9ea7 100644 --- a/src/translate_c/ast.zig +++ b/src/translate_c/ast.zig @@ -154,6 +154,8 @@ pub const Node = extern union { div_exact, /// @offsetOf(lhs, rhs) offset_of, + /// @splat(lhs, rhs) + vector_zero_init, /// @shuffle(type, a, b, mask) shuffle, @@ -328,6 +330,7 @@ pub const Node = extern union { .div_exact, .offset_of, .helpers_cast, + .vector_zero_init, => Payload.BinOp, .integer_literal, @@ -1829,6 +1832,10 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { const type_expr = try renderNode(c, payload.cond); return renderArrayInit(c, type_expr, payload.cases); }, + .vector_zero_init => { + const payload = node.castTag(.vector_zero_init).?.data; + return renderBuiltinCall(c, "@splat", &.{ payload.lhs, payload.rhs }); + }, .field_access => { const payload = node.castTag(.field_access).?.data; const lhs = try renderNodeGrouped(c, payload.lhs); @@ -2305,6 +2312,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { .@"struct", .@"union", .array_init, + .vector_zero_init, .tuple, .container_init, .container_init_dot, diff --git a/test/run_translated_c.zig b/test/run_translated_c.zig index 871ec98fbc..4345625dc1 100644 --- a/test/run_translated_c.zig +++ b/test/run_translated_c.zig @@ -1322,28 +1322,28 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void { \\} , ""); - if (@import("builtin").zig_backend == .stage1) { - // https://github.com/ziglang/zig/issues/12264 - cases.add("basic vector expressions", - \\#include - \\#include - \\typedef int16_t __v8hi __attribute__((__vector_size__(16))); - \\int main(int argc, char**argv) { - \\ __v8hi uninitialized; - \\ __v8hi empty_init = {}; - \\ __v8hi partial_init = {0, 1, 2, 3}; - \\ - \\ __v8hi a = {0, 1, 2, 3, 4, 5, 6, 7}; - \\ __v8hi b = (__v8hi) {100, 200, 300, 400, 500, 600, 700, 800}; - \\ - \\ __v8hi sum = a + b; - \\ for (int i = 0; i < 8; i++) { - \\ if (sum[i] != a[i] + b[i]) abort(); - \\ } - \\ return 0; - \\} - , ""); - } + cases.add("basic vector expressions", + \\#include + \\#include + \\typedef int16_t __v8hi __attribute__((__vector_size__(16))); + \\int main(int argc, char**argv) { + \\ __v8hi uninitialized; + \\ __v8hi empty_init = {}; + \\ for (int i = 0; i < 8; i++) { + \\ if (empty_init[i] != 0) abort(); + \\ } + \\ __v8hi partial_init = {0, 1, 2, 3}; + \\ + \\ __v8hi a = {0, 1, 2, 3, 4, 5, 6, 7}; + \\ __v8hi b = (__v8hi) {100, 200, 300, 400, 500, 600, 700, 800}; + \\ + \\ __v8hi sum = a + b; + \\ for (int i = 0; i < 8; i++) { + \\ if (sum[i] != a[i] + b[i]) abort(); + \\ } + \\ return 0; + \\} + , ""); cases.add("__builtin_shufflevector", \\#include