stage2: implement runtime array multiplication

Additionally:

 * Sema: fix array cat/mul not setting the sentinel value
   - This required an LLVM backend enhancement to the handling of the
     AIR instruction aggregate_init that likely needs to be
     propagated to the other backends.
 * Sema: report integer overflow of array concatenation in a proper
   compile error instead of crashing.
 * Sema: fix not using proper pointer address space for array cat/mul
This commit is contained in:
Andrew Kelley
2022-05-25 22:23:32 -07:00
parent b82081e709
commit 83f69af971
4 changed files with 236 additions and 93 deletions

View File

@@ -7728,7 +7728,14 @@ pub const FuncGen = struct {
const alloca_inst = self.buildAlloca(llvm_result_ty);
alloca_inst.setAlignment(result_ty.abiAlignment(target));
const elem_ty = result_ty.childType();
const array_info = result_ty.arrayInfo();
var elem_ptr_payload: Type.Payload.Pointer = .{
.data = .{
.pointee_type = array_info.elem_type,
.@"addrspace" = .generic,
},
};
const elem_ptr_ty = Type.initPayload(&elem_ptr_payload.base);
for (elements) |elem, i| {
const indices: [2]*const llvm.Value = .{
@@ -7737,13 +7744,19 @@ pub const FuncGen = struct {
};
const elem_ptr = self.builder.buildInBoundsGEP(alloca_inst, &indices, indices.len, "");
const llvm_elem = try self.resolveInst(elem);
var elem_ptr_payload: Type.Payload.Pointer = .{
.data = .{
.pointee_type = elem_ty,
.@"addrspace" = .generic,
},
self.store(elem_ptr, elem_ptr_ty, llvm_elem, .NotAtomic);
}
if (array_info.sentinel) |sent_val| {
const indices: [2]*const llvm.Value = .{
llvm_usize.constNull(),
llvm_usize.constInt(@intCast(c_uint, array_info.len), .False),
};
const elem_ptr_ty = Type.initPayload(&elem_ptr_payload.base);
const elem_ptr = self.builder.buildInBoundsGEP(alloca_inst, &indices, indices.len, "");
const llvm_elem = try self.dg.lowerValue(.{
.ty = array_info.elem_type,
.val = sent_val,
});
self.store(elem_ptr, elem_ptr_ty, llvm_elem, .NotAtomic);
}