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
signature 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 {...@@ -2575,6 +2575,7 @@ enum IrInstructionId {
2575 IrInstructionIdResume,2575 IrInstructionIdResume,
2576 IrInstructionIdSpillBegin,2576 IrInstructionIdSpillBegin,
2577 IrInstructionIdSpillEnd,2577 IrInstructionIdSpillEnd,
2578 IrInstructionIdVectorExtractElem,
2578};2579};
25792580
2580struct IrInstruction {2581struct IrInstruction {
...@@ -3902,6 +3903,13 @@ struct IrInstructionSpillEnd {...@@ -3902,6 +3903,13 @@ struct IrInstructionSpillEnd {
3902 IrInstructionSpillBegin *begin;3903 IrInstructionSpillBegin *begin;
3903};3904};
39043905
3906struct IrInstructionVectorExtractElem {
3907 IrInstruction base;
3908
3909 IrInstruction *vector;
3910 IrInstruction *index;
3911};
3912
3905enum ResultLocId {3913enum ResultLocId {
3906 ResultLocIdInvalid,3914 ResultLocIdInvalid,
3907 ResultLocIdNone,3915 ResultLocIdNone,
src/codegen.cpp+10
...@@ -6002,6 +6002,14 @@ static LLVMValueRef ir_render_spill_end(CodeGen *g, IrExecutable *executable, Ir...@@ -6002,6 +6002,14 @@ static LLVMValueRef ir_render_spill_end(CodeGen *g, IrExecutable *executable, Ir
6002 zig_unreachable();6002 zig_unreachable();
6003}6003}
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
6005static void set_debug_location(CodeGen *g, IrInstruction *instruction) {6013static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
6006 AstNode *source_node = instruction->source_node;6014 AstNode *source_node = instruction->source_node;
6007 Scope *scope = instruction->scope;6015 Scope *scope = instruction->scope;
...@@ -6262,6 +6270,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -6262,6 +6270,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
6262 return ir_render_shuffle_vector(g, executable, (IrInstructionShuffleVector *) instruction);6270 return ir_render_shuffle_vector(g, executable, (IrInstructionShuffleVector *) instruction);
6263 case IrInstructionIdSplatGen:6271 case IrInstructionIdSplatGen:
6264 return ir_render_splat(g, executable, (IrInstructionSplatGen *) instruction);6272 return ir_render_splat(g, executable, (IrInstructionSplatGen *) instruction);
6273 case IrInstructionIdVectorExtractElem:
6274 return ir_render_vector_extract_elem(g, executable, (IrInstructionVectorExtractElem *) instruction);
6265 }6275 }
6266 zig_unreachable();6276 zig_unreachable();
6267}6277}
src/ir.cpp+29-1
...@@ -1083,6 +1083,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSpillEnd *) {...@@ -1083,6 +1083,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSpillEnd *) {
1083 return IrInstructionIdSpillEnd;1083 return IrInstructionIdSpillEnd;
1084}1084}
10851085
1086static constexpr IrInstructionId ir_instruction_id(IrInstructionVectorExtractElem *) {
1087 return IrInstructionIdVectorExtractElem;
1088}
1089
1086template<typename T>1090template<typename T>
1087static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {1091static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
1088 const char *name = nullptr;1092 const char *name = nullptr;
...@@ -3419,6 +3423,21 @@ static IrInstruction *ir_build_spill_end(IrBuilder *irb, Scope *scope, AstNode *...@@ -3419,6 +3423,21 @@ static IrInstruction *ir_build_spill_end(IrBuilder *irb, Scope *scope, AstNode *
3419 return &instruction->base;3423 return &instruction->base;
3420}3424}
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
3422static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {3441static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
3423 results[ReturnKindUnconditional] = 0;3442 results[ReturnKindUnconditional] = 0;
3424 results[ReturnKindError] = 0;3443 results[ReturnKindError] = 0;
...@@ -12965,8 +12984,15 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc...@@ -12965,8 +12984,15 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc
12965 // the type information does not contain enough information to actually12984 // the type information does not contain enough information to actually
12966 // perform a dereference.12985 // perform a dereference.
12967 if (ptr_type->data.pointer.vector_index == VECTOR_INDEX_RUNTIME) {12986 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 }
12968 ir_add_error(ira, ptr,12994 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)));
12970 return ira->codegen->invalid_instruction;12996 return ira->codegen->invalid_instruction;
12971 }12997 }
1297212998
...@@ -26036,6 +26062,7 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction...@@ -26036,6 +26062,7 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction
26036 case IrInstructionIdFrameSizeGen:26062 case IrInstructionIdFrameSizeGen:
26037 case IrInstructionIdAwaitGen:26063 case IrInstructionIdAwaitGen:
26038 case IrInstructionIdSplatGen:26064 case IrInstructionIdSplatGen:
26065 case IrInstructionIdVectorExtractElem:
26039 zig_unreachable();26066 zig_unreachable();
2604026067
26041 case IrInstructionIdReturn:26068 case IrInstructionIdReturn:
...@@ -26571,6 +26598,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -26571,6 +26598,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
26571 case IrInstructionIdAllocaSrc:26598 case IrInstructionIdAllocaSrc:
26572 case IrInstructionIdAllocaGen:26599 case IrInstructionIdAllocaGen:
26573 case IrInstructionIdSpillEnd:26600 case IrInstructionIdSpillEnd:
26601 case IrInstructionIdVectorExtractElem:
26574 return false;26602 return false;
2657526603
26576 case IrInstructionIdAsm:26604 case IrInstructionIdAsm:
src/ir_print.cpp+13
...@@ -370,6 +370,8 @@ const char* ir_instruction_type_str(IrInstructionId id) {...@@ -370,6 +370,8 @@ const char* ir_instruction_type_str(IrInstructionId id) {
370 return "SpillBegin";370 return "SpillBegin";
371 case IrInstructionIdSpillEnd:371 case IrInstructionIdSpillEnd:
372 return "SpillEnd";372 return "SpillEnd";
373 case IrInstructionIdVectorExtractElem:
374 return "VectorExtractElem";
373 }375 }
374 zig_unreachable();376 zig_unreachable();
375}377}
...@@ -1969,6 +1971,14 @@ static void ir_print_spill_end(IrPrint *irp, IrInstructionSpillEnd *instruction)...@@ -1969,6 +1971,14 @@ static void ir_print_spill_end(IrPrint *irp, IrInstructionSpillEnd *instruction)
1969 fprintf(irp->f, ")");1971 fprintf(irp->f, ")");
1970}1972}
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
1972static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction, bool trailing) {1982static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction, bool trailing) {
1973 ir_print_prefix(irp, instruction, trailing);1983 ir_print_prefix(irp, instruction, trailing);
1974 switch (instruction->id) {1984 switch (instruction->id) {
...@@ -2466,6 +2476,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction, bool...@@ -2466,6 +2476,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction, bool
2466 case IrInstructionIdSpillEnd:2476 case IrInstructionIdSpillEnd:
2467 ir_print_spill_end(irp, (IrInstructionSpillEnd *)instruction);2477 ir_print_spill_end(irp, (IrInstructionSpillEnd *)instruction);
2468 break;2478 break;
2479 case IrInstructionIdVectorExtractElem:
2480 ir_print_vector_extract_elem(irp, (IrInstructionVectorExtractElem *)instruction);
2481 break;
2469 }2482 }
2470 fprintf(irp->f, "\n");2483 fprintf(irp->f, "\n");
2471}2484}
test/compile_errors.zig+16
...@@ -24,6 +24,22 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -24,6 +24,22 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
24 "tmp.zig:4:20: note: referenced here",24 "tmp.zig:4:20: note: referenced here",
25 );25 );
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
27 cases.add(43 cases.add(
28 "using an unknown len ptr type instead of array",44 "using an unknown len ptr type instead of array",
29 \\const resolutions = [*][*]const u8{45 \\const resolutions = [*][*]const u8{
test/stage1/behavior/vector.zig+17
...@@ -199,3 +199,20 @@ test "store vector elements via comptime index" {...@@ -199,3 +199,20 @@ test "store vector elements via comptime index" {
199 S.doTheTest();199 S.doTheTest();
200 comptime S.doTheTest();200 comptime S.doTheTest();
201}201}
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}