It is possible to index vector elements with run-time indexes. This need was noticed here. GCC supports this:
#include <stdint.h>
typedef uint32_t __attribute__ ((vector_size (16))) uint32x4_t;
uint32_t extract(uint32x4_t vector, uint32_t index) {
return vector[index];
}
The current way Zig handles vector indexes, through the type system, prevents us from matching GCC's features:
// If the instruction is a element pointer instruction to a vector, we emit
// vector element extract instruction rather than load pointer. If the
// pointer type has non-VECTOR_INDEX_RUNTIME value, it would have been
// possible to implement this in the codegen for IrInstGenLoadPtr.
// However if it has VECTOR_INDEX_RUNTIME then we must emit a compile error
// if the vector index cannot be determined right here, right now, because
// the type information does not contain enough information to actually
// perform a dereference.
if (ptr_type->data.pointer.vector_index == VECTOR_INDEX_RUNTIME) {
if (ptr->id == IrInstGenIdElemPtr) {
IrInstGenElemPtr *elem_ptr = (IrInstGenElemPtr *)ptr;
IrInstGen *vector_loaded = ir_get_deref(ira, &elem_ptr->array_ptr->base,
elem_ptr->array_ptr, nullptr);
IrInstGen *elem_index = elem_ptr->elem_index;
return ir_build_vector_extract_elem(ira, source_instruction, vector_loaded, elem_index);
}
ir_add_error(ira, &ptr->base,
buf_sprintf("unable to determine vector element index of type '%s'", buf_ptr(&ptr_type->name)));
return ira->codegen->invalid_inst_gen;
}
Instead of using the type system, we need to write the vectors to the stack, and then index them with an inbounds GEP pointer, which can be calculated at run-time. LLVM does register allocation of the vector and avoids the stack.
It is possible to index vector elements with run-time indexes. This need was noticed here. GCC supports this:
The current way Zig handles vector indexes, through the type system, prevents us from matching GCC's features:
Instead of using the type system, we need to write the vectors to the stack, and then index them with an inbounds GEP pointer, which can be calculated at run-time. LLVM does register allocation of the vector and avoids the stack.