diff options
| author | gingerBill <bill@gingerbill.org> | 2021-10-25 13:10:56 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-10-25 13:10:56 +0100 |
| commit | a440d8d812223961f0934aefecaef4975a604c43 (patch) | |
| tree | aebedd62f7ed3a8956d5b94a91c74fb72dee5d94 /src/llvm_backend_utility.cpp | |
| parent | aaaddd03a6fc7194fa9315f802e369a0f62b9e07 (diff) | |
Improve use of vector muladd operations
Diffstat (limited to 'src/llvm_backend_utility.cpp')
| -rw-r--r-- | src/llvm_backend_utility.cpp | 44 |
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 |