aboutsummaryrefslogtreecommitdiff
path: root/src/llvm_backend_utility.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-10-25 13:10:56 +0100
committergingerBill <bill@gingerbill.org>2021-10-25 13:10:56 +0100
commita440d8d812223961f0934aefecaef4975a604c43 (patch)
treeaebedd62f7ed3a8956d5b94a91c74fb72dee5d94 /src/llvm_backend_utility.cpp
parentaaaddd03a6fc7194fa9315f802e369a0f62b9e07 (diff)
Improve use of vector muladd operations
Diffstat (limited to 'src/llvm_backend_utility.cpp')
-rw-r--r--src/llvm_backend_utility.cpp44
1 files changed, 44 insertions, 0 deletions
diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp
index af773d467..9bb22b50b 100644
--- a/src/llvm_backend_utility.cpp
+++ b/src/llvm_backend_utility.cpp
@@ -1631,4 +1631,48 @@ LLVMValueRef llvm_vector_mul(lbProcedure *p, LLVMValueRef a, LLVMValueRef b) {
LLVMValueRef llvm_vector_dot(lbProcedure *p, LLVMValueRef a, LLVMValueRef b) {
return llvm_vector_reduce_add(p, llvm_vector_mul(p, a, 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);
+
+ bool is_possible = false;
+
+ switch (LLVMGetTypeKind(elem)) {
+ case LLVMHalfTypeKind:
+ is_possible = true;
+ break;
+ case LLVMFloatTypeKind:
+ case LLVMDoubleTypeKind:
+ is_possible = true;
+ break;
+ }
+
+ 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), "");
+ return call;
+ } else {
+ LLVMValueRef x = llvm_vector_mul(p, a, b);
+ LLVMValueRef y = llvm_vector_add(p, x, c);
+ return y;
+ }
} \ No newline at end of file