Commit 8632e4fc7b

Evan Haas <evan@lagerdata.com>
2022-07-29 06:04:17
translate-c: use correct number of initializers for vectors
Fixes #12264
1 parent 3cf8f28
Changed files (3)
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,
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, .{
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 <stdlib.h>
-            \\#include <stdint.h>
-            \\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 <stdlib.h>
+        \\#include <stdint.h>
+        \\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 <stdlib.h>