aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_backend_utility.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/llvm_backend_utility.cpp')
-rw-r--r--src/llvm_backend_utility.cpp326
1 files changed, 150 insertions, 176 deletions
diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp
index 88ec2f22c..7163f1d9e 100644
--- a/src/llvm_backend_utility.cpp
+++ b/src/llvm_backend_utility.cpp
@@ -39,6 +39,13 @@ bool lb_is_type_aggregate(Type *t) {
return false;
}
+void lb_emit_unreachable(lbProcedure *p) {
+ LLVMValueRef instr = LLVMGetLastInstruction(p->curr_block->block);
+ if (instr == nullptr || !lb_is_instr_terminating(instr)) {
+ lb_call_intrinsic(p, "llvm.trap", nullptr, 0, nullptr, 0);
+ LLVMBuildUnreachable(p->builder);
+ }
+}
lbValue lb_correct_endianness(lbProcedure *p, lbValue value) {
Type *src = core_type(value.type);
@@ -73,9 +80,6 @@ LLVMValueRef lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, LLVMValu
lb_type(p->module, t_int)
};
if (true || is_inlinable) {
- unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
- GB_ASSERT_MSG(id != 0, "Unable to find %s.%s.%s", name, LLVMPrintTypeToString(types[0]), LLVMPrintTypeToString(types[1]));
- LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
LLVMValueRef args[4] = {};
args[0] = LLVMBuildPointerCast(p->builder, ptr, types[0], "");
@@ -83,16 +87,18 @@ LLVMValueRef lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, LLVMValu
args[2] = LLVMBuildIntCast2(p->builder, len, types[1], /*signed*/false, "");
args[3] = LLVMConstInt(LLVMInt1TypeInContext(p->module->ctx), is_volatile, false);
- return LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
+ return lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
} else {
- LLVMValueRef ip = lb_lookup_runtime_procedure(p->module, str_lit("memset")).value;
+ lbValue pr = lb_lookup_runtime_procedure(p->module, str_lit("memset"));
LLVMValueRef args[3] = {};
args[0] = LLVMBuildPointerCast(p->builder, ptr, types[0], "");
args[1] = LLVMConstInt(LLVMInt32TypeInContext(p->module->ctx), 0, false);
args[2] = LLVMBuildIntCast2(p->builder, len, types[1], /*signed*/false, "");
- return LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
+ // We always get the function pointer type rather than the function and there is apparently no way around that?
+ LLVMTypeRef type = lb_type_internal_for_procedures_raw(p->module, pr.type);
+ return LLVMBuildCall2(p->builder, type, pr.value, args, gb_count_of(args), "");
}
}
@@ -346,44 +352,65 @@ lbValue lb_emit_try_has_value(lbProcedure *p, lbValue rhs) {
lbValue lb_emit_or_else(lbProcedure *p, Ast *arg, Ast *else_expr, TypeAndValue const &tv) {
+ if (arg->state_flags & StateFlag_DirectiveWasFalse) {
+ return lb_build_expr(p, else_expr);
+ }
+
lbValue lhs = {};
lbValue rhs = {};
lb_emit_try_lhs_rhs(p, arg, tv, &lhs, &rhs);
- LLVMValueRef incoming_values[2] = {};
- LLVMBasicBlockRef incoming_blocks[2] = {};
-
GB_ASSERT(else_expr != nullptr);
- lbBlock *then = lb_create_block(p, "or_else.then");
- lbBlock *done = lb_create_block(p, "or_else.done"); // NOTE(bill): Append later
- lbBlock *else_ = lb_create_block(p, "or_else.else");
-
- lb_emit_if(p, lb_emit_try_has_value(p, rhs), then, else_);
- lb_start_block(p, then);
Type *type = default_type(tv.type);
- incoming_values[0] = lb_emit_conv(p, lhs, type).value;
+ if (is_diverging_expr(else_expr)) {
+ lbBlock *then = lb_create_block(p, "or_else.then");
+ lbBlock *else_ = lb_create_block(p, "or_else.else");
- lb_emit_jump(p, done);
- lb_start_block(p, else_);
+ lb_emit_if(p, lb_emit_try_has_value(p, rhs), then, else_);
+ // NOTE(bill): else block needs to be straight afterwards to make sure that the actual value is used
+ // from the then block
+ lb_start_block(p, else_);
- incoming_values[1] = lb_emit_conv(p, lb_build_expr(p, else_expr), type).value;
+ lb_build_expr(p, else_expr);
+ lb_emit_unreachable(p); // add just in case
- lb_emit_jump(p, done);
- lb_start_block(p, done);
+ lb_start_block(p, then);
+ return lb_emit_conv(p, lhs, type);
+ } else {
+ LLVMValueRef incoming_values[2] = {};
+ LLVMBasicBlockRef incoming_blocks[2] = {};
- lbValue res = {};
- res.value = LLVMBuildPhi(p->builder, lb_type(p->module, type), "");
- res.type = type;
+ lbBlock *then = lb_create_block(p, "or_else.then");
+ lbBlock *done = lb_create_block(p, "or_else.done"); // NOTE(bill): Append later
+ lbBlock *else_ = lb_create_block(p, "or_else.else");
- GB_ASSERT(p->curr_block->preds.count >= 2);
- incoming_blocks[0] = p->curr_block->preds[0]->block;
- incoming_blocks[1] = p->curr_block->preds[1]->block;
+ lb_emit_if(p, lb_emit_try_has_value(p, rhs), then, else_);
+ lb_start_block(p, then);
- LLVMAddIncoming(res.value, incoming_values, incoming_blocks, 2);
+ incoming_values[0] = lb_emit_conv(p, lhs, type).value;
- return res;
+ lb_emit_jump(p, done);
+ lb_start_block(p, else_);
+
+ incoming_values[1] = lb_emit_conv(p, lb_build_expr(p, else_expr), type).value;
+
+ lb_emit_jump(p, done);
+ lb_start_block(p, done);
+
+ lbValue res = {};
+ res.value = LLVMBuildPhi(p->builder, lb_type(p->module, type), "");
+ res.type = type;
+
+ GB_ASSERT(p->curr_block->preds.count >= 2);
+ incoming_blocks[0] = p->curr_block->preds[0]->block;
+ incoming_blocks[1] = p->curr_block->preds[1]->block;
+
+ LLVMAddIncoming(res.value, incoming_values, incoming_blocks, 2);
+
+ return res;
+ }
}
void lb_build_return_stmt(lbProcedure *p, Slice<Ast *> const &return_results);
@@ -460,15 +487,11 @@ lbValue lb_emit_byte_swap(lbProcedure *p, lbValue value, Type *end_type) {
char const *name = "llvm.bswap";
LLVMTypeRef types[1] = {lb_type(p->module, value.type)};
- unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
- GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
- LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
- LLVMValueRef args[1] = {};
- args[0] = value.value;
+ LLVMValueRef args[1] = { value.value };
lbValue res = {};
- res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
+ res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
res.type = value.type;
if (is_type_float(original_type)) {
@@ -486,15 +509,10 @@ lbValue lb_emit_count_ones(lbProcedure *p, lbValue x, Type *type) {
char const *name = "llvm.ctpop";
LLVMTypeRef types[1] = {lb_type(p->module, type)};
- unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
- GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
- LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
-
- LLVMValueRef args[1] = {};
- args[0] = x.value;
+ LLVMValueRef args[1] = { x.value };
lbValue res = {};
- res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
+ res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
res.type = type;
return res;
}
@@ -515,16 +533,13 @@ lbValue lb_emit_count_trailing_zeros(lbProcedure *p, lbValue x, Type *type) {
char const *name = "llvm.cttz";
LLVMTypeRef types[1] = {lb_type(p->module, type)};
- unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
- GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
- LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
- LLVMValueRef args[2] = {};
- args[0] = x.value;
- args[1] = LLVMConstNull(LLVMInt1TypeInContext(p->module->ctx));
+ LLVMValueRef args[2] = {
+ x.value,
+ LLVMConstNull(LLVMInt1TypeInContext(p->module->ctx)) };
lbValue res = {};
- res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
+ res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
res.type = type;
return res;
}
@@ -534,16 +549,13 @@ lbValue lb_emit_count_leading_zeros(lbProcedure *p, lbValue x, Type *type) {
char const *name = "llvm.ctlz";
LLVMTypeRef types[1] = {lb_type(p->module, type)};
- unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
- GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
- LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
- LLVMValueRef args[2] = {};
- args[0] = x.value;
- args[1] = LLVMConstNull(LLVMInt1TypeInContext(p->module->ctx));
+ LLVMValueRef args[2] = {
+ x.value,
+ LLVMConstNull(LLVMInt1TypeInContext(p->module->ctx)) };
lbValue res = {};
- res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
+ res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
res.type = type;
return res;
}
@@ -555,15 +567,11 @@ lbValue lb_emit_reverse_bits(lbProcedure *p, lbValue x, Type *type) {
char const *name = "llvm.bitreverse";
LLVMTypeRef types[1] = {lb_type(p->module, type)};
- unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
- GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
- LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
- LLVMValueRef args[1] = {};
- args[0] = x.value;
+ LLVMValueRef args[1] = { x.value };
lbValue res = {};
- res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
+ res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
res.type = type;
return res;
}
@@ -984,6 +992,11 @@ lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
case 0: result_type = t->RelativeSlice.base_integer; break;
case 1: result_type = t->RelativeSlice.base_integer; break;
}
+ } else if (is_type_soa_pointer(t)) {
+ switch (index) {
+ case 0: result_type = alloc_type_pointer(t->SoaPointer.elem); break;
+ case 1: result_type = t_int; break;
+ }
} else {
GB_PANIC("TODO(bill): struct_gep type: %s, %d", type_to_string(s.type), index);
}
@@ -994,15 +1007,16 @@ lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
index = lb_convert_struct_index(p->module, t, index);
if (lb_is_const(s)) {
+ // NOTE(bill): this cannot be replaced with lb_emit_epi
lbModule *m = p->module;
lbValue res = {};
LLVMValueRef indices[2] = {llvm_zero(m), LLVMConstInt(lb_type(m, t_i32), index, false)};
- res.value = LLVMConstGEP(s.value, indices, gb_count_of(indices));
+ res.value = LLVMConstGEP2(lb_type(m, type_deref(s.type)), s.value, indices, gb_count_of(indices));
res.type = alloc_type_pointer(result_type);
return res;
} else {
lbValue res = {};
- LLVMTypeRef st = LLVMGetElementType(LLVMTypeOf(s.value));
+ LLVMTypeRef st = lb_type(p->module, type_deref(s.type));
// gb_printf_err("%s\n", type_to_string(s.type));
// gb_printf_err("%s\n", LLVMPrintTypeToString(LLVMTypeOf(s.value)));
// gb_printf_err("%d\n", index);
@@ -1010,7 +1024,7 @@ lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
unsigned count = LLVMCountStructElementTypes(st);
GB_ASSERT_MSG(count >= cast(unsigned)index, "%u %d %d", count, index, original_index);
- res.value = LLVMBuildStructGEP(p->builder, s.value, cast(unsigned)index, "");
+ res.value = LLVMBuildStructGEP2(p->builder, st, s.value, cast(unsigned)index, "");
res.type = alloc_type_pointer(result_type);
return res;
}
@@ -1114,6 +1128,13 @@ lbValue lb_emit_struct_ev(lbProcedure *p, lbValue s, i32 index) {
result_type = t->Array.elem;
break;
+ case Type_SoaPointer:
+ switch (index) {
+ case 0: result_type = alloc_type_pointer(t->SoaPointer.elem); break;
+ case 1: result_type = t_int; break;
+ }
+ break;
+
default:
GB_PANIC("TODO(bill): struct_ev type: %s, %d", type_to_string(s.type), index);
break;
@@ -1141,7 +1162,28 @@ lbValue lb_emit_deep_field_gep(lbProcedure *p, lbValue e, Selection sel) {
}
type = core_type(type);
- if (is_type_quaternion(type)) {
+ if (type->kind == Type_SoaPointer) {
+ lbValue addr = lb_emit_struct_ep(p, e, 0);
+ lbValue index = lb_emit_struct_ep(p, e, 1);
+ addr = lb_emit_load(p, addr);
+ index = lb_emit_load(p, index);
+
+ i32 first_index = sel.index[0];
+ Selection sub_sel = sel;
+ sub_sel.index.data += 1;
+ sub_sel.index.count -= 1;
+
+ lbValue arr = lb_emit_struct_ep(p, addr, first_index);
+
+ Type *t = base_type(type_deref(addr.type));
+ GB_ASSERT(is_type_soa_struct(t));
+
+ if (t->Struct.soa_kind == StructSoa_Fixed) {
+ e = lb_emit_array_ep(p, arr, index);
+ } else {
+ e = lb_emit_ptr_offset(p, lb_emit_load(p, arr), index);
+ }
+ } else if (is_type_quaternion(type)) {
e = lb_emit_struct_ep(p, e, index);
} else if (is_type_raw_union(type)) {
type = get_struct_field_type(type, index);
@@ -1216,7 +1258,12 @@ lbValue lb_emit_array_ep(lbProcedure *p, lbValue s, lbValue index) {
Type *ptr = base_array_type(st);
lbValue res = {};
- res.value = LLVMBuildGEP(p->builder, s.value, indices, 2, "");
+
+ if (LLVMIsConstant(s.value) && LLVMIsConstant(index.value)) {
+ res.value = LLVMConstGEP2(lb_type(p->module, st), s.value, indices, gb_count_of(indices));
+ } else {
+ res.value = LLVMBuildGEP2(p->builder, lb_type(p->module, st), s.value, indices, gb_count_of(indices), "");
+ }
res.type = alloc_type_pointer(ptr);
return res;
}
@@ -1226,24 +1273,16 @@ lbValue lb_emit_array_epi(lbProcedure *p, lbValue s, isize index) {
GB_ASSERT(is_type_pointer(t));
Type *st = base_type(type_deref(t));
GB_ASSERT_MSG(is_type_array(st) || is_type_enumerated_array(st) || is_type_matrix(st), "%s", type_to_string(st));
-
GB_ASSERT(0 <= index);
- Type *ptr = base_array_type(st);
-
-
- LLVMValueRef indices[2] = {
- LLVMConstInt(lb_type(p->module, t_int), 0, false),
- LLVMConstInt(lb_type(p->module, t_int), cast(unsigned)index, false),
- };
-
- lbValue res = {};
- if (lb_is_const(s)) {
- res.value = LLVMConstGEP(s.value, indices, gb_count_of(indices));
- } else {
- res.value = LLVMBuildGEP(p->builder, s.value, indices, gb_count_of(indices), "");
- }
- res.type = alloc_type_pointer(ptr);
- return res;
+ return lb_emit_epi(p, s, index);
+}
+lbValue lb_emit_array_epi(lbModule *m, lbValue s, isize index) {
+ Type *t = s.type;
+ GB_ASSERT(is_type_pointer(t));
+ Type *st = base_type(type_deref(t));
+ GB_ASSERT_MSG(is_type_array(st) || is_type_enumerated_array(st) || is_type_matrix(st), "%s", type_to_string(st));
+ GB_ASSERT(0 <= index);
+ return lb_emit_epi(m, s, index);
}
lbValue lb_emit_ptr_offset(lbProcedure *p, lbValue ptr, lbValue index) {
@@ -1251,11 +1290,12 @@ lbValue lb_emit_ptr_offset(lbProcedure *p, lbValue ptr, lbValue index) {
LLVMValueRef indices[1] = {index.value};
lbValue res = {};
res.type = ptr.type;
+ LLVMTypeRef type = lb_type(p->module, type_deref(res.type, true));
if (lb_is_const(ptr) && lb_is_const(index)) {
- res.value = LLVMConstGEP(ptr.value, indices, 1);
+ res.value = LLVMConstGEP2(type, ptr.value, indices, 1);
} else {
- res.value = LLVMBuildGEP(p->builder, ptr.value, indices, 1, "");
+ res.value = LLVMBuildGEP2(p->builder, type, ptr.value, indices, 1, "");
}
return res;
}
@@ -1264,63 +1304,18 @@ lbValue lb_emit_matrix_epi(lbProcedure *p, lbValue s, isize row, isize column) {
Type *t = s.type;
GB_ASSERT(is_type_pointer(t));
Type *mt = base_type(type_deref(t));
-
- Type *ptr = base_array_type(mt);
-
if (column == 0) {
GB_ASSERT_MSG(is_type_matrix(mt) || is_type_array_like(mt), "%s", type_to_string(mt));
-
- LLVMValueRef indices[2] = {
- LLVMConstInt(lb_type(p->module, t_int), 0, false),
- LLVMConstInt(lb_type(p->module, t_int), cast(unsigned)row, false),
- };
-
- lbValue res = {};
- if (lb_is_const(s)) {
- res.value = LLVMConstGEP(s.value, indices, gb_count_of(indices));
- } else {
- res.value = LLVMBuildGEP(p->builder, s.value, indices, gb_count_of(indices), "");
- }
-
- Type *ptr = base_array_type(mt);
- res.type = alloc_type_pointer(ptr);
- return res;
+ return lb_emit_epi(p, s, row);
} else if (row == 0 && is_type_array_like(mt)) {
- LLVMValueRef indices[2] = {
- LLVMConstInt(lb_type(p->module, t_int), 0, false),
- LLVMConstInt(lb_type(p->module, t_int), cast(unsigned)column, false),
- };
-
- lbValue res = {};
- if (lb_is_const(s)) {
- res.value = LLVMConstGEP(s.value, indices, gb_count_of(indices));
- } else {
- res.value = LLVMBuildGEP(p->builder, s.value, indices, gb_count_of(indices), "");
- }
-
- Type *ptr = base_array_type(mt);
- res.type = alloc_type_pointer(ptr);
- return res;
+ return lb_emit_epi(p, s, column);
}
GB_ASSERT_MSG(is_type_matrix(mt), "%s", type_to_string(mt));
isize offset = matrix_indices_to_offset(mt, row, column);
-
- LLVMValueRef indices[2] = {
- LLVMConstInt(lb_type(p->module, t_int), 0, false),
- LLVMConstInt(lb_type(p->module, t_int), cast(unsigned)offset, false),
- };
-
- lbValue res = {};
- if (lb_is_const(s)) {
- res.value = LLVMConstGEP(s.value, indices, gb_count_of(indices));
- } else {
- res.value = LLVMBuildGEP(p->builder, s.value, indices, gb_count_of(indices), "");
- }
- res.type = alloc_type_pointer(ptr);
- return res;
+ return lb_emit_epi(p, s, offset);
}
lbValue lb_emit_matrix_ep(lbProcedure *p, lbValue s, lbValue row, lbValue column) {
@@ -1343,11 +1338,12 @@ lbValue lb_emit_matrix_ep(lbProcedure *p, lbValue s, lbValue row, lbValue column
index,
};
+ LLVMTypeRef type = lb_type(p->module, mt);
lbValue res = {};
if (lb_is_const(s)) {
- res.value = LLVMConstGEP(s.value, indices, gb_count_of(indices));
+ res.value = LLVMConstGEP2(type, s.value, indices, gb_count_of(indices));
} else {
- res.value = LLVMBuildGEP(p->builder, s.value, indices, gb_count_of(indices), "");
+ res.value = LLVMBuildGEP2(p->builder, type, s.value, indices, gb_count_of(indices), "");
}
res.type = alloc_type_pointer(ptr);
return res;
@@ -1551,18 +1547,12 @@ lbValue lb_emit_mul_add(lbProcedure *p, lbValue a, lbValue b, lbValue c, Type *t
if (is_possible) {
char const *name = "llvm.fma";
- unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
- GB_ASSERT_MSG(id != 0, "Unable to find %s", name);
-
- LLVMTypeRef types[1] = {};
- types[0] = lb_type(m, t);
-
- LLVMValueRef ip = LLVMGetIntrinsicDeclaration(m->mod, id, types, gb_count_of(types));
- LLVMValueRef values[3] = {};
- values[0] = a.value;
- values[1] = b.value;
- values[2] = c.value;
- LLVMValueRef call = LLVMBuildCall(p->builder, ip, values, gb_count_of(values), "");
+ LLVMTypeRef types[1] = { lb_type(m, t) };
+ LLVMValueRef values[3] = {
+ a.value,
+ b.value,
+ c.value };
+ LLVMValueRef call = lb_call_intrinsic(p, name, values, gb_count_of(values), types, gb_count_of(types));
return {call, t};
} else {
lbValue x = lb_emit_arith(p, Token_Mul, a, b, t);
@@ -1661,7 +1651,7 @@ LLVMValueRef llvm_vector_expand_to_power_of_two(lbProcedure *p, LLVMValueRef val
LLVMValueRef llvm_vector_reduce_add(lbProcedure *p, LLVMValueRef value) {
LLVMTypeRef type = LLVMTypeOf(value);
GB_ASSERT(LLVMGetTypeKind(type) == LLVMVectorTypeKind);
- LLVMTypeRef elem = LLVMGetElementType(type);
+ LLVMTypeRef elem = OdinLLVMGetVectorElementType(type);
unsigned len = LLVMGetVectorSize(type);
if (len == 0) {
return LLVMConstNull(type);
@@ -1691,15 +1681,9 @@ LLVMValueRef llvm_vector_reduce_add(lbProcedure *p, LLVMValueRef value) {
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
if (id != 0 && false) {
- LLVMTypeRef types[1] = {};
- types[0] = type;
-
- LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
- LLVMValueRef values[2] = {};
- values[0] = LLVMConstNull(elem);
- values[1] = value;
- LLVMValueRef call = LLVMBuildCall(p->builder, ip, values+value_offset, value_count, "");
- return call;
+ LLVMTypeRef types[1] = { type };
+ LLVMValueRef values[2] = { LLVMConstNull(elem), value };
+ return lb_call_intrinsic(p, name, values + value_offset, value_count, types, gb_count_of(types));
}
// Manual reduce
@@ -1743,7 +1727,7 @@ LLVMValueRef llvm_vector_reduce_add(lbProcedure *p, LLVMValueRef value) {
LLVMValueRef llvm_vector_add(lbProcedure *p, LLVMValueRef a, LLVMValueRef b) {
GB_ASSERT(LLVMTypeOf(a) == LLVMTypeOf(b));
- LLVMTypeRef elem = LLVMGetElementType(LLVMTypeOf(a));
+ LLVMTypeRef elem = OdinLLVMGetVectorElementType(LLVMTypeOf(a));
if (LLVMGetTypeKind(elem) == LLVMIntegerTypeKind) {
return LLVMBuildAdd(p->builder, a, b, "");
@@ -1754,7 +1738,7 @@ LLVMValueRef llvm_vector_add(lbProcedure *p, LLVMValueRef a, LLVMValueRef b) {
LLVMValueRef llvm_vector_mul(lbProcedure *p, LLVMValueRef a, LLVMValueRef b) {
GB_ASSERT(LLVMTypeOf(a) == LLVMTypeOf(b));
- LLVMTypeRef elem = LLVMGetElementType(LLVMTypeOf(a));
+ LLVMTypeRef elem = OdinLLVMGetVectorElementType(LLVMTypeOf(a));
if (LLVMGetTypeKind(elem) == LLVMIntegerTypeKind) {
return LLVMBuildMul(p->builder, a, b, "");
@@ -1768,14 +1752,13 @@ LLVMValueRef llvm_vector_dot(lbProcedure *p, LLVMValueRef a, LLVMValueRef b) {
}
LLVMValueRef llvm_vector_mul_add(lbProcedure *p, LLVMValueRef a, LLVMValueRef b, LLVMValueRef c) {
- lbModule *m = p->module;
-
+
LLVMTypeRef t = LLVMTypeOf(a);
GB_ASSERT(t == LLVMTypeOf(b));
GB_ASSERT(t == LLVMTypeOf(c));
GB_ASSERT(LLVMGetTypeKind(t) == LLVMVectorTypeKind);
- LLVMTypeRef elem = LLVMGetElementType(t);
+ LLVMTypeRef elem = OdinLLVMGetVectorElementType(t);
bool is_possible = false;
@@ -1791,18 +1774,9 @@ LLVMValueRef llvm_vector_mul_add(lbProcedure *p, LLVMValueRef a, LLVMValueRef b,
if (is_possible) {
char const *name = "llvm.fmuladd";
- unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
- GB_ASSERT_MSG(id != 0, "Unable to find %s", name);
-
- LLVMTypeRef types[1] = {};
- types[0] = t;
-
- LLVMValueRef ip = LLVMGetIntrinsicDeclaration(m->mod, id, types, gb_count_of(types));
- LLVMValueRef values[3] = {};
- values[0] = a;
- values[1] = b;
- values[2] = c;
- LLVMValueRef call = LLVMBuildCall(p->builder, ip, values, gb_count_of(values), "");
+ LLVMTypeRef types[1] = { t };
+ LLVMValueRef values[3] = { a, b, c};
+ LLVMValueRef call = lb_call_intrinsic(p, name, values, gb_count_of(values), types, gb_count_of(types));
return call;
} else {
LLVMValueRef x = llvm_vector_mul(p, a, b);
@@ -1817,7 +1791,7 @@ LLVMValueRef llvm_get_inline_asm(LLVMTypeRef func_type, String const &str, Strin
cast(char *)clobbers.text, cast(size_t)clobbers.len,
has_side_effects, is_align_stack,
dialect
- #if LLVM_VERSION_MAJOR >= 13
+ #if LLVM_VERSION_MAJOR >= 13
, /*CanThrow*/false
#endif
);