authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-01 22:57:19-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-05 12:11:40-05:00
log70be308c4315c53d42889d568d5731ba227dcf88
tree181b9f099af8dee8637535adfe87550f0355a2f3
parent76d188551eb3f742c2feb086c8c51c6b0815184d
signaturelock-open Commit is signed but in an unrecognized format.

implement loading vector elements via runtime index


6 files changed, 93 insertions(+), 1 deletions(-)

src/all_types.hpp+8
......@@ -2575,6 +2575,7 @@ enum IrInstructionId {
25752575 IrInstructionIdResume,
25762576 IrInstructionIdSpillBegin,
25772577 IrInstructionIdSpillEnd,
2578 IrInstructionIdVectorExtractElem,
25782579};
25792580
25802581struct IrInstruction {
......@@ -3902,6 +3903,13 @@ struct IrInstructionSpillEnd {
39023903 IrInstructionSpillBegin *begin;
39033904};
39043905
3906struct IrInstructionVectorExtractElem {
3907 IrInstruction base;
3908
3909 IrInstruction *vector;
3910 IrInstruction *index;
3911};
3912
39053913enum ResultLocId {
39063914 ResultLocIdInvalid,
39073915 ResultLocIdNone,
src/codegen.cpp+10
......@@ -6002,6 +6002,14 @@ static LLVMValueRef ir_render_spill_end(CodeGen *g, IrExecutable *executable, Ir
60026002 zig_unreachable();
60036003}
60046004
6005static LLVMValueRef ir_render_vector_extract_elem(CodeGen *g, IrExecutable *executable,
6006 IrInstructionVectorExtractElem *instruction)
6007{
6008 LLVMValueRef vector = ir_llvm_value(g, instruction->vector);
6009 LLVMValueRef index = ir_llvm_value(g, instruction->index);
6010 return LLVMBuildExtractElement(g->builder, vector, index, "");
6011}
6012
60056013static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
60066014 AstNode *source_node = instruction->source_node;
60076015 Scope *scope = instruction->scope;
......@@ -6262,6 +6270,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
62626270 return ir_render_shuffle_vector(g, executable, (IrInstructionShuffleVector *) instruction);
62636271 case IrInstructionIdSplatGen:
62646272 return ir_render_splat(g, executable, (IrInstructionSplatGen *) instruction);
6273 case IrInstructionIdVectorExtractElem:
6274 return ir_render_vector_extract_elem(g, executable, (IrInstructionVectorExtractElem *) instruction);
62656275 }
62666276 zig_unreachable();
62676277}
src/ir.cpp+29-1
......@@ -1083,6 +1083,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSpillEnd *) {
10831083 return IrInstructionIdSpillEnd;
10841084}
10851085
1086static constexpr IrInstructionId ir_instruction_id(IrInstructionVectorExtractElem *) {
1087 return IrInstructionIdVectorExtractElem;
1088}
1089
10861090template<typename T>
10871091static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
10881092 const char *name = nullptr;
......@@ -3419,6 +3423,21 @@ static IrInstruction *ir_build_spill_end(IrBuilder *irb, Scope *scope, AstNode *
34193423 return &instruction->base;
34203424}
34213425
3426static IrInstruction *ir_build_vector_extract_elem(IrAnalyze *ira, IrInstruction *source_instruction,
3427 IrInstruction *vector, IrInstruction *index)
3428{
3429 IrInstructionVectorExtractElem *instruction = ir_build_instruction<IrInstructionVectorExtractElem>(
3430 &ira->new_irb, source_instruction->scope, source_instruction->source_node);
3431 instruction->base.value.type = vector->value.type->data.vector.elem_type;
3432 instruction->vector = vector;
3433 instruction->index = index;
3434
3435 ir_ref_instruction(vector, ira->new_irb.current_basic_block);
3436 ir_ref_instruction(index, ira->new_irb.current_basic_block);
3437
3438 return &instruction->base;
3439}
3440
34223441static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
34233442 results[ReturnKindUnconditional] = 0;
34243443 results[ReturnKindError] = 0;
......@@ -12965,8 +12984,15 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc
1296512984 // the type information does not contain enough information to actually
1296612985 // perform a dereference.
1296712986 if (ptr_type->data.pointer.vector_index == VECTOR_INDEX_RUNTIME) {
12987 if (ptr->id == IrInstructionIdElemPtr) {
12988 IrInstructionElemPtr *elem_ptr = (IrInstructionElemPtr *)ptr;
12989 IrInstruction *vector_loaded = ir_get_deref(ira, elem_ptr->array_ptr,
12990 elem_ptr->array_ptr, nullptr);
12991 IrInstruction *elem_index = elem_ptr->elem_index;
12992 return ir_build_vector_extract_elem(ira, source_instruction, vector_loaded, elem_index);
12993 }
1296812994 ir_add_error(ira, ptr,
12969 buf_sprintf("unable to determine element index in order to dereference vector pointer"));
12995 buf_sprintf("unable to determine vector element index of type '%s'", buf_ptr(&ptr_type->name)));
1297012996 return ira->codegen->invalid_instruction;
1297112997 }
1297212998
......@@ -26036,6 +26062,7 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
2603626062 case IrInstructionIdFrameSizeGen:
2603726063 case IrInstructionIdAwaitGen:
2603826064 case IrInstructionIdSplatGen:
26065 case IrInstructionIdVectorExtractElem:
2603926066 zig_unreachable();
2604026067
2604126068 case IrInstructionIdReturn:
......@@ -26571,6 +26598,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
2657126598 case IrInstructionIdAllocaSrc:
2657226599 case IrInstructionIdAllocaGen:
2657326600 case IrInstructionIdSpillEnd:
26601 case IrInstructionIdVectorExtractElem:
2657426602 return false;
2657526603
2657626604 case IrInstructionIdAsm:
src/ir_print.cpp+13
......@@ -370,6 +370,8 @@ const char* ir_instruction_type_str(IrInstructionId id) {
370370 return "SpillBegin";
371371 case IrInstructionIdSpillEnd:
372372 return "SpillEnd";
373 case IrInstructionIdVectorExtractElem:
374 return "VectorExtractElem";
373375 }
374376 zig_unreachable();
375377}
......@@ -1969,6 +1971,14 @@ static void ir_print_spill_end(IrPrint *irp, IrInstructionSpillEnd *instruction)
19691971 fprintf(irp->f, ")");
19701972}
19711973
1974static void ir_print_vector_extract_elem(IrPrint *irp, IrInstructionVectorExtractElem *instruction) {
1975 fprintf(irp->f, "@vectorExtractElem(");
1976 ir_print_other_instruction(irp, instruction->vector);
1977 fprintf(irp->f, ",");
1978 ir_print_other_instruction(irp, instruction->index);
1979 fprintf(irp->f, ")");
1980}
1981
19721982static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction, bool trailing) {
19731983 ir_print_prefix(irp, instruction, trailing);
19741984 switch (instruction->id) {
......@@ -2466,6 +2476,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction, bool
24662476 case IrInstructionIdSpillEnd:
24672477 ir_print_spill_end(irp, (IrInstructionSpillEnd *)instruction);
24682478 break;
2479 case IrInstructionIdVectorExtractElem:
2480 ir_print_vector_extract_elem(irp, (IrInstructionVectorExtractElem *)instruction);
2481 break;
24692482 }
24702483 fprintf(irp->f, "\n");
24712484}
test/compile_errors.zig+16
......@@ -24,6 +24,22 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2424 "tmp.zig:4:20: note: referenced here",
2525 );
2626
27 cases.add(
28 "dereference vector pointer with unknown runtime index",
29 \\export fn entry() void {
30 \\ var v: @Vector(4, i32) = [_]i32{ 1, 5, 3, undefined };
31 \\
32 \\ var i: u32 = 0;
33 \\ var x = loadv(&v[i]);
34 \\}
35 \\
36 \\fn loadv(ptr: var) i32 {
37 \\ return ptr.*;
38 \\}
39 ,
40 "tmp.zig:9:12: error: unable to determine vector element index of type '*align(16:0:4:?) i32",
41 );
42
2743 cases.add(
2844 "using an unknown len ptr type instead of array",
2945 \\const resolutions = [*][*]const u8{
test/stage1/behavior/vector.zig+17
......@@ -199,3 +199,20 @@ test "store vector elements via comptime index" {
199199 S.doTheTest();
200200 comptime S.doTheTest();
201201}
202
203test "load vector elements via runtime index" {
204 const S = struct {
205 fn doTheTest() void {
206 var v: @Vector(4, i32) = [_]i32{ 1, 2, 3, undefined };
207 var i: u32 = 0;
208 expect(v[i] == 1);
209 i += 1;
210 expect(v[i] == 2);
211 i += 1;
212 expect(v[i] == 3);
213 }
214 };
215
216 S.doTheTest();
217 comptime S.doTheTest();
218}