diff options
| author | gingerBill <bill@gingerbill.org> | 2021-10-28 00:57:10 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2021-10-28 00:57:10 +0100 |
| commit | 70793236abc278dd51ca577b35ca1757851380d3 (patch) | |
| tree | b3241ea3fae32b104623e1c4ea3c3dfba3cccd7b /src | |
| parent | 0a1ef1e59da47a15a04967a407ff3e8a7a2ffea4 (diff) | |
Support `llvm_vector_reduce_add` if the LLVM intrinsic is not supported
Diffstat (limited to 'src')
| -rw-r--r-- | src/llvm_backend_utility.cpp | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index e2249171c..eccf01319 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -1567,6 +1567,10 @@ LLVMValueRef llvm_vector_reduce_add(lbProcedure *p, LLVMValueRef value) { LLVMTypeRef type = LLVMTypeOf(value); GB_ASSERT(LLVMGetTypeKind(type) == LLVMVectorTypeKind); LLVMTypeRef elem = LLVMGetElementType(type); + unsigned len = LLVMGetVectorSize(type); + if (len == 0) { + return LLVMConstNull(type); + } char const *name = nullptr; i32 value_offset = 0; @@ -1591,17 +1595,30 @@ LLVMValueRef llvm_vector_reduce_add(lbProcedure *p, LLVMValueRef value) { } unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name)); - GB_ASSERT_MSG(id != 0, "Unable to find %s", name); + if (id != 0) { + 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] = {}; - types[0] = type; + // Manual reduce - 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; + LLVMValueRef sum = LLVMBuildExtractElement(p->builder, value, lb_const_int(p->module, t_u32, 0).value, ""); + for (unsigned i = 0; i < len; i++) { + LLVMValueRef val = LLVMBuildExtractElement(p->builder, value, lb_const_int(p->module, t_u32, i).value, ""); + if (LLVMGetTypeKind(elem) == LLVMIntegerTypeKind) { + sum = LLVMBuildAdd(p->builder, sum, val, ""); + } else { + sum = LLVMBuildFAdd(p->builder, sum, val, ""); + } + } + return sum; } LLVMValueRef llvm_vector_add(lbProcedure *p, LLVMValueRef a, LLVMValueRef b) { |