GCC Code Coverage Report


Directory: ./
File: openvdb_ax/openvdb_ax/codegen/StandardFunctions.cc
Date: 2022-07-25 17:40:05
Exec Total Coverage
Lines: 1652 1677 98.5%
Functions: 171 177 96.6%
Branches: 1996 3988 50.1%

Line Branch Exec Source
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3
4 /// @file codegen/StandardFunctions.cc
5 ///
6 /// @authors Nick Avramoussis, Richard Jones, Francisco Gochez
7 ///
8 /// @brief Definitions for all standard functions supported by AX. A
9 /// standard function is one that is supported no matter the input
10 /// primitive type and rely either solely on AX types or core AX
11 /// intrinsics.
12
13 #include "Functions.h"
14 #include "FunctionTypes.h"
15 #include "Types.h"
16 #include "Utils.h"
17
18 #include "../Exceptions.h"
19 #include "../math/OpenSimplexNoise.h"
20 #include "../compiler/CompilerOptions.h"
21 #include "../compiler/CustomData.h"
22
23 #include <tbb/enumerable_thread_specific.h>
24
25 #include <llvm/IR/Intrinsics.h>
26 #include <llvm/IR/Instructions.h>
27
28 #include <unordered_map>
29 #include <functional>
30 #include <random>
31 #include <cmath>
32 #include <cstdlib>
33 #include <numeric> // std::iota
34 #include <stddef.h>
35 #include <stdint.h>
36
37 namespace openvdb {
38 OPENVDB_USE_VERSION_NAMESPACE
39 namespace OPENVDB_VERSION_NAME {
40
41 namespace ax {
42 namespace codegen {
43
44 namespace
45 {
46
47 // Reduce a size_t hash down into an unsigned int, taking all bits in the
48 // size_t into account. We achieve this by repeatedly XORing as many bytes
49 // that fit into an unsigned int, and then shift those bytes out of the
50 // hash. We repeat until we have no bits left in the hash.
51 template <typename SeedType>
52 inline SeedType hashToSeed(size_t hash) {
53 SeedType seed = 0;
54 378 do {
55
2/2
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 189 times.
378 seed ^= (SeedType) hash;
56 } while (hash >>= sizeof(SeedType) * 8);
57 return seed;
58 }
59
60 struct SimplexNoise
61 {
62 // Open simplex noise - Visually axis-decorrelated coherent noise algorithm
63 // based on the simplectic honeycomb.
64 // See https://gist.github.com/KdotJPG/b1270127455a94ac5d19
65 1188 inline static double noise(double x, double y, double z)
66 {
67
4/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1187 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
1188 static const OSN::OSNoise noiseGenerator = OSN::OSNoise();
68 1188 const double result = noiseGenerator.eval<double>(x, y, z);
69 // adjust result so that it lies between 0 and 1, since
70 // Noise::eval returns a number between -1 and 1
71 1188 return (result + 1.0) * 0.5;
72 }
73 };
74
75 }
76
77 ///////////////////////////////////////////////////////////////////////////
78 ///////////////////////////////////////////////////////////////////////////
79
80 #define DEFINE_LLVM_FP_INTRINSIC(Identifier, Doc, UseIR) \
81 inline FunctionGroup::UniquePtr llvm_##Identifier(const FunctionOptions& op) \
82 { \
83 static auto generate = \
84 [](const std::vector<llvm::Value*>& args, \
85 llvm::IRBuilder<>& B) -> llvm::Value* \
86 { \
87 llvm::Module* M = B.GetInsertBlock()->getParent()->getParent(); \
88 llvm::Function* function = \
89 llvm::Intrinsic::getDeclaration(M, \
90 llvm::Intrinsic::Identifier, args[0]->getType()); \
91 assert(function); \
92 return B.CreateCall(function, args); \
93 }; \
94 \
95 return FunctionBuilder(#Identifier) \
96 .addSignature<double(double)>(generate, (double(*)(double))(std::Identifier)) \
97 .addSignature<float(float)>(generate, (float(*)(float))(std::Identifier)) \
98 .setArgumentNames({"n"}) \
99 .addFunctionAttribute(llvm::Attribute::ReadOnly) \
100 .addFunctionAttribute(llvm::Attribute::NoRecurse) \
101 .addFunctionAttribute(llvm::Attribute::NoUnwind) \
102 .addFunctionAttribute(llvm::Attribute::AlwaysInline) \
103 .setConstantFold(op.mConstantFoldCBindings) \
104 .setPreferredImpl((UseIR && op.mPrioritiseIR) ? \
105 FunctionBuilder::IR : FunctionBuilder::C) \
106 .setDocumentation(Doc) \
107 .get(); \
108 } \
109
110 #define DEFINE_AX_C_FP_BINDING(Identifier, Doc) \
111 inline FunctionGroup::UniquePtr ax##Identifier(const FunctionOptions& op) \
112 { \
113 return FunctionBuilder(#Identifier) \
114 .addSignature<double(double)>((double(*)(double))(std::Identifier)) \
115 .addSignature<float(float)>((float(*)(float))(std::Identifier)) \
116 .setArgumentNames({"arg"}) \
117 .addFunctionAttribute(llvm::Attribute::ReadOnly) \
118 .addFunctionAttribute(llvm::Attribute::NoRecurse) \
119 .addFunctionAttribute(llvm::Attribute::NoUnwind) \
120 .addFunctionAttribute(llvm::Attribute::AlwaysInline) \
121 .setConstantFold(op.mConstantFoldCBindings) \
122 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C) \
123 .setDocumentation(Doc) \
124 .get(); \
125 }
126
127 ///////////////////////////////////////////////////////////////////////////
128 ///////////////////////////////////////////////////////////////////////////
129
130 // Memory
131
132 1 inline FunctionGroup::UniquePtr axmalloc(const FunctionOptions& op)
133 {
134 static auto generate =
135 [](const std::vector<llvm::Value*>& args,
136 llvm::IRBuilder<>& B) -> llvm::Value*
137 {
138 llvm::BasicBlock* BB = B.GetInsertBlock();
139 /// @note The return type is i8* as the void* type is aliased to
140 /// i8* in Types.h.
141 /// @todo should probably remove this alias and use i8* explicitly
142 llvm::Instruction* inst =
143 llvm::CallInst::CreateMalloc(BB, // location
144 B.getInt64Ty(), // int ptr type
145 B.getInt8Ty(), // return type
146 args[0], // size
147 nullptr,
148 nullptr);
149 assert(inst);
150 B.Insert(inst);
151 return inst;
152 };
153
154 1 return FunctionBuilder("axmalloc")
155 2 .addSignature<void*(size_t)>(generate, std::malloc, "malloc") // symbol is malloc, not ax.malloc
156
3/8
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
2 .setArgumentNames({"size"})
157 .setEmbedIR(true) // Embed the call to CreateMalloc, otherwise we gen a function "malloc" which calls "malloc"!
158 .setConstantFold(false)
159
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
160 .setDocumentation("Allocate memory.")
161
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 .get();
162 }
163
164 1 inline FunctionGroup::UniquePtr axfree(const FunctionOptions& op)
165 {
166 static auto generate =
167 [](const std::vector<llvm::Value*>& args,
168 llvm::IRBuilder<>& B) -> llvm::Value*
169 {
170 llvm::BasicBlock* BB = B.GetInsertBlock();
171 llvm::Instruction* inst = llvm::CallInst::CreateFree(args[0], BB);
172 assert(inst);
173 B.Insert(inst);
174 return nullptr;
175 };
176
177 1 return FunctionBuilder("axfree")
178 2 .addSignature<void(void*)>(generate, std::free, "free") // symbol is free, not ax.free
179
3/8
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
2 .setArgumentNames({"ptr"})
180 .setEmbedIR(true) // Embed the call to CreateFree, otherwise we gen a function "free" which calls "free"!
181 .setConstantFold(false)
182
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
183 .setDocumentation("Free memory.")
184
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 .get();
185 }
186
187 1 inline FunctionGroup::UniquePtr axrealloc(const FunctionOptions&)
188 {
189 1 return FunctionBuilder("axrealloc")
190
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 .addSignature<void*(void*,size_t)>(std::realloc, "realloc")
191
2/4
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 .setArgumentNames({"ptr", "size"})
192 .setConstantFold(false)
193 .setPreferredImpl(FunctionBuilder::C)
194 .setDocumentation("Reallocate memory.")
195
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 .get();
196 }
197
198 // Intrinsics
199
200
11/24
✗ Branch 1 not taken.
✓ Branch 2 taken 40 times.
✓ Branch 4 taken 125 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 125 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 125 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 125 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 125 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 32 times.
✓ Branch 19 taken 93 times.
✓ Branch 21 taken 125 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 125 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 125 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
1894 DEFINE_LLVM_FP_INTRINSIC(sqrt, "Computes the square root of arg.", true)
201
11/24
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✓ Branch 19 taken 5 times.
✓ Branch 21 taken 13 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 13 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
214 DEFINE_LLVM_FP_INTRINSIC(sin, "Computes the sine of arg (measured in radians).", true)
202
11/24
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✓ Branch 19 taken 5 times.
✓ Branch 21 taken 13 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 13 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
214 DEFINE_LLVM_FP_INTRINSIC(cos, "Computes the cosine of arg (measured in radians).", true)
203
11/24
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✓ Branch 19 taken 5 times.
✓ Branch 21 taken 13 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 13 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
214 DEFINE_LLVM_FP_INTRINSIC(log, "Computes the natural (base e) logarithm of arg.", true)
204
11/24
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✓ Branch 19 taken 5 times.
✓ Branch 21 taken 13 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 13 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
214 DEFINE_LLVM_FP_INTRINSIC(log10, "Computes the common (base-10) logarithm of arg.", true)
205
11/24
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✓ Branch 19 taken 5 times.
✓ Branch 21 taken 13 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 13 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
214 DEFINE_LLVM_FP_INTRINSIC(exp, "Computes e (Euler's number, 2.7182818...) raised to the given power arg.", true)
206
11/24
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✓ Branch 4 taken 617 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 617 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 617 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 617 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 617 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 32 times.
✓ Branch 19 taken 585 times.
✓ Branch 21 taken 617 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 617 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 617 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
8766 DEFINE_LLVM_FP_INTRINSIC(fabs, "Computes the absolute value of a floating point value arg.", true)
207
11/24
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✓ Branch 4 taken 49 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 49 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 49 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 49 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 49 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 24 times.
✓ Branch 19 taken 25 times.
✓ Branch 21 taken 49 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 49 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 49 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
782 DEFINE_LLVM_FP_INTRINSIC(floor, "Computes the largest integer value not greater than arg.", true)
208
11/24
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✓ Branch 19 taken 5 times.
✓ Branch 21 taken 13 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 13 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
214 DEFINE_LLVM_FP_INTRINSIC(ceil, "Computes the smallest integer value not less than arg.", true)
209
11/24
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✓ Branch 19 taken 5 times.
✓ Branch 21 taken 13 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 13 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
214 DEFINE_LLVM_FP_INTRINSIC(round, "Computes the nearest integer value to arg (in floating-point format),"
210 " rounding halfway cases away from zero.", true)
211
212 // On Windows (or using the Win CRT) log2 and exp2 intrinsics seem to cause a
213 // crash. Still yet to track this down. For now use the C bindings.
214 #ifdef _MSC_VER
215 DEFINE_LLVM_FP_INTRINSIC(log2, "Computes the binary (base-2) logarithm of arg.", false)
216 DEFINE_LLVM_FP_INTRINSIC(exp2, "Computes 2 raised to the given power arg.", false)
217 #else
218
11/24
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✓ Branch 19 taken 5 times.
✓ Branch 21 taken 13 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 13 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
214 DEFINE_LLVM_FP_INTRINSIC(log2, "Computes the binary (base-2) logarithm of arg.", true)
219
11/24
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 13 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 13 times.
✗ Branch 14 not taken.
✓ Branch 16 taken 13 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 8 times.
✓ Branch 19 taken 5 times.
✓ Branch 21 taken 13 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 13 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
✗ Branch 28 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
214 DEFINE_LLVM_FP_INTRINSIC(exp2, "Computes 2 raised to the given power arg.", true)
220 #endif
221
222 // pow created explicitly as it takes two arguments and performs slightly different
223 // calls for integer exponents
224
225 13 inline FunctionGroup::UniquePtr llvm_pow(const FunctionOptions& op)
226 {
227 static auto generate =
228
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 [](const std::vector<llvm::Value*>& args,
229 llvm::IRBuilder<>& B) -> llvm::Value*
230 {
231
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 llvm::Type* overloadType = args[0]->getType();
232
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 llvm::Type* expType = args[1]->getType();
233 const llvm::Intrinsic::ID id =
234
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 expType->isIntegerTy() ? llvm::Intrinsic::powi : llvm::Intrinsic::pow;
235 llvm::Module* M = B.GetInsertBlock()->getParent()->getParent();
236 8 llvm::Function* function = llvm::Intrinsic::getDeclaration(M, id, overloadType);
237 8 return B.CreateCall(function, args);
238 };
239
240 13 return FunctionBuilder("pow")
241 26 .addSignature<double(double,double)>(generate, (double(*)(double,double))(std::pow))
242
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<float(float,float)>(generate, (float(*)(float,float))(std::pow))
243
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<double(double,int32_t)>(generate, (double(*)(double,int32_t))(std::pow))
244
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"base", "exp"})
245
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::ReadOnly)
246
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoRecurse)
247
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
248
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
249 .setConstantFold(false) // decl's differ
250
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
251 .setDocumentation("Computes the value of the first argument raised to the power of the second argument.")
252
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
253 }
254
255 ///////////////////////////////////////////////////////////////////////////
256 ///////////////////////////////////////////////////////////////////////////
257
258 // Math
259
260
10/18
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 13 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 13 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 13 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 13 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 13 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 13 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 8 times.
✓ Branch 23 taken 5 times.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
47 DEFINE_AX_C_FP_BINDING(cbrt, "Computes the cubic root of the input.")
261
262 13 inline FunctionGroup::UniquePtr axabs(const FunctionOptions& op)
263 {
264 auto generate =
265
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 [op](const std::vector<llvm::Value*>& args,
266 llvm::IRBuilder<>& B) -> llvm::Value*
267 {
268
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 llvm::Value* value = args.front();
269 llvm::Type* type = value->getType();
270
271 if (type->isFloatingPointTy()) {
272
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 return llvm_fabs(op)->execute(args, B);
273 }
274
275 // if negative flip all the bits and add 1 (xor with -1 and sub 1)
276 llvm::Value* shift = type == LLVMType<int32_t>::get(B.getContext()) ?
277 4 LLVMType<int32_t>::get(B.getContext(), 31) :
278
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 LLVMType<int64_t>::get(B.getContext(), 63);
279
280 // arithmetic shift right
281 8 llvm::Value* mask = B.CreateAShr(value, shift);
282 8 llvm::Value* xorResult = binaryOperator(value, mask, ast::tokens::BITXOR, B);
283 8 return binaryOperator(xorResult, mask, ast::tokens::MINUS, B);
284 13 };
285
286 // @note We also support fabs through the ax abs function
287 13 return FunctionBuilder("abs")
288 26 .addSignature<int64_t(int64_t)>(generate, (int64_t(*)(int64_t))(std::abs))
289
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<int32_t(int32_t)>(generate, (int32_t(*)(int32_t))(std::abs))
290
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<double(double)>(generate, (double(*)(double))(std::abs))
291
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<float(float)>(generate, (float(*)(float))(std::abs))
292
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"n"})
293
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addDependency("fabs")
294
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::ReadOnly)
295
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoRecurse)
296
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
297 13 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
298
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
299
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
300 .setDocumentation("Computes the absolute value of an integer number.")
301
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
302 }
303
304 13 inline FunctionGroup::UniquePtr axdot(const FunctionOptions& op)
305 {
306 static auto generate =
307
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 [](const std::vector<llvm::Value*>& args,
308 llvm::IRBuilder<>& B) -> llvm::Value*
309 {
310 std::vector<llvm::Value*> v1, v2;
311
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 arrayUnpack(args[0], v1, B, /*load*/true);
312
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 arrayUnpack(args[1], v2, B, /*load*/true);
313
314
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 v1[0] = binaryOperator(v1[0], v2[0], ast::tokens::MULTIPLY, B);
315
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 v1[1] = binaryOperator(v1[1], v2[1], ast::tokens::MULTIPLY, B);
316
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 v1[2] = binaryOperator(v1[2], v2[2], ast::tokens::MULTIPLY, B);
317
318
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 llvm::Value* result = binaryOperator(v1[0], v1[1], ast::tokens::PLUS, B);
319
2/6
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
8 result = binaryOperator(result, v1[2], ast::tokens::PLUS, B);
320 8 return result;
321 };
322
323 static auto dot = [](auto a, auto b) {
324 return a->dot(*b);
325 };
326
327 using DotD = double(openvdb::math::Vec3<double>*,openvdb::math::Vec3<double>*);
328 using DotF = float(openvdb::math::Vec3<float>*,openvdb::math::Vec3<float>*);
329 using DotI = int32_t(openvdb::math::Vec3<int32_t>*,openvdb::math::Vec3<int32_t>*);
330
331 13 return FunctionBuilder("dot")
332 26 .addSignature<DotD>(generate, (DotD*)(dot))
333
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<DotF>(generate, (DotF*)(dot))
334
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<DotI>(generate, (DotI*)(dot))
335
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"a", "b"})
336
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::ReadOnly)
337
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(1, llvm::Attribute::ReadOnly)
338
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::ReadOnly)
339
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoRecurse)
340
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
341 13 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
342
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
343
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
344 .setDocumentation("Computes the dot product of two vectors.")
345
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
346 }
347
348 13 inline FunctionGroup::UniquePtr axcross(const FunctionOptions& op)
349 {
350 static auto generate =
351
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 [](const std::vector<llvm::Value*>& args,
352 llvm::IRBuilder<>& B) -> llvm::Value*
353 {
354 std::vector<llvm::Value*> ptrs, left, right;
355
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 arrayUnpack(args[0], ptrs, B, /*load*/false);
356
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 arrayUnpack(args[1], left, B, /*load*/true);
357
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 arrayUnpack(args[2], right, B, /*load*/true);
358
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 assert(ptrs.size() == 3);
359
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 assert(left.size() == 3);
360
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 assert(right.size() == 3);
361
362
1/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
8 std::vector<llvm::Value*> results(3);
363
364
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 llvm::Value* tmp1 = binaryOperator(left[1], right[2], ast::tokens::MULTIPLY, B);
365
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 llvm::Value* tmp2 = binaryOperator(left[2], right[1], ast::tokens::MULTIPLY, B);
366
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 results[0] = binaryOperator(tmp1, tmp2, ast::tokens::MINUS, B);
367
368
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 tmp1 = binaryOperator(left[2], right[0], ast::tokens::MULTIPLY, B);
369
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 tmp2 = binaryOperator(left[0], right[2], ast::tokens::MULTIPLY, B);
370
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 results[1] = binaryOperator(tmp1, tmp2, ast::tokens::MINUS, B);
371
372
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 tmp1 = binaryOperator(left[0], right[1], ast::tokens::MULTIPLY, B);
373
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 tmp2 = binaryOperator(left[1], right[0], ast::tokens::MULTIPLY, B);
374
2/6
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
8 results[2] = binaryOperator(tmp1, tmp2, ast::tokens::MINUS, B);
375
376
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 B.CreateStore(results[0], ptrs[0]);
377
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 B.CreateStore(results[1], ptrs[1]);
378
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 B.CreateStore(results[2], ptrs[2]);
379
380 8 return nullptr;
381 };
382
383 136 static auto cross = [](auto out, auto a, auto b) -> auto {
384 136 *out = a->cross(*b);
385 136 };
386
387 using CrossD = void(openvdb::math::Vec3<double>*,openvdb::math::Vec3<double>*,openvdb::math::Vec3<double>*);
388 using CrossF = void(openvdb::math::Vec3<float>*,openvdb::math::Vec3<float>*,openvdb::math::Vec3<float>*);
389 using CrossI = void(openvdb::math::Vec3<int32_t>*,openvdb::math::Vec3<int32_t>*,openvdb::math::Vec3<int32_t>*);
390
391 13 return FunctionBuilder("cross")
392 26 .addSignature<CrossD, true>(generate, (CrossD*)(cross))
393
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<CrossF, true>(generate, (CrossF*)(cross))
394
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<CrossI, true>(generate, (CrossI*)(cross))
395
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"a", "b"})
396
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::NoAlias)
397
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::WriteOnly)
398
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(1, llvm::Attribute::ReadOnly)
399
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(2, llvm::Attribute::ReadOnly)
400
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
401 13 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
402
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
403
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
404 .setDocumentation("Returns the length of the given vector")
405
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
406 }
407
408 113 inline FunctionGroup::UniquePtr axlengthsq(const FunctionOptions& op)
409 {
410 static auto generate =
411
1/2
✓ Branch 1 taken 104 times.
✗ Branch 2 not taken.
104 [](const std::vector<llvm::Value*>& args,
412 llvm::IRBuilder<>& B) -> llvm::Value*
413 {
414 std::vector<llvm::Value*> elements;
415
1/2
✓ Branch 1 taken 104 times.
✗ Branch 2 not taken.
104 arrayUnpack(args[0], elements, B, /*load*/true);
416
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 104 times.
104 assert(elements.size() >= 2);
417
418
1/2
✓ Branch 1 taken 104 times.
✗ Branch 2 not taken.
104 llvm::Value* v1 = binaryOperator(elements[0], elements[0], ast::tokens::MULTIPLY, B);
419
1/2
✓ Branch 1 taken 104 times.
✗ Branch 2 not taken.
104 llvm::Value* v2 = binaryOperator(elements[1], elements[1], ast::tokens::MULTIPLY, B);
420
3/4
✓ Branch 1 taken 104 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 80 times.
✓ Branch 4 taken 24 times.
104 llvm::Value* result = binaryOperator(v1, v2, ast::tokens::PLUS, B);
421
422
2/2
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 24 times.
104 if (elements.size() > 2) {
423
1/2
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
80 llvm::Value* v3 = binaryOperator(elements[2], elements[2], ast::tokens::MULTIPLY, B);
424
1/2
✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
80 result = binaryOperator(result, v3, ast::tokens::PLUS, B);
425 }
426
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 68 times.
104 if (elements.size() > 3) {
427
1/2
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
36 llvm::Value* v4 = binaryOperator(elements[3], elements[3], ast::tokens::MULTIPLY, B);
428
1/4
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
36 result = binaryOperator(result, v4, ast::tokens::PLUS, B);
429 }
430
431 104 return result;
432 };
433
434 static auto lengthsq = [](auto in) -> auto { return in->lengthSqr(); };
435
436 113 return FunctionBuilder("lengthsq")
437 226 .addSignature<double(openvdb::math::Vec2<double>*)>(generate, lengthsq)
438
1/4
✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
226 .addSignature<float(openvdb::math::Vec2<float>*)>(generate, lengthsq)
439
1/4
✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
226 .addSignature<int32_t(openvdb::math::Vec2<int32_t>*)>(generate, lengthsq)
440
1/4
✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
226 .addSignature<double(openvdb::math::Vec3<double>*)>(generate, lengthsq)
441
1/4
✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
226 .addSignature<float(openvdb::math::Vec3<float>*)>(generate, lengthsq)
442
1/4
✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
226 .addSignature<int32_t(openvdb::math::Vec3<int32_t>*)>(generate, lengthsq)
443
1/4
✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
226 .addSignature<double(openvdb::math::Vec4<double>*)>(generate, lengthsq)
444
1/4
✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
226 .addSignature<float(openvdb::math::Vec4<float>*)>(generate, lengthsq)
445
1/4
✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
226 .addSignature<int32_t(openvdb::math::Vec4<int32_t>*)>(generate, lengthsq)
446
3/8
✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 113 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 113 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
226 .setArgumentNames({"v"})
447
1/2
✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
113 .addParameterAttribute(0, llvm::Attribute::ReadOnly)
448
1/2
✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
113 .addFunctionAttribute(llvm::Attribute::ReadOnly)
449
1/2
✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
113 .addFunctionAttribute(llvm::Attribute::NoRecurse)
450
1/2
✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
113 .addFunctionAttribute(llvm::Attribute::NoUnwind)
451 113 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
452
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 89 times.
113 .setConstantFold(op.mConstantFoldCBindings)
453
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 89 times.
113 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
454 .setDocumentation("Returns the squared length of the given vector")
455
1/2
✓ Branch 1 taken 113 times.
✗ Branch 2 not taken.
226 .get();
456 }
457
458 61 inline FunctionGroup::UniquePtr axlength(const FunctionOptions& op)
459 {
460 auto generate =
461 68 [op](const std::vector<llvm::Value*>& args,
462 llvm::IRBuilder<>& B) -> llvm::Value*
463 {
464 136 auto a = axlengthsq(op);
465
1/2
✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
68 auto s = llvm_sqrt(op);
466
1/2
✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
68 llvm::Value* lsq = a->execute(args, B);
467
2/4
✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 68 times.
✗ Branch 5 not taken.
204 return s->execute({lsq}, B);
468 61 };
469
470 492 static auto length = [](auto in) -> auto
471 {
472 using VecType = typename std::remove_pointer<decltype(in)>::type;
473 using ElementT = typename openvdb::VecTraits<VecType>::ElementType;
474 using RetT = typename std::conditional
475 <std::is_floating_point<ElementT>::value, ElementT, double>::type;
476 492 return std::sqrt(RetT(in->lengthSqr()));
477 };
478
479 61 return FunctionBuilder("length")
480 122 .addSignature<double(openvdb::math::Vec2<double>*)>(generate, length)
481
1/4
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
122 .addSignature<float(openvdb::math::Vec2<float>*)>(generate, length)
482
1/4
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
122 .addSignature<double(openvdb::math::Vec2<int32_t>*)>(generate, length)
483
1/4
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
122 .addSignature<double(openvdb::math::Vec3<double>*)>(generate, length)
484
1/4
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
122 .addSignature<float(openvdb::math::Vec3<float>*)>(generate, length)
485
1/4
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
122 .addSignature<double(openvdb::math::Vec3<int32_t>*)>(generate, length)
486
1/4
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
122 .addSignature<double(openvdb::math::Vec4<double>*)>(generate, length)
487
1/4
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
122 .addSignature<float(openvdb::math::Vec4<float>*)>(generate, length)
488
1/4
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
122 .addSignature<double(openvdb::math::Vec4<int32_t>*)>(generate, length)
489
1/2
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
61 .addDependency("lengthsq")
490 61 .addDependency("sqrt")
491
3/8
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 61 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 61 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
122 .setArgumentNames({"v"})
492
1/2
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
61 .addParameterAttribute(0, llvm::Attribute::ReadOnly)
493
1/2
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
61 .addFunctionAttribute(llvm::Attribute::ReadOnly)
494
1/2
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
61 .addFunctionAttribute(llvm::Attribute::NoRecurse)
495
1/2
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
61 .addFunctionAttribute(llvm::Attribute::NoUnwind)
496 61 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
497
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 45 times.
61 .setConstantFold(op.mConstantFoldCBindings)
498
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 45 times.
61 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
499 .setDocumentation("Returns the length of the given vector")
500
1/2
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
122 .get();
501 }
502
503 17 inline FunctionGroup::UniquePtr axnormalize(const FunctionOptions& op)
504 {
505 auto generate =
506 28 [op](const std::vector<llvm::Value*>& args,
507 llvm::IRBuilder<>& B) -> llvm::Value*
508 {
509 56 auto a = axlength(op);
510
3/6
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 28 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 28 times.
✗ Branch 8 not taken.
56 llvm::Value* len = a->execute({args[1]}, B);
511
512 std::vector<llvm::Value*> ptrs, elements;
513
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 arrayUnpack(args[0], ptrs, B, /*load*/false);
514
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 arrayUnpack(args[1], elements, B, /*load*/true);
515
3/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
28 assert(ptrs.size() == 3 || ptrs.size() == 4);
516
3/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
28 assert(elements.size() == 3 || elements.size() == 4);
517
518
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 20 times.
28 if (elements[0]->getType()->isIntegerTy()) {
519
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 arithmeticConversion(elements, LLVMType<double>::get(B.getContext()), B);
520 }
521
522 // the following is always done at fp precision
523
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 llvm::Value* one = llvm::ConstantFP::get(len->getType(), 1.0);
524
1/2
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
28 llvm::Value* oneDividedByLength = B.CreateFDiv(one, len);
525
526
1/2
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
28 elements[0] = B.CreateFMul(elements[0], oneDividedByLength);
527
1/2
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
28 elements[1] = B.CreateFMul(elements[1], oneDividedByLength);
528
3/4
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12 times.
✓ Branch 5 taken 16 times.
28 elements[2] = B.CreateFMul(elements[2], oneDividedByLength);
529
3/6
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 16 times.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
28 if (elements.size() == 4) elements[3] = B.CreateFMul(elements[3], oneDividedByLength);
530
531
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 B.CreateStore(elements[0], ptrs[0]);
532
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 B.CreateStore(elements[1], ptrs[1]);
533
1/2
✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
28 B.CreateStore(elements[2], ptrs[2]);
534
3/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 16 times.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
28 if (elements.size() == 4) B.CreateStore(elements[3], ptrs[3]);
535
536 28 return nullptr;
537 17 };
538
539 static auto norm = [](auto out, auto in) {
540 using VecType = typename std::remove_pointer<decltype(out)>::type;
541 using ElementT = typename openvdb::VecTraits<VecType>::ElementType;
542 *out = *in; // copy
543 out->normalize(ElementT(0.0));
544 };
545
546 using Normalize3D = void(openvdb::math::Vec3<double>*,openvdb::math::Vec3<double>*);
547 using Normalize3F = void(openvdb::math::Vec3<float>*,openvdb::math::Vec3<float>*);
548 using Normalize3I = void(openvdb::math::Vec3<double>*, openvdb::math::Vec3<int32_t>*);
549 using Normalize4D = void(openvdb::math::Vec4<double>*,openvdb::math::Vec4<double>*);
550 using Normalize4F = void(openvdb::math::Vec4<float>*,openvdb::math::Vec4<float>*);
551 using Normalize4I = void(openvdb::math::Vec4<double>*, openvdb::math::Vec4<int32_t>*);
552
553 17 return FunctionBuilder("normalize")
554 34 .addSignature<Normalize3D, true>(generate, (Normalize3D*)(norm))
555
1/4
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
34 .addSignature<Normalize3F, true>(generate, (Normalize3F*)(norm))
556
1/4
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
34 .addSignature<Normalize3I, true>(generate, (Normalize3I*)(norm))
557
1/4
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
34 .addSignature<Normalize4D, true>(generate, (Normalize4D*)(norm))
558
1/4
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
34 .addSignature<Normalize4F, true>(generate, (Normalize4F*)(norm))
559
1/4
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
34 .addSignature<Normalize4I, true>(generate, (Normalize4I*)(norm))
560 17 .addDependency("length")
561
3/8
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 17 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 17 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
34 .setArgumentNames({"v"})
562
1/2
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
17 .addParameterAttribute(0, llvm::Attribute::NoAlias)
563
1/2
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
17 .addParameterAttribute(1, llvm::Attribute::ReadOnly)
564
1/2
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
17 .addFunctionAttribute(llvm::Attribute::NoUnwind)
565 17 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
566
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 9 times.
17 .setConstantFold(op.mConstantFoldCBindings)
567
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 9 times.
17 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
568 .setDocumentation("Returns the normalized result of the given vector.")
569
1/2
✓ Branch 1 taken 17 times.
✗ Branch 2 not taken.
34 .get();
570 }
571
572 13 inline FunctionGroup::UniquePtr axlerp(const FunctionOptions& op)
573 {
574 static auto generate =
575
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 [](const std::vector<llvm::Value*>& args,
576 llvm::IRBuilder<>& B) -> llvm::Value*
577 {
578
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 assert(args.size() == 3);
579 8 llvm::Value* a = args[0], *b = args[1], *t = args[2];
580 8 llvm::Value* zero = llvm::ConstantFP::get(a->getType(), 0.0);
581 8 llvm::Value* one = llvm::ConstantFP::get(a->getType(), 1.0);
582 llvm::Function* base = B.GetInsertBlock()->getParent();
583
584 // @todo short-circuit?
585 8 llvm::Value* a1 = binaryOperator(a, zero, ast::tokens::LESSTHANOREQUAL, B);
586 8 llvm::Value* b1 = binaryOperator(b, zero, ast::tokens::MORETHANOREQUAL, B);
587 8 llvm::Value* a2 = binaryOperator(a, zero, ast::tokens::MORETHANOREQUAL, B);
588 8 llvm::Value* b2 = binaryOperator(b, zero, ast::tokens::LESSTHANOREQUAL, B);
589 8 a1 = binaryOperator(a1, b1, ast::tokens::AND, B);
590 8 a2 = binaryOperator(a2, b2, ast::tokens::AND, B);
591 8 a1 = binaryOperator(a1, a2, ast::tokens::OR, B);
592
593 8 llvm::BasicBlock* then = llvm::BasicBlock::Create(B.getContext(), "then", base);
594 8 llvm::BasicBlock* post = llvm::BasicBlock::Create(B.getContext(), "post", base);
595 8 B.CreateCondBr(a1, then, post);
596
597 B.SetInsertPoint(then);
598 8 llvm::Value* r = binaryOperator(one, t, ast::tokens::MINUS, B);
599 8 r = binaryOperator(r, a, ast::tokens::MULTIPLY, B);
600 8 llvm::Value* right = binaryOperator(t, b, ast::tokens::MULTIPLY, B);
601 8 r = binaryOperator(r, right, ast::tokens::PLUS, B);
602 8 B.CreateRet(r);
603
604 B.SetInsertPoint(post);
605
606 8 llvm::Value* tisone = binaryOperator(t, one, ast::tokens::EQUALSEQUALS, B);
607
608 8 then = llvm::BasicBlock::Create(B.getContext(), "then", base);
609 8 post = llvm::BasicBlock::Create(B.getContext(), "post", base);
610 8 B.CreateCondBr(tisone, then, post);
611
612 B.SetInsertPoint(then);
613 8 B.CreateRet(b);
614
615 B.SetInsertPoint(post);
616
617 // if nlerp
618 8 llvm::Value* x = binaryOperator(b, a, ast::tokens::MINUS, B);
619 8 x = binaryOperator(t, x, ast::tokens::MULTIPLY, B);
620 8 x = binaryOperator(a, x, ast::tokens::PLUS, B);
621
622 8 then = llvm::BasicBlock::Create(B.getContext(), "then", base);
623 8 post = llvm::BasicBlock::Create(B.getContext(), "post", base);
624
625 8 a1 = binaryOperator(t, one, ast::tokens::MORETHAN, B);
626 8 a2 = binaryOperator(b, a, ast::tokens::MORETHAN, B);
627 8 a1 = binaryOperator(a1, a2, ast::tokens::EQUALSEQUALS, B);
628 8 B.CreateCondBr(a1, then, post);
629
630 B.SetInsertPoint(then);
631 8 b1 = binaryOperator(b, x, ast::tokens::LESSTHAN, B);
632 8 B.CreateRet(B.CreateSelect(b1, x, b));
633
634 B.SetInsertPoint(post);
635 8 b1 = binaryOperator(x, b, ast::tokens::LESSTHAN, B);
636 8 return B.CreateRet(B.CreateSelect(b1, x, b));
637 };
638
639 // This lerp implementation is taken from clang and matches the C++20 standard
640 980 static auto lerp = [](auto a, auto b, auto t) -> auto
641 {
642 using ValueT = decltype(a);
643 // If there is a zero crossing with a,b do the more precise
644 // linear interpolation. This is only monotonic if there is
645 // a zero crossing
646 // Exact, monotonic, bounded, determinate, and (for a=b=0)
647 // consistent
648
7/8
✓ Branch 0 taken 196 times.
✓ Branch 1 taken 294 times.
✓ Branch 2 taken 98 times.
✓ Branch 3 taken 98 times.
✓ Branch 4 taken 294 times.
✓ Branch 5 taken 98 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 294 times.
980 if ((a <= 0 && b >= 0) || (a >= 0 && b <= 0)) {
649 196 return t * b + (ValueT(1.0) - t) * a;
650 }
651 // If t is exactly 1, return b (as the second impl doesn't
652 // guarantee this due to fp arithmetic)
653
2/2
✓ Branch 0 taken 294 times.
✓ Branch 1 taken 98 times.
784 if (t == ValueT(1.0)) return b;
654 // less precise interpolation when there is no crossing
655 // Exact at t=0, monotonic except near t=1, bounded,
656 // determinate, and consistent
657 588 const auto x = a + t * (b - a);
658 // Ensure b is preferred to another equal value (i.e. -0. vs. +0.),
659 // which avoids returning -0 for t==1 but +0 for other nearby
660 // values of t. This branching also stops nans being returns from
661 // inf inputs
662 // monotonic near t=1
663
3/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 245 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 49 times.
588 if ((t > ValueT(1.0)) == (b > a)) return b < x ? x : b;
664
2/2
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 147 times.
686 else return x < b ? x : b;
665 };
666
667 13 return FunctionBuilder("lerp")
668 26 .addSignature<double(double,double,double)>(generate, (double(*)(double,double,double))(lerp))
669
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<float(float,float,float)>(generate, (float(*)(float,float,float))(lerp))
670
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"a", "b", "amount"})
671
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::ReadOnly)
672
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoRecurse)
673
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
674 13 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
675
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
676
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
677 .setDocumentation("Performs bilinear interpolation between the values. If the "
678 "amount is outside the range 0 to 1, the values will be extrapolated linearly. "
679 "If amount is 0, the first value is returned. If it is 1, the second value "
680 "is returned. This implementation is guaranteed to be monotonic.")
681
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
682 }
683
684 105 inline FunctionGroup::UniquePtr axmin(const FunctionOptions& op)
685 {
686 static auto generate =
687 36 [](const std::vector<llvm::Value*>& args,
688 llvm::IRBuilder<>& B) -> llvm::Value*
689 {
690 llvm::Value* result =
691 36 binaryOperator(args[0], args[1], ast::tokens::MORETHAN, B);
692 36 return B.CreateSelect(result, args[1], args[0]);
693 };
694
695 static auto min = [](auto a, auto b) -> auto {
696 return std::min(a, b);
697 };
698
699 105 return FunctionBuilder("min")
700 210 .addSignature<double(double,double)>(generate, (double(*)(double,double))(min))
701
1/4
✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
210 .addSignature<float(float,float)>(generate, (float(*)(float,float))(min))
702
1/4
✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
210 .addSignature<int64_t(int64_t,int64_t)>(generate, (int64_t(*)(int64_t,int64_t))(min))
703
1/4
✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
210 .addSignature<int32_t(int32_t,int32_t)>(generate, (int32_t(*)(int32_t,int32_t))(min))
704
3/8
✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 105 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 105 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
210 .setArgumentNames({"a", "b"})
705
1/2
✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
105 .addFunctionAttribute(llvm::Attribute::ReadOnly)
706
1/2
✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
105 .addFunctionAttribute(llvm::Attribute::NoRecurse)
707
1/2
✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
105 .addFunctionAttribute(llvm::Attribute::NoUnwind)
708 105 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
709
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 49 times.
105 .setConstantFold(op.mConstantFoldCBindings)
710
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 49 times.
105 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
711 .setDocumentation("Returns the smaller of the given values.")
712
1/2
✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
210 .get();
713 }
714
715 105 inline FunctionGroup::UniquePtr axmax(const FunctionOptions& op)
716 {
717 static auto generate =
718 36 [](const std::vector<llvm::Value*>& args,
719 llvm::IRBuilder<>& B) -> llvm::Value*
720 {
721 llvm::Value* result =
722 36 binaryOperator(args[0], args[1], ast::tokens::MORETHAN, B);
723 36 return B.CreateSelect(result, args[0], args[1]);
724 };
725
726 static auto max = [](auto a, auto b) -> auto {
727 return std::max(a, b);
728 };
729
730 105 return FunctionBuilder("max")
731 210 .addSignature<double(double,double)>(generate, (double(*)(double,double))(max))
732
1/4
✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
210 .addSignature<float(float,float)>(generate, (float(*)(float,float))(max))
733
1/4
✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
210 .addSignature<int64_t(int64_t,int64_t)>(generate, (int64_t(*)(int64_t,int64_t))(max))
734
1/4
✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
210 .addSignature<int32_t(int32_t,int32_t)>(generate, (int32_t(*)(int32_t,int32_t))(max))
735
3/8
✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 105 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 105 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
210 .setArgumentNames({"a", "b"})
736
1/2
✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
105 .addFunctionAttribute(llvm::Attribute::ReadOnly)
737
1/2
✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
105 .addFunctionAttribute(llvm::Attribute::NoRecurse)
738
1/2
✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
105 .addFunctionAttribute(llvm::Attribute::NoUnwind)
739 105 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
740
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 49 times.
105 .setConstantFold(op.mConstantFoldCBindings)
741
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 49 times.
105 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
742 .setDocumentation("Returns the larger of the given values.")
743
1/2
✓ Branch 1 taken 105 times.
✗ Branch 2 not taken.
210 .get();
744 }
745
746 85 inline FunctionGroup::UniquePtr axclamp(const FunctionOptions& op)
747 {
748 auto generate =
749 20 [op](const std::vector<llvm::Value*>& args,
750 llvm::IRBuilder<>& B) -> llvm::Value*
751 {
752
2/4
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 20 times.
✗ Branch 6 not taken.
40 llvm::Value* min = axmax(op)->execute({args[0], args[1]}, B);
753
2/4
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 20 times.
✗ Branch 6 not taken.
40 llvm::Value* result = axmin(op)->execute({min, args[2]}, B);
754 20 return result;
755 85 };
756
757 using ClampD = double(double, double, double);
758 using ClampF = float(float, float, float);
759 using ClampI = int32_t(int32_t, int32_t, int32_t);
760 using ClampL = int64_t(int64_t, int64_t, int64_t);
761
762 85 return FunctionBuilder("clamp")
763 170 .addSignature<ClampD>(generate, &openvdb::math::Clamp<double>)
764
1/4
✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
170 .addSignature<ClampF>(generate, &openvdb::math::Clamp<float>)
765
1/4
✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
170 .addSignature<ClampL>(generate, &openvdb::math::Clamp<int64_t>)
766
1/4
✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
170 .addSignature<ClampI>(generate, &openvdb::math::Clamp<int32_t>)
767
1/2
✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
85 .addDependency("min")
768
1/2
✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
85 .addDependency("max")
769
1/2
✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
85 .addFunctionAttribute(llvm::Attribute::ReadOnly)
770
1/2
✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
85 .addFunctionAttribute(llvm::Attribute::NoRecurse)
771
1/2
✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
85 .addFunctionAttribute(llvm::Attribute::NoUnwind)
772 85 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
773
3/8
✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 85 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 85 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
170 .setArgumentNames({"in", "min", "max"})
774
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 29 times.
85 .setConstantFold(op.mConstantFoldCBindings)
775
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 29 times.
85 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
776 .setDocumentation("Clamps the first argument to the minimum second argument "
777 "value and maximum third argument value")
778
1/2
✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
170 .get();
779 }
780
781 13 inline FunctionGroup::UniquePtr axfit(const FunctionOptions& op)
782 {
783 auto generate =
784 36 [op](const std::vector<llvm::Value*>& args,
785 llvm::IRBuilder<>& B) -> llvm::Value*
786 {
787 // (outMax - outMin)(x - inMin)
788 // f(x) = ---------------------------- + outMin
789 // inMax - inMin
790 // if inMax == inMin, f(x) = (outMax + outMin) / 2.0
791
792 // NOTE: this also performs a clamp on the ordered input range
793 // @TODO revisit. If this is the best thing to do, should add conditional
794 // branching so that the clamping math is never executed when the value
795 // is inside
796
797 36 std::vector<llvm::Value*> argcopy(args);
798
799 // select the precision at which to perform
800
801
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 24 times.
36 llvm::Type* precision = argcopy[0]->getType();
802
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 24 times.
36 if (precision->isIntegerTy()) {
803 precision = LLVMType<double>::get(B.getContext());
804 }
805
806 // See if the input range has a valid magnitude .i.e. the values are not the same
807
808 llvm::Value* isInputRangeValid =
809
1/2
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
36 binaryOperator(argcopy[1], argcopy[2], ast::tokens::NOTEQUALS, B);
810
811 // clamp the input to the ORDERED inMin to inMax range
812
813 llvm::Value* minRangeComp =
814
1/2
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
36 binaryOperator(argcopy[1], argcopy[2], ast::tokens::LESSTHAN, B);
815
1/2
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
36 llvm::Value* minInputRange = B.CreateSelect(minRangeComp, argcopy[1], argcopy[2]);
816
1/2
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
36 llvm::Value* maxInputRange = B.CreateSelect(minRangeComp, argcopy[2], argcopy[1]);
817
818 // clamp
819 {
820
1/2
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
36 auto clamp = axclamp(op);
821
3/6
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 36 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 36 times.
✗ Branch 7 not taken.
72 argcopy[0] = clamp->execute({ argcopy[0], minInputRange, maxInputRange }, B);
822 }
823
824 // cast all (the following requires floating point precision)
825
826
3/4
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 36 times.
✓ Branch 3 taken 180 times.
✗ Branch 4 not taken.
216 for (auto& arg : argcopy) arg = arithmeticConversion(arg, precision, B);
827
828
1/2
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
36 llvm::Value* valueMinusMin = B.CreateFSub(argcopy[0], argcopy[1]);
829
1/2
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
36 llvm::Value* inputRange = B.CreateFSub(argcopy[2], argcopy[1]);
830
1/2
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
36 llvm::Value* outputRange = B.CreateFSub(argcopy[4], argcopy[3]);
831
832
1/2
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
36 llvm::Value* result = B.CreateFMul(outputRange, valueMinusMin);
833
1/2
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
36 result = B.CreateFDiv(result, inputRange); // NOTE - This can cause division by zero
834
1/2
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
36 result = B.CreateFAdd(argcopy[3], result);
835
836 // calculate the output range over 2 and use this value if the input range is invalid
837
838
1/2
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
36 llvm::Value* outputRangeOverTwo = B.CreateFAdd(argcopy[3], argcopy[4]);
839
1/2
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
36 llvm::Value* two = llvm::ConstantFP::get(precision, 2.0);
840
1/2
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
36 outputRangeOverTwo = B.CreateFDiv(outputRangeOverTwo, two);
841
842
2/6
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 36 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
72 return B.CreateSelect(isInputRangeValid, result, outputRangeOverTwo);
843 13 };
844
845 using FitD = double(double, double, double, double, double);
846 using FitF = float(float, float, float, float, float);
847 using FitL = double(int64_t, int64_t, int64_t, int64_t, int64_t);
848 using FitI = double(int32_t, int32_t, int32_t, int32_t, int32_t);
849
850 13 return FunctionBuilder("fit")
851
1/2
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
26 .addSignature<FitD>(generate)
852
2/6
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
26 .addSignature<FitF>(generate)
853
2/6
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
26 .addSignature<FitL>(generate)
854
2/6
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
26 .addSignature<FitI>(generate)
855 13 .addDependency("clamp")
856
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"value", "omin", "omax", "nmin", "nmax"})
857 .setConstantFold(false)
858
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::ReadOnly)
859
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoRecurse)
860
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
861 13 .addFunctionAttribute(llvm::Attribute::InlineHint)
862
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
863 .setDocumentation("Fit the first argument to the output range by "
864 "first clamping the value between the second and third input range "
865 "arguments and then remapping the result to the output range fourth and "
866 "fifth arguments")
867
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
868 }
869
870 14 inline FunctionGroup::UniquePtr axrand(const FunctionOptions& op)
871 {
872 struct Rand
873 {
874 100712556 static double rand(const std::mt19937_64::result_type* seed)
875 {
876 using ThreadLocalEngineContainer =
877 tbb::enumerable_thread_specific<std::mt19937_64>;
878
4/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 100712555 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
100712556 static ThreadLocalEngineContainer ThreadLocalEngines;
879
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 100712555 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
100712556 static std::uniform_real_distribution<double> Generator(0.0,1.0);
880 std::mt19937_64& engine = ThreadLocalEngines.local();
881
2/2
✓ Branch 0 taken 75534417 times.
✓ Branch 1 taken 25178139 times.
100712556 if (seed) {
882 75534417 engine.seed(static_cast<std::mt19937_64::result_type>(*seed));
883 }
884 100712556 return Generator(engine);
885 }
886
887 25178139 static double rand() { return Rand::rand(nullptr); }
888
889
1/2
✓ Branch 0 taken 75534417 times.
✗ Branch 1 not taken.
75534417 static double rand(double seed)
890 {
891 const std::mt19937_64::result_type hash =
892 75534417 static_cast<std::mt19937_64::result_type>(std::hash<double>()(seed));
893 75534417 return Rand::rand(&hash);
894 }
895
896 static double rand(int64_t seed)
897 {
898 const std::mt19937_64::result_type hash =
899 static_cast<std::mt19937_64::result_type>(seed);
900 return Rand::rand(&hash);
901 }
902 };
903
904 14 return FunctionBuilder("rand")
905
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 .addSignature<double()>((double(*)())(Rand::rand))
906
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 .addSignature<double(double)>((double(*)(double))(Rand::rand))
907
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 .addSignature<double(int64_t)>((double(*)(int64_t))(Rand::rand))
908
2/4
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
28 .setArgumentNames({"seed"})
909 // We can't constant fold rand even if it's been called with a constant as
910 // it will leave the generator in a different state in comparison to other
911 // threads and, as it relies on an internal state, doesn't respect branching
912 // etc. We also can't use a different generate for constant calls as subsequent
913 // calls to rand() without an argument won't know to advance the generator.
914 .setConstantFold(false)
915
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6 times.
14 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
916 .setDocumentation("Creates a random number based on the provided "
917 "seed. The number will be in the range of 0 to 1. The same number is "
918 "produced for the same seed. Note that if rand is called without a seed "
919 "the previous state of the random number generator is advanced for the "
920 "currently processing element. This state is determined by the last call to "
921 "rand() with a given seed. If rand is not called with a seed, the generator "
922 "advances continuously across different elements which can produce non-"
923 "deterministic results. It is important that rand is always called with a "
924 "seed at least once for deterministic results.")
925
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
28 .get();
926 }
927
928 13 inline FunctionGroup::UniquePtr axrand32(const FunctionOptions& op)
929 {
930 struct Rand
931 {
932 252 static double rand(const std::mt19937::result_type* seed)
933 {
934 using ThreadLocalEngineContainer =
935 tbb::enumerable_thread_specific<std::mt19937>;
936 // Obtain thread-local engine (or create if it doesn't exist already).
937
4/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 251 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
252 static ThreadLocalEngineContainer ThreadLocalEngines;
938
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 251 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
252 static std::uniform_real_distribution<double> Generator(0.0,1.0);
939 std::mt19937& engine = ThreadLocalEngines.local();
940
2/2
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 63 times.
252 if (seed) {
941 189 engine.seed(static_cast<std::mt19937::result_type>(*seed));
942 }
943 // Once we have seeded the random number generator, we then evaluate it,
944 // which returns a floating point number in the range [0,1)
945 252 return Generator(engine);
946 }
947
948 63 static double rand() { return Rand::rand(nullptr); }
949
950
1/2
✓ Branch 0 taken 189 times.
✗ Branch 1 not taken.
189 static double rand(double seed)
951 {
952 // We initially hash the double-precision seed with `std::hash`. The
953 // important thing about the hash is that it produces a "reliable" hash value,
954 // taking into account a number of special cases for floating point numbers
955 // (e.g. -0 and +0 must return the same hash value, etc). Other than these
956 // special cases, this function will usually just copy the binary
957 // representation of a float into the resultant `size_t`
958 189 const size_t hash = std::hash<double>()(seed);
959
960 // Now that we have a reliable hash (with special floating-point cases taken
961 // care of), we proceed to use this hash to seed a random number generator.
962 // The generator takes an unsigned int, which is not guaranteed to be the
963 // same size as size_t.
964 //
965 // So, we must convert it. I should note that the OpenVDB math libraries will
966 // do this for us, but its implementation static_casts `size_t` to `unsigned int`,
967 // and because `std::hash` returns a binary copy of the original
968 // double-precision number in almost all cases, this ends up producing noticable
969 // patterns in the result (e.g. by truncating the upper 4 bytes, values of 1.0,
970 // 2.0, 3.0, and 4.0 all return the same hash value because their lower 4 bytes
971 // are all zero).
972 //
973 // We use the `hashToSeed` function to reduce our `size_t` to an `unsigned int`,
974 // whilst taking all bits in the `size_t` into account.
975 // On some architectures std::uint_fast32_t may be size_t, but we always hash to
976 // be consistent.
977 const std::mt19937::result_type uintseed =
978 189 static_cast<std::mt19937::result_type>(hashToSeed<uint32_t>(hash));
979 189 return Rand::rand(&uintseed);
980 }
981
982 static double rand(int32_t seed)
983 {
984 const std::mt19937::result_type uintseed =
985 static_cast<std::mt19937::result_type>(seed);
986 return Rand::rand(&uintseed);
987 }
988 };
989
990 13 return FunctionBuilder("rand32")
991
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<double()>((double(*)())(Rand::rand))
992
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<double(double)>((double(*)(double))(Rand::rand))
993
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<double(int32_t)>((double(*)(int32_t))(Rand::rand))
994
2/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
26 .setArgumentNames({"seed"})
995 // We can't constant fold rand even if it's been called with a constant as
996 // it will leave the generator in a different state in comparison to other
997 // threads and, as it relies on an internal state, doesn't respect branching
998 // etc. We also can't use a different generate for constant calls as subsequent
999 // calls to rand() without an argument won't know to advance the generator.
1000 .setConstantFold(false)
1001
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
1002 .setDocumentation("Creates a random number based on the provided 32 bit "
1003 "seed. The number will be in the range of 0 to 1. The same number is "
1004 "produced for the same seed. "
1005 "NOTE: This function does not share the same random number generator as "
1006 "rand(). rand32() may provide a higher throughput on some architectures, "
1007 "but will produce different results to rand(). "
1008 "NOTE: If rand32 is called without a seed the previous state of the random "
1009 "number generator is advanced for the currently processing element. This "
1010 "state is determined by the last call to rand32() with a given seed. If "
1011 "rand32 is not called with a seed, the generator advances continuously "
1012 "across different elements which can produce non-deterministic results. "
1013 "It is important that rand32 is always called with a seed at least once "
1014 "for deterministic results.")
1015
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
1016 }
1017
1018 13 inline FunctionGroup::UniquePtr axsign(const FunctionOptions& op)
1019 {
1020 static auto generate =
1021
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 [](const std::vector<llvm::Value*>& args,
1022 llvm::IRBuilder<>& B) -> llvm::Value*
1023 {
1024 // int r = (T(0) < val) - (val < T(0));
1025
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 assert(args.size() == 1);
1026
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 24 times.
36 llvm::Value* arg = args.front();
1027 llvm::Type* type = arg->getType();
1028 llvm::Value* zero;
1029
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 24 times.
36 if (type->isIntegerTy()) {
1030 12 zero = llvm::ConstantInt::get(type, static_cast<uint64_t>(0), /*signed*/true);
1031 }
1032 else {
1033 assert(type->isFloatingPointTy());
1034 24 zero = llvm::ConstantFP::get(type, static_cast<double>(0.0));
1035 }
1036
1037 36 llvm::Value* c1 = binaryOperator(zero, arg, ast::tokens::LESSTHAN, B);
1038 36 c1 = arithmeticConversion(c1, LLVMType<int32_t>::get(B.getContext()), B);
1039 36 llvm::Value* c2 = binaryOperator(arg, zero, ast::tokens::LESSTHAN, B);
1040 36 c2 = arithmeticConversion(c2, LLVMType<int32_t>::get(B.getContext()), B);
1041 36 llvm::Value* r = binaryOperator(c1, c2, ast::tokens::MINUS, B);
1042 36 return arithmeticConversion(r, LLVMType<int32_t>::get(B.getContext()), B);
1043 };
1044
1045 13 return FunctionBuilder("sign")
1046
1/2
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
26 .addSignature<int32_t(double)>(generate)
1047
2/6
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
26 .addSignature<int32_t(float)>(generate)
1048
2/6
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
26 .addSignature<int32_t(int64_t)>(generate)
1049
2/6
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
26 .addSignature<int32_t(int32_t)>(generate)
1050
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"n"})
1051
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::ReadOnly)
1052
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoRecurse)
1053
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
1054 13 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
1055
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
1056
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
1057 .setDocumentation("Implements signum, determining if the input is negative, zero "
1058 "or positive. Returns -1 for a negative number, 0 for the number zero, and +1 "
1059 "for a positive number. Note that this function does not check the sign of "
1060 "floating point +/-0.0 values. See signbit().")
1061 13 .get();
1062 }
1063
1064 13 inline FunctionGroup::UniquePtr axsignbit(const FunctionOptions& op)
1065 {
1066 13 return FunctionBuilder("signbit")
1067
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<bool(double)>((bool(*)(double))(std::signbit))
1068
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<bool(float)>((bool(*)(float))(std::signbit))
1069
2/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
26 .setArgumentNames({"n"})
1070
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::ReadOnly)
1071
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoRecurse)
1072
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
1073 13 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
1074
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
1075
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
1076 .setDocumentation("Determines if the given floating point number input is negative. "
1077 "Returns true if arg is negative, false otherwise. Will return true for -0.0, "
1078 "false for +0.0")
1079
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
1080 }
1081
1082 13 inline FunctionGroup::UniquePtr axtruncatemod(const FunctionOptions& op)
1083 {
1084 static auto generate =
1085
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 [](const std::vector<llvm::Value*>& args,
1086 llvm::IRBuilder<>& B) -> llvm::Value*
1087 {
1088
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 assert(args.size() == 2);
1089 36 return binaryOperator(args[0], args[1], ast::tokens::MODULO, B);
1090 };
1091
1092 13 return FunctionBuilder("truncatemod")
1093
1/2
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
26 .addSignature<double(double,double)>(generate)
1094
2/6
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
26 .addSignature<float(float,float)>(generate)
1095
2/6
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
26 .addSignature<int64_t(int64_t,int64_t)>(generate)
1096
2/6
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
26 .addSignature<int32_t(int32_t,int32_t)>(generate)
1097
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"dividend", "divisor"})
1098
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::ReadOnly)
1099
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoRecurse)
1100
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
1101 13 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
1102
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
1103
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
1104 .setDocumentation("Truncated modulo, where the result of the division operator "
1105 "on (dividend / divisor) is truncated. The remainder is thus calculated with "
1106 "D - d * trunc(D/d). This is equal to the C/C++ % implementation. This is NOT "
1107 "equal to a%b in AX. See floormod(), euclideanmod().")
1108
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
1109 }
1110
1111 153 inline FunctionGroup::UniquePtr axfloormod(const FunctionOptions& op)
1112 {
1113 static auto ifmod = [](auto D, auto d) -> auto
1114 {
1115 using ValueType = decltype(D);
1116 auto r = D % d; // tmod
1117 if ((r > 0 && d < 0) || (r < 0 && d > 0)) r = r+d;
1118 return ValueType(r);
1119 };
1120
1121
2/2
✓ Branch 0 taken 420 times.
✓ Branch 1 taken 420 times.
4544 static auto ffmod = [](auto D, auto d) -> auto
1122 {
1123 2864 auto r = std::fmod(D, d);
1124
8/8
✓ Branch 0 taken 1062 times.
✓ Branch 1 taken 1210 times.
✓ Branch 2 taken 642 times.
✓ Branch 3 taken 420 times.
✓ Branch 4 taken 988 times.
✓ Branch 5 taken 864 times.
✓ Branch 6 taken 568 times.
✓ Branch 7 taken 420 times.
4544 if ((r > 0 && d < 0) || (r < 0 && d > 0)) r = r+d;
1125 4544 return r;
1126 };
1127
1128 static auto generate =
1129
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 144 times.
144 [](const std::vector<llvm::Value*>& args,
1130 llvm::IRBuilder<>& B) -> llvm::Value*
1131 {
1132
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 144 times.
144 assert(args.size() == 2);
1133 144 llvm::Value* D = args[0];
1134 144 llvm::Value* d = args[1];
1135 // tmod
1136 144 llvm::Value* r = binaryOperator(D, d, ast::tokens::MODULO, B);
1137
1138 144 llvm::Value* zero = llvmConstant(0, D->getType());
1139 144 llvm::Value* a1 = binaryOperator(r, zero, ast::tokens::MORETHAN, B);
1140 144 llvm::Value* a2 = binaryOperator(d, zero, ast::tokens::LESSTHAN, B);
1141 144 a1 = binaryOperator(a1, a2, ast::tokens::AND, B);
1142 144 llvm::Value* b1 = binaryOperator(r, zero, ast::tokens::LESSTHAN, B);
1143 144 llvm::Value* b2 = binaryOperator(d, zero, ast::tokens::MORETHAN, B);
1144 144 b1 = binaryOperator(b1, b2, ast::tokens::AND, B);
1145 144 a1 = binaryOperator(a1, b1, ast::tokens::OR, B);
1146
1147 144 llvm::Value* rplus = binaryOperator(r, d, ast::tokens::PLUS, B);
1148 144 return B.CreateSelect(a1, rplus, r);
1149 };
1150
1151 153 return FunctionBuilder("floormod")
1152 306 .addSignature<double(double,double)>(generate, (double(*)(double,double))(ffmod))
1153
1/4
✓ Branch 1 taken 153 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
306 .addSignature<float(float,float)>(generate, (float(*)(float,float))(ffmod))
1154
1/4
✓ Branch 1 taken 153 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
306 .addSignature<int64_t(int64_t,int64_t)>(generate, (int64_t(*)(int64_t,int64_t))(ifmod))
1155
1/4
✓ Branch 1 taken 153 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
306 .addSignature<int32_t(int32_t,int32_t)>(generate, (int32_t(*)(int32_t,int32_t))(ifmod))
1156
3/8
✓ Branch 1 taken 153 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 153 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 153 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
306 .setArgumentNames({"dividend", "divisor"})
1157
1/2
✓ Branch 1 taken 153 times.
✗ Branch 2 not taken.
153 .addFunctionAttribute(llvm::Attribute::ReadOnly)
1158
1/2
✓ Branch 1 taken 153 times.
✗ Branch 2 not taken.
153 .addFunctionAttribute(llvm::Attribute::NoRecurse)
1159
1/2
✓ Branch 1 taken 153 times.
✗ Branch 2 not taken.
153 .addFunctionAttribute(llvm::Attribute::NoUnwind)
1160 153 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
1161
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 129 times.
153 .setConstantFold(op.mConstantFoldCBindings)
1162
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 129 times.
153 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
1163 .setDocumentation("Floored modulo, where the result of the division operator "
1164 "on (dividend / divisor) is floored. The remainder is thus calculated with "
1165 "D - d * floor(D/d). This is the implemented modulo % operator of AX. This is "
1166 "equal to the python % implementation. See trucnatemod(), euclideanmod().")
1167
1/2
✓ Branch 1 taken 153 times.
✗ Branch 2 not taken.
306 .get();
1168 }
1169
1170 13 inline FunctionGroup::UniquePtr axeuclideanmod(const FunctionOptions& op)
1171 {
1172 static auto iemod = [](auto D, auto d) -> auto
1173 {
1174 using ValueType = decltype(D);
1175 auto r = D%d;
1176 if (r < 0) {
1177 if (d > 0) r = r + d;
1178 else r = r - d;
1179 }
1180 return ValueType(r);
1181 };
1182
1183 static auto femod = [](auto D, auto d) -> auto
1184 {
1185 auto r = std::fmod(D, d);
1186 if (r < 0) {
1187 if (d > 0) r = r + d;
1188 else r = r - d;
1189 }
1190 return r;
1191 };
1192
1193 static auto generate =
1194
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 [](const std::vector<llvm::Value*>& args,
1195 llvm::IRBuilder<>& B) -> llvm::Value*
1196 {
1197
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 assert(args.size() == 2);
1198 12 llvm::Value* D = args[0], *d = args[1];
1199 12 llvm::Value* r = binaryOperator(D, d, ast::tokens::MODULO, B); // tmod
1200
1201 12 llvm::Value* zero = llvmConstant(0, D->getType());
1202 12 llvm::Value* a1 = binaryOperator(d, zero, ast::tokens::MORETHAN, B);
1203 12 llvm::Value* rplus = binaryOperator(r, d, ast::tokens::PLUS, B);
1204 12 llvm::Value* rminus = binaryOperator(r, d, ast::tokens::MINUS, B);
1205 12 llvm::Value* rd = B.CreateSelect(a1, rplus, rminus);
1206
1207 12 a1 = binaryOperator(r, zero, ast::tokens::LESSTHAN, B);
1208 12 return B.CreateSelect(a1, rd, r);
1209 };
1210
1211 13 return FunctionBuilder("euclideanmod")
1212 26 .addSignature<double(double,double)>(generate, (double(*)(double,double))(femod))
1213
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<float(float,float)>(generate, (float(*)(float,float))(femod))
1214
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<int64_t(int64_t,int64_t)>(generate, (int64_t(*)(int64_t,int64_t))(iemod))
1215
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<int32_t(int32_t,int32_t)>(generate, (int32_t(*)(int32_t,int32_t))(iemod))
1216
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"dividend", "divisor"})
1217
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::ReadOnly)
1218
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoRecurse)
1219
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
1220 13 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
1221
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
1222
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
1223 .setDocumentation("Euclidean modulo, where by the result of the division operator "
1224 "on (dividend / divisor) is floored or ceiled depending on its sign, guaranteeing "
1225 "that the return value is always positive. The remainder is thus calculated with "
1226 "D - d * (d < 0 ? ceil(D/d) : floor(D/d)). This is NOT equal to a%b in AX. See "
1227 "truncatemod(), floormod().")
1228
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
1229 }
1230
1231 13 inline FunctionGroup::UniquePtr axisfinite(const FunctionOptions& op)
1232 {
1233 auto generate =
1234
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 [op](const std::vector<llvm::Value*>& args,
1235 llvm::IRBuilder<>& B) -> llvm::Value*
1236 {
1237
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 assert(args.size() == 1);
1238
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 8 times.
48 llvm::Value* arg = args[0];
1239 llvm::Type* etype = arg->getType();
1240
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 8 times.
48 if (etype->isPointerTy()) {
1241 etype = etype->getPointerElementType()->getArrayElementType();
1242 }
1243
1244 llvm::Value* inf;
1245
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 24 times.
48 if (etype->isFloatTy()) {
1246 const llvm::APFloat apinf =
1247 24 llvm::APFloat::getInf(llvm::APFloatBase::IEEEsingle());
1248
2/4
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
24 inf = LLVMType<float>::get(B.getContext(), apinf.convertToFloat());
1249 }
1250 else {
1251
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 assert(etype->isDoubleTy());
1252 const llvm::APFloat apinf =
1253 24 llvm::APFloat::getInf(llvm::APFloatBase::IEEEdouble());
1254
2/4
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
24 inf = LLVMType<double>::get(B.getContext(), apinf.convertToDouble());
1255 }
1256
1257
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 40 times.
48 if (!arg->getType()->isPointerTy()) {
1258
2/4
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
16 arg = llvm_fabs(op)->execute({arg}, B);
1259 8 return binaryOperator(inf, arg, ast::tokens::NOTEQUALS, B);
1260 }
1261
1262 std::vector<llvm::Value*> array;
1263
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 arrayUnpack(arg, array, B, /*load*/true);
1264
1265 // @todo short-circuit?
1266 llvm::Value* result = B.getTrue();
1267
2/2
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 40 times.
312 for (auto& value : array) {
1268
4/8
✓ Branch 1 taken 272 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 272 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 272 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 272 times.
✗ Branch 10 not taken.
544 value = llvm_fabs(op)->execute({value}, B);
1269
1/2
✓ Branch 1 taken 272 times.
✗ Branch 2 not taken.
272 llvm::Value* comp = binaryOperator(inf, value, ast::tokens::NOTEQUALS, B);
1270
1/4
✓ Branch 1 taken 272 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
272 result = binaryOperator(comp, result, ast::tokens::AND, B);
1271 }
1272 return result;
1273 13 };
1274
1275 static auto isfinitearray = [](const auto input) -> bool
1276 {
1277 return input->isFinite();
1278 };
1279
1280 13 return FunctionBuilder("isfinite")
1281 26 .addSignature<bool(openvdb::Vec2d*)>(generate, (bool(*)(openvdb::Vec2d*))(isfinitearray))
1282
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::Vec2f*)>(generate, (bool(*)(openvdb::Vec2f*))(isfinitearray))
1283
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::Vec3d*)>(generate, (bool(*)(openvdb::Vec3d*))(isfinitearray))
1284
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::Vec3f*)>(generate, (bool(*)(openvdb::Vec3f*))(isfinitearray))
1285
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::Vec4d*)>(generate, (bool(*)(openvdb::Vec4d*))(isfinitearray))
1286
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::Vec4f*)>(generate, (bool(*)(openvdb::Vec4f*))(isfinitearray))
1287
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::math::Mat3<float>*)>(generate, (bool(*)(openvdb::math::Mat3<float>*))(isfinitearray))
1288
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::math::Mat3<double>*)>(generate, (bool(*)(openvdb::math::Mat3<double>*))(isfinitearray))
1289
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::math::Mat4<float>*)>(generate, (bool(*)(openvdb::math::Mat4<float>*))(isfinitearray))
1290
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::math::Mat4<double>*)>(generate, (bool(*)(openvdb::math::Mat4<double>*))(isfinitearray))
1291 13 .addParameterAttribute(0, llvm::Attribute::ReadOnly)
1292
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(double)>(generate, (bool(*)(double))(std::isfinite))
1293
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(float)>(generate, (bool(*)(float))(std::isfinite))
1294
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"arg"})
1295
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addDependency("fabs")
1296
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::ReadOnly)
1297
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoRecurse)
1298
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
1299 13 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
1300
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
1301
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
1302 .setDocumentation("Returns whether the value is finite i.e. not infinite or NaN. "
1303 "For matrix and vector types will return false if any element is not finite.")
1304
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
1305 }
1306
1307 13 inline FunctionGroup::UniquePtr axisinf(const FunctionOptions& op)
1308 {
1309 auto generate =
1310
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 [op](const std::vector<llvm::Value*>& args,
1311 llvm::IRBuilder<>& B) -> llvm::Value*
1312 {
1313
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 assert(args.size() == 1);
1314
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 8 times.
48 llvm::Value* arg = args[0];
1315 llvm::Type* etype = arg->getType();
1316
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 8 times.
48 if (etype->isPointerTy()) {
1317 etype = etype->getPointerElementType()->getArrayElementType();
1318 }
1319
1320 llvm::Value* inf;
1321
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 24 times.
48 if (etype->isFloatTy()) {
1322 const llvm::APFloat apinf =
1323 24 llvm::APFloat::getInf(llvm::APFloatBase::IEEEsingle());
1324
2/4
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
24 inf = LLVMType<float>::get(B.getContext(), apinf.convertToFloat());
1325 }
1326 else {
1327
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 assert(etype->isDoubleTy());
1328 const llvm::APFloat apinf =
1329 24 llvm::APFloat::getInf(llvm::APFloatBase::IEEEdouble());
1330
2/4
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 24 times.
✗ Branch 5 not taken.
24 inf = LLVMType<double>::get(B.getContext(), apinf.convertToDouble());
1331 }
1332
1333
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 40 times.
48 if (!arg->getType()->isPointerTy()) {
1334
2/4
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
16 arg = llvm_fabs(op)->execute({arg}, B);
1335 8 return binaryOperator(inf, arg, ast::tokens::EQUALSEQUALS, B);
1336 }
1337
1338 std::vector<llvm::Value*> array;
1339
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 arrayUnpack(arg, array, B, /*load*/true);
1340
1341 // @todo short-circuit?
1342 llvm::Value* result = B.getFalse();
1343
2/2
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 40 times.
312 for (auto& value : array) {
1344
4/8
✓ Branch 1 taken 272 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 272 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 272 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 272 times.
✗ Branch 10 not taken.
544 value = llvm_fabs(op)->execute({value}, B);
1345
1/2
✓ Branch 1 taken 272 times.
✗ Branch 2 not taken.
272 llvm::Value* comp = binaryOperator(inf, value, ast::tokens::EQUALSEQUALS, B);
1346
1/4
✓ Branch 1 taken 272 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
272 result = binaryOperator(comp, result, ast::tokens::OR, B);
1347 }
1348 return result;
1349 13 };
1350
1351 static auto isinfarray = [](const auto input) -> bool
1352 {
1353 return input->isInfinite();
1354 };
1355
1356 13 return FunctionBuilder("isinf")
1357 26 .addSignature<bool(openvdb::Vec2d*)>(generate, (bool(*)(openvdb::Vec2d*))(isinfarray))
1358
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::Vec2f*)>(generate, (bool(*)(openvdb::Vec2f*))(isinfarray))
1359
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::Vec3d*)>(generate, (bool(*)(openvdb::Vec3d*))(isinfarray))
1360
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::Vec3f*)>(generate, (bool(*)(openvdb::Vec3f*))(isinfarray))
1361
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::Vec4d*)>(generate, (bool(*)(openvdb::Vec4d*))(isinfarray))
1362
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::Vec4f*)>(generate, (bool(*)(openvdb::Vec4f*))(isinfarray))
1363
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::math::Mat3<float>*)>(generate, (bool(*)(openvdb::math::Mat3<float>*))(isinfarray))
1364
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::math::Mat3<double>*)>(generate, (bool(*)(openvdb::math::Mat3<double>*))(isinfarray))
1365
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::math::Mat4<float>*)>(generate, (bool(*)(openvdb::math::Mat4<float>*))(isinfarray))
1366
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::math::Mat4<double>*)>(generate, (bool(*)(openvdb::math::Mat4<double>*))(isinfarray))
1367 13 .addParameterAttribute(0, llvm::Attribute::ReadOnly)
1368
2/6
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
26 .addSignature<bool(double)>(generate /*, (bool(*)(double))(std::isinf)*/) // @note: gcc needs _GLIBCXX_NO_OBSOLETE_ISINF_ISNAN_DYNAMIC defined
1369
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(float)>(generate, (bool(*)(float))(std::isinf))
1370
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"arg"})
1371
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addDependency("fabs")
1372
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::ReadOnly)
1373
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoRecurse)
1374
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
1375 13 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
1376
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
1377
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
1378 .setDocumentation("Returns whether the value is inf. "
1379 "For matrix and vector types will return true if any element is inf.")
1380
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
1381 }
1382
1383 13 inline FunctionGroup::UniquePtr axisnan(const FunctionOptions& op)
1384 {
1385 static auto generate =
1386
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 [](const std::vector<llvm::Value*>& args,
1387 llvm::IRBuilder<>& B) -> llvm::Value*
1388 {
1389 // uno (unordered) comparison with self
1390 // https://llvm.org/docs/LangRef.html#fcmp-instruction
1391
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 assert(args.size() == 1);
1392
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 40 times.
48 llvm::Value* arg = args[0];
1393
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 40 times.
48 if (!arg->getType()->isPointerTy()) {
1394 16 return B.CreateFCmpUNO(arg, arg);
1395 }
1396
1397 std::vector<llvm::Value*> array;
1398
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 arrayUnpack(arg, array, B, /*load*/true);
1399
1400 // @todo short-circuit?
1401 llvm::Value* result = B.getFalse();
1402
2/2
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 40 times.
312 for (auto& value : array) {
1403
1/2
✓ Branch 2 taken 272 times.
✗ Branch 3 not taken.
272 llvm::Value* comp = B.CreateFCmpUNO(value, value);
1404
1/4
✓ Branch 1 taken 272 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
272 result = binaryOperator(comp, result, ast::tokens::OR, B);
1405 }
1406 return result;
1407 };
1408
1409 static auto isnanarray = [](const auto input) -> bool
1410 {
1411 return input->isNan();
1412 };
1413
1414 13 return FunctionBuilder("isnan")
1415 26 .addSignature<bool(openvdb::Vec2d*)>(generate, (bool(*)(openvdb::Vec2d*))(isnanarray))
1416
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::Vec2f*)>(generate, (bool(*)(openvdb::Vec2f*))(isnanarray))
1417
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::Vec3d*)>(generate, (bool(*)(openvdb::Vec3d*))(isnanarray))
1418
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::Vec3f*)>(generate, (bool(*)(openvdb::Vec3f*))(isnanarray))
1419
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::Vec4d*)>(generate, (bool(*)(openvdb::Vec4d*))(isnanarray))
1420
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::Vec4f*)>(generate, (bool(*)(openvdb::Vec4f*))(isnanarray))
1421
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::math::Mat3<float>*)>(generate, (bool(*)(openvdb::math::Mat3<float>*))(isnanarray))
1422
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::math::Mat3<double>*)>(generate, (bool(*)(openvdb::math::Mat3<double>*))(isnanarray))
1423
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::math::Mat4<float>*)>(generate, (bool(*)(openvdb::math::Mat4<float>*))(isnanarray))
1424
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(openvdb::math::Mat4<double>*)>(generate, (bool(*)(openvdb::math::Mat4<double>*))(isnanarray))
1425 13 .addParameterAttribute(0, llvm::Attribute::ReadOnly)
1426
2/6
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
26 .addSignature<bool(double)>(generate/*, (bool(*)(double))(std::isnan)*/) // @note: gcc needs _GLIBCXX_NO_OBSOLETE_ISINF_ISNAN_DYNAMIC defined
1427
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<bool(float)>(generate, (bool(*)(float))(std::isnan))
1428
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"arg"})
1429
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::ReadOnly)
1430
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoRecurse)
1431
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
1432 13 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
1433
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
1434
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
1435 .setDocumentation("Returns whether the value is NaN (not-a-number).")
1436
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
1437 }
1438
1439 ///////////////////////////////////////////////////////////////////////////
1440 ///////////////////////////////////////////////////////////////////////////
1441
1442 // Matrix math
1443
1444 13 inline FunctionGroup::UniquePtr axdeterminant(const FunctionOptions& op)
1445 {
1446 // 3 by 3 determinant
1447 static auto generate3 =
1448
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 [](const std::vector<llvm::Value*>& args,
1449 llvm::IRBuilder<>& B) -> llvm::Value*
1450 {
1451 std::vector<llvm::Value*> m1;
1452
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 arrayUnpack(args[0], m1, B, /*load*/true);
1453
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 40 times.
40 assert(m1.size() == 9);
1454
1455
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 llvm::Value* e1 = binaryOperator(m1[4], m1[8], ast::tokens::MULTIPLY, B);
1456
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 llvm::Value* e2 = binaryOperator(m1[5], m1[7], ast::tokens::MULTIPLY, B);
1457
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 llvm::Value* c0 = binaryOperator(e1, e2, ast::tokens::MINUS, B);
1458
1459
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 e1 = binaryOperator(m1[5], m1[6], ast::tokens::MULTIPLY, B);
1460
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 e2 = binaryOperator(m1[3], m1[8], ast::tokens::MULTIPLY, B);
1461
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 llvm::Value* c1 = binaryOperator(e1, e2, ast::tokens::MINUS, B);
1462
1463
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 e1 = binaryOperator(m1[3], m1[7], ast::tokens::MULTIPLY, B);
1464
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 e2 = binaryOperator(m1[4], m1[6], ast::tokens::MULTIPLY, B);
1465
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 llvm::Value* c2 = binaryOperator(e1, e2, ast::tokens::MINUS, B);
1466
1467
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 c0 = binaryOperator(m1[0], c0, ast::tokens::MULTIPLY, B);
1468
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 c1 = binaryOperator(m1[1], c1, ast::tokens::MULTIPLY, B);
1469
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 c2 = binaryOperator(m1[2], c2, ast::tokens::MULTIPLY, B);
1470
1471
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 c0 = binaryOperator(c0, c1, ast::tokens::PLUS, B);
1472
2/6
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
40 c0 = binaryOperator(c0, c2, ast::tokens::PLUS, B);
1473 40 return c0;
1474 };
1475
1476 // 4 by 4 determinant
1477 static auto generate4 =
1478
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 [](const std::vector<llvm::Value*>& args,
1479 llvm::IRBuilder<>& B) -> llvm::Value*
1480 {
1481 std::vector<llvm::Value*> m1;
1482
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 arrayUnpack(args[0], m1, B, /*load*/true);
1483
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 assert(m1.size() == 16);
1484
1485 // @note Okay to alloca here as long as embed IR is false
1486
3/8
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 8 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
8 llvm::Value* subMat = B.CreateAlloca(llvm::ArrayType::get(m1.front()->getType(), 9));
1487 std::vector<llvm::Value*> elements;
1488
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 arrayUnpack(subMat, elements, B, /*load elements*/false);
1489
1490
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 llvm::Value* result = llvm::ConstantFP::get(m1.front()->getType(), 0.0);
1491
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 8 times.
40 for (size_t i = 0; i < 4; ++i) {
1492 size_t sourceIndex = 0, targetIndex = 0;
1493
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 32 times.
160 for (size_t j = 0; j < 4; ++j) {
1494
2/2
✓ Branch 0 taken 512 times.
✓ Branch 1 taken 128 times.
640 for (size_t k = 0; k < 4; ++k) {
1495
2/2
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 224 times.
512 if ((k != i) && (j != 0)) {
1496
1/2
✓ Branch 1 taken 288 times.
✗ Branch 2 not taken.
288 B.CreateStore(m1[sourceIndex], elements[targetIndex]);
1497 288 ++targetIndex;
1498 }
1499 512 ++sourceIndex;
1500 }
1501 }
1502
2/4
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 32 times.
✗ Branch 5 not taken.
32 llvm::Value* subResult = generate3({subMat}, B);
1503
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 subResult = binaryOperator(m1[i], subResult, ast::tokens::MULTIPLY, B);
1504
1505
3/4
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
32 if (i % 2) result = binaryOperator(result, subResult, ast::tokens::MINUS, B);
1506
1/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
16 else result = binaryOperator(result, subResult, ast::tokens::PLUS, B);
1507 }
1508
1509 8 return result;
1510 };
1511
1512 static auto determinant = [](auto mat) -> auto {
1513 return mat->det();
1514 };
1515
1516 using DeterminantM3D = double(openvdb::math::Mat3<double>*);
1517 using DeterminantM3F = float(openvdb::math::Mat3<float>*);
1518 using DeterminantM4D = double(openvdb::math::Mat4<double>*);
1519 using DeterminantM4F = float(openvdb::math::Mat4<float>*);
1520
1521 13 return FunctionBuilder("determinant")
1522 26 .addSignature<DeterminantM3D>(generate3, (DeterminantM3D*)(determinant))
1523
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<DeterminantM3F>(generate3, (DeterminantM3F*)(determinant))
1524
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<DeterminantM4D>(generate4, (DeterminantM4D*)(determinant))
1525
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<DeterminantM4F>(generate4, (DeterminantM4F*)(determinant))
1526
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"mat"})
1527
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::ReadOnly)
1528
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
1529 13 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
1530
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
1531
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
1532 .setDocumentation("Returns the determinant of a matrix.")
1533
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
1534 }
1535
1536 13 inline FunctionGroup::UniquePtr axdiag(const FunctionOptions& op)
1537 {
1538 static auto generate =
1539
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 [](const std::vector<llvm::Value*>& args,
1540 llvm::IRBuilder<>& B) -> llvm::Value*
1541 {
1542 std::vector<llvm::Value*> ptrs, arg1;
1543
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 arrayUnpack(args[0], ptrs, B, /*load*/false);
1544
1/2
✓ Branch 1 taken 32 times.
✗ Branch 2 not taken.
32 arrayUnpack(args[1], arg1, B, /*load*/true);
1545
1546 const size_t size = arg1.size();
1547
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 16 times.
32 if (size == 3 || size == 4) {
1548 //vector - convert to diagonal matrix
1549
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 const size_t dim = size*size;
1550
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 assert(ptrs.size() == dim);
1551
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 llvm::Type* type = arg1.front()->getType();
1552
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 llvm::Value* zero = type->isFloatTy() ? LLVMType<float>::get(B.getContext(), 0.0f)
1553
3/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
16 : LLVMType<double>::get(B.getContext(), 0.0);
1554
1555
2/2
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 16 times.
216 for (size_t i = 0, j = 0; i < dim; ++i) {
1556 llvm::Value* m = zero;
1557
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 144 times.
200 if (i % (size + 1) == 0) {
1558 56 m = arg1[j];
1559 56 ++j;
1560 }
1561
1/2
✓ Branch 1 taken 200 times.
✗ Branch 2 not taken.
200 B.CreateStore(m, ptrs[i]);
1562 }
1563 }
1564 else {
1565 // matrix - convert to vector
1566
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 assert(size == 9 || size == 16);
1567
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 const size_t dim = size == 9 ? 3 : 4;
1568
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 assert(ptrs.size() == dim);
1569
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 16 times.
72 for (size_t i = 0; i < dim; ++i) {
1570
1/2
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
56 B.CreateStore(arg1[i+(i*dim)], ptrs[i]);
1571 }
1572 }
1573
1574 32 return nullptr;
1575 };
1576
1577 592 static auto diag = [](auto result, const auto input)
1578 {
1579 using ValueType = typename std::remove_pointer<decltype(input)>::type;
1580 using ResultType = typename std::remove_pointer<decltype(result)>::type;
1581 using ElementT = typename openvdb::ValueTraits<ValueType>::ElementType;
1582 using RElementT = typename openvdb::ValueTraits<ResultType>::ElementType;
1583
1584 static_assert(std::is_same<ElementT, RElementT>::value,
1585 "Input and result arguments for diag are not the same type");
1586
1587 if (openvdb::ValueTraits<ValueType>::IsVec) {
1588 // input is a vec, result is a matrix
1589 const int size = openvdb::ValueTraits<ValueType>::Size;
1590 int element = 0;
1591
2/2
✓ Branch 0 taken 1036 times.
✓ Branch 1 taken 296 times.
2664 for (int i = 0; i < size; ++i) {
1592
2/2
✓ Branch 0 taken 3700 times.
✓ Branch 1 taken 1036 times.
9472 for (int j = 0; j < size; ++j) {
1593
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3700 times.
7400 assert(element < openvdb::ValueTraits<ResultType>::Elements);
1594
2/2
✓ Branch 0 taken 1036 times.
✓ Branch 1 taken 2664 times.
7400 if (i == j) result->asPointer()[element] = (input->asPointer())[i];
1595 5328 else result->asPointer()[element] = ElementT(0.0);
1596 7400 ++element;
1597 }
1598 }
1599 }
1600 else {
1601 assert(openvdb::ValueTraits<ValueType>::IsMat);
1602 // input is a matrix, result is a vec
1603 const int size = openvdb::ValueTraits<ValueType>::Size;
1604 for (int i = 0; i < size; ++i) {
1605 assert(i < openvdb::ValueTraits<ResultType>::Size);
1606 result->asPointer()[i] = input->asPointer()[i+(i*size)];
1607 }
1608 }
1609 592 };
1610
1611 using DiagV3M3D = void(openvdb::math::Vec3<double>*, openvdb::math::Mat3<double>*);
1612 using DiagV3M3F = void(openvdb::math::Vec3<float>*, openvdb::math::Mat3<float>*);
1613 using DiagV4M4D = void(openvdb::math::Vec4<double>*, openvdb::math::Mat4<double>*);
1614 using DiagV4M4F = void(openvdb::math::Vec4<float>*, openvdb::math::Mat4<float>*);
1615
1616 using DiagM3V3D = void(openvdb::math::Mat3<double>*, openvdb::math::Vec3<double>*);
1617 using DiagM3V3F = void(openvdb::math::Mat3<float>*, openvdb::math::Vec3<float>*);
1618 using DiagM4V4D = void(openvdb::math::Mat4<double>*, openvdb::math::Vec4<double>*);
1619 using DiagM4V4F = void(openvdb::math::Mat4<float>*, openvdb::math::Vec4<float>*);
1620
1621 13 return FunctionBuilder("diag")
1622 26 .addSignature<DiagV3M3D, true>(generate, (DiagV3M3D*)(diag))
1623
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<DiagV3M3F, true>(generate, (DiagV3M3F*)(diag))
1624
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<DiagV4M4D, true>(generate, (DiagV4M4D*)(diag))
1625
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<DiagV4M4F, true>(generate, (DiagV4M4F*)(diag))
1626
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"vec"})
1627
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::WriteOnly)
1628
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::NoAlias)
1629
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(1, llvm::Attribute::ReadOnly)
1630
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
1631 13 .addFunctionAttribute(llvm::Attribute::InlineHint)
1632 13 .setConstantFold(op.mConstantFoldCBindings)
1633
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<DiagM3V3D, true>(generate, (DiagM3V3D*)(diag))
1634
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<DiagM3V3F, true>(generate, (DiagM3V3F*)(diag))
1635
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<DiagM4V4D, true>(generate, (DiagM4V4D*)(diag))
1636
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<DiagM4V4F, true>(generate, (DiagM4V4F*)(diag))
1637
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"mat"})
1638
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::WriteOnly)
1639
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::NoAlias)
1640
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(1, llvm::Attribute::ReadOnly)
1641
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
1642 13 .addFunctionAttribute(llvm::Attribute::InlineHint)
1643
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
1644
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
1645 .setDocumentation("Create a diagonal matrix from a vector, or return the diagonal "
1646 "components of a matrix as a vector.")
1647
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
1648 }
1649
1650 50 inline FunctionGroup::UniquePtr axidentity3(const FunctionOptions& op)
1651 {
1652 static auto generate =
1653
1/2
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
49 [](const std::vector<llvm::Value*>& args,
1654 llvm::IRBuilder<>& B) -> llvm::Value*
1655 {
1656 std::vector<llvm::Value*> elements;
1657
1/2
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
49 arrayUnpack(args[0], elements, B, /*load elements*/false);
1658
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 49 times.
49 assert(elements.size() == 9);
1659
1/2
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
49 llvm::Value* zero = LLVMType<float>::get(B.getContext(), 0.0f);
1660
1/2
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
49 llvm::Value* one = LLVMType<float>::get(B.getContext(), 1.0f);
1661
2/2
✓ Branch 0 taken 441 times.
✓ Branch 1 taken 49 times.
490 for (size_t i = 0; i < 9; ++i) {
1662
4/4
✓ Branch 0 taken 343 times.
✓ Branch 1 taken 98 times.
✓ Branch 2 taken 294 times.
✓ Branch 3 taken 49 times.
441 llvm::Value* m = ((i == 0 || i == 4 || i == 8) ? one : zero);
1663
1/2
✓ Branch 1 taken 441 times.
✗ Branch 2 not taken.
441 B.CreateStore(m, elements[i]);
1664 }
1665 49 return nullptr;
1666 };
1667
1668 50 return FunctionBuilder("identity3")
1669
1/2
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
100 .addSignature<void(openvdb::math::Mat3<float>*), true>(generate)
1670 .setConstantFold(false)
1671
1/2
✓ Branch 1 taken 50 times.
✗ Branch 2 not taken.
50 .addFunctionAttribute(llvm::Attribute::NoUnwind)
1672 50 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
1673
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 18 times.
50 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
1674 .setDocumentation("Returns the 3x3 identity matrix")
1675
1/2
✓ Branch 1 taken 50 times.
✗ Branch 2 not taken.
100 .get();
1676 }
1677
1678 49 inline FunctionGroup::UniquePtr axidentity4(const FunctionOptions& op)
1679 {
1680 static auto generate =
1681
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 [](const std::vector<llvm::Value*>& args,
1682 llvm::IRBuilder<>& B) -> llvm::Value*
1683 {
1684 std::vector<llvm::Value*> elements;
1685
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 arrayUnpack(args[0], elements, B, /*load elements*/false);
1686
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 assert(elements.size() == 16);
1687
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 llvm::Value* zero = LLVMType<float>::get(B.getContext(), 0.0f);
1688
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 llvm::Value* one = LLVMType<float>::get(B.getContext(), 1.0f);
1689
2/2
✓ Branch 0 taken 768 times.
✓ Branch 1 taken 48 times.
816 for (size_t i = 0; i < 16; ++i) {
1690
4/4
✓ Branch 0 taken 672 times.
✓ Branch 1 taken 96 times.
✓ Branch 2 taken 576 times.
✓ Branch 3 taken 96 times.
768 llvm::Value* m = ((i == 0 || i == 5 || i == 10 || i == 15) ? one : zero);
1691
1/2
✓ Branch 1 taken 768 times.
✗ Branch 2 not taken.
768 B.CreateStore(m, elements[i]);
1692 }
1693 48 return nullptr;
1694 };
1695
1696 49 return FunctionBuilder("identity4")
1697
1/2
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
98 .addSignature<void(openvdb::math::Mat4<float>*), true>(generate)
1698 .setConstantFold(false)
1699
1/2
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
49 .addFunctionAttribute(llvm::Attribute::NoUnwind)
1700 49 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
1701
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 17 times.
49 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
1702 .setDocumentation("Returns the 4x4 identity matrix")
1703
1/2
✓ Branch 1 taken 49 times.
✗ Branch 2 not taken.
98 .get();
1704 }
1705
1706 37 inline FunctionGroup::UniquePtr axmmmult(const FunctionOptions& op)
1707 {
1708 static auto generate =
1709
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 [](const std::vector<llvm::Value*>& args,
1710 llvm::IRBuilder<>& B) -> llvm::Value*
1711 {
1712 std::vector<llvm::Value*> ptrs, m1, m2;
1713
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 arrayUnpack(args[0], ptrs, B, /*load*/false);
1714
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 arrayUnpack(args[1], m1, B, /*load*/true);
1715
1/2
✓ Branch 1 taken 48 times.
✗ Branch 2 not taken.
48 arrayUnpack(args[2], m2, B, /*load*/true);
1716
1717
3/4
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 24 times.
48 assert(m1.size() == 9 || m1.size() == 16);
1718
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 assert(ptrs.size() == m1.size());
1719
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
48 assert(ptrs.size() == m2.size());
1720
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 24 times.
48 const size_t dim = m1.size() == 9 ? 3 : 4;
1721
1722 llvm::Value* e3 = nullptr, *e4 = nullptr;
1723
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 48 times.
216 for (size_t i = 0; i < dim; ++i) {
1724 168 const size_t row = i*dim;
1725
2/2
✓ Branch 0 taken 600 times.
✓ Branch 1 taken 168 times.
768 for (size_t j = 0; j < dim; ++j) {
1726
1/2
✓ Branch 1 taken 600 times.
✗ Branch 2 not taken.
600 llvm::Value* e1 = binaryOperator(m1[0+row], m2[j], ast::tokens::MULTIPLY, B);
1727
1/2
✓ Branch 1 taken 600 times.
✗ Branch 2 not taken.
600 llvm::Value* e2 = binaryOperator(m1[1+row], m2[dim+j], ast::tokens::MULTIPLY, B);
1728
2/4
✓ Branch 0 taken 600 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 600 times.
✗ Branch 4 not taken.
600 if (dim >=3) e3 = binaryOperator(m1[2+row], m2[(dim*2)+j], ast::tokens::MULTIPLY, B);
1729
3/4
✓ Branch 0 taken 384 times.
✓ Branch 1 taken 216 times.
✓ Branch 3 taken 384 times.
✗ Branch 4 not taken.
600 if (dim >=4) e4 = binaryOperator(m1[3+row], m2[(dim*3)+j], ast::tokens::MULTIPLY, B);
1730
1/2
✓ Branch 1 taken 600 times.
✗ Branch 2 not taken.
600 e1 = binaryOperator(e1, e2, ast::tokens::PLUS, B);
1731
2/4
✓ Branch 0 taken 600 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 600 times.
✗ Branch 4 not taken.
600 if (dim >=3) e1 = binaryOperator(e1, e3, ast::tokens::PLUS, B);
1732
3/6
✓ Branch 0 taken 384 times.
✓ Branch 1 taken 216 times.
✓ Branch 3 taken 384 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
600 if (dim >=4) e1 = binaryOperator(e1, e4, ast::tokens::PLUS, B);
1733
1/2
✓ Branch 1 taken 600 times.
✗ Branch 2 not taken.
600 B.CreateStore(e1, ptrs[row+j]);
1734 }
1735 }
1736
1737 48 return nullptr;
1738 };
1739
1740 static auto mmmult = [](auto out, auto mat2, auto mat1) {
1741 *out = (*mat1) * (*mat2);
1742 };
1743
1744 using MMMultM3D = void(openvdb::math::Mat3<double>*, openvdb::math::Mat3<double>*, openvdb::math::Mat3<double>*);
1745 using MMMultM3F = void(openvdb::math::Mat3<float>*, openvdb::math::Mat3<float>*, openvdb::math::Mat3<float>*);
1746 using MMMultM4D = void(openvdb::math::Mat4<double>*, openvdb::math::Mat4<double>*, openvdb::math::Mat4<double>*);
1747 using MMMultM4F = void(openvdb::math::Mat4<float>*, openvdb::math::Mat4<float>*, openvdb::math::Mat4<float>*);
1748
1749 37 return FunctionBuilder("mmmult")
1750 74 .addSignature<MMMultM3D, true>(generate, (MMMultM3D*)(mmmult))
1751
1/4
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
74 .addSignature<MMMultM3F, true>(generate, (MMMultM3F*)(mmmult))
1752
1/4
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
74 .addSignature<MMMultM4D, true>(generate, (MMMultM4D*)(mmmult))
1753
1/4
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
74 .addSignature<MMMultM4F, true>(generate, (MMMultM4F*)(mmmult))
1754
3/8
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 37 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 37 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
74 .setArgumentNames({"a", "b"})
1755
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 .addParameterAttribute(0, llvm::Attribute::NoAlias)
1756
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 .addParameterAttribute(0, llvm::Attribute::WriteOnly)
1757
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 .addParameterAttribute(1, llvm::Attribute::ReadOnly)
1758
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 .addParameterAttribute(2, llvm::Attribute::ReadOnly)
1759
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
37 .addFunctionAttribute(llvm::Attribute::NoUnwind)
1760 37 .addFunctionAttribute(llvm::Attribute::InlineHint)
1761
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
37 .setConstantFold(op.mConstantFoldCBindings)
1762
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
37 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
1763 .setDocumentation("Multiplies two matrices together and returns the result")
1764
1/2
✓ Branch 1 taken 37 times.
✗ Branch 2 not taken.
74 .get();
1765 }
1766
1767 13 inline FunctionGroup::UniquePtr axpolardecompose(const FunctionOptions& op)
1768 {
1769 25178154 static auto polardecompose = [](auto in, auto orth, auto symm) -> bool {
1770 bool success = false;
1771 try {
1772
1/2
✓ Branch 1 taken 12589077 times.
✗ Branch 2 not taken.
25178154 success = openvdb::math::polarDecomposition(*in, *orth, *symm);
1773 }
1774 catch (const openvdb::ArithmeticError&) {
1775 success = false;
1776 }
1777 25178154 return success;
1778 };
1779
1780 using PolarDecompositionM3D =
1781 bool(openvdb::math::Mat3<double>*,
1782 openvdb::math::Mat3<double>*,
1783 openvdb::math::Mat3<double>*);
1784 using PolarDecompositionM3F =
1785 bool(openvdb::math::Mat3<float>*,
1786 openvdb::math::Mat3<float>*,
1787 openvdb::math::Mat3<float>*);
1788
1789 13 return FunctionBuilder("polardecompose")
1790
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<PolarDecompositionM3D>((PolarDecompositionM3D*)(polardecompose))
1791
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<PolarDecompositionM3F>((PolarDecompositionM3F*)(polardecompose))
1792
2/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
26 .setArgumentNames({"input", "unitary", "symmetric"})
1793
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::ReadOnly)
1794 13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
1795
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
1796
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
1797 .setDocumentation("Decompose an invertible 3x3 matrix into its orthogonal (unitary) "
1798 "matrix and symmetric matrix components. If the determinant of the unitary matrix "
1799 "is 1 it is a rotation, otherwise if it is -1 there is some part reflection.")
1800
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
1801 }
1802
1803 13 inline FunctionGroup::UniquePtr axpostscale(const FunctionOptions& op)
1804 {
1805 static auto generate =
1806
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 [](const std::vector<llvm::Value*>& args,
1807 llvm::IRBuilder<>& B) -> llvm::Value*
1808 {
1809 std::vector<llvm::Value*> m1, v1;
1810
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 arrayUnpack(args[0], m1, B, /*load*/false);
1811
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 arrayUnpack(args[1], v1, B, /*load*/true);
1812
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 assert(m1.size() == 16);
1813
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 assert(v1.size() == 3);
1814
1815 // modify first 3 elements in all mat rows
1816
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 8 times.
40 for (size_t row = 0; row < 4; ++row) {
1817
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 32 times.
128 for (size_t col = 0; col < 3; ++col) {
1818 96 const size_t idx = (row*4) + col;
1819
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 assert(idx <= 14);
1820
1/2
✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
96 llvm::Value* m1v = B.CreateLoad(m1[idx]);
1821
2/6
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 96 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
96 m1v = binaryOperator(m1v, v1[col], ast::tokens::MULTIPLY, B);
1822
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 B.CreateStore(m1v, m1[idx]);
1823 }
1824 }
1825
1826 // @warning this is invalid for embedded IR
1827 8 return nullptr;
1828 };
1829
1830 static auto postscale = [](auto mat, auto vec) {
1831 mat->postScale(*vec);
1832 };
1833
1834 using PostscaleM4D = void(openvdb::math::Mat4<double>*, openvdb::math::Vec3<double>*);
1835 using PostscaleM4F = void(openvdb::math::Mat4<float>*, openvdb::math::Vec3<float>*);
1836
1837 13 return FunctionBuilder("postscale")
1838 26 .addSignature<PostscaleM4D>(generate, (PostscaleM4D*)(postscale))
1839
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<PostscaleM4F>(generate, (PostscaleM4F*)(postscale))
1840
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"transform", "vec"})
1841
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(1, llvm::Attribute::ReadOnly)
1842
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
1843 13 .addFunctionAttribute(llvm::Attribute::InlineHint)
1844
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
1845
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
1846 .setDocumentation("Post-scale a given matrix by the provided vector.")
1847
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
1848 }
1849
1850 13 inline FunctionGroup::UniquePtr axpretransform(const FunctionOptions& op)
1851 {
1852 static auto generate =
1853
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 [](const std::vector<llvm::Value*>& args,
1854 llvm::IRBuilder<>& B) -> llvm::Value*
1855 {
1856 std::vector<llvm::Value*> ptrs, m1, v1;
1857
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 arrayUnpack(args[0], ptrs, B, /*load*/false);
1858
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 arrayUnpack(args[1], m1, B, /*load*/true);
1859
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 arrayUnpack(args[2], v1, B, /*load*/true);
1860
1861 const size_t vec = v1.size();
1862
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
12 const size_t dim = (m1.size() == 9 ? 3 : 4);
1863
1864
3/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
12 assert(m1.size() == 9 || m1.size() == 16);
1865
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 assert(vec == 3 || vec == 4);
1866
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 assert(ptrs.size() == vec);
1867
1868 // mat * vec
1869 llvm::Value* e3 = nullptr, *e4 = nullptr;
1870
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 12 times.
52 for (size_t i = 0; i < vec; ++i) {
1871
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 llvm::Value* e1 = binaryOperator(v1[0], m1[0+(i*dim)], ast::tokens::MULTIPLY, B);
1872
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 llvm::Value* e2 = binaryOperator(v1[1], m1[1+(i*dim)], ast::tokens::MULTIPLY, B);
1873
2/4
✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
40 if (dim >= 3) e3 = binaryOperator(v1[2], m1[2+(i*dim)], ast::tokens::MULTIPLY, B);
1874
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 12 times.
40 if (dim == 4) {
1875
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 16 times.
28 if (vec == 3) e4 = m1[3+(i*dim)];
1876
2/4
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
16 else if (vec == 4) e4 = binaryOperator(v1[3], m1[3+(i*dim)], ast::tokens::MULTIPLY, B);
1877 }
1878
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 e1 = binaryOperator(e1, e2, ast::tokens::PLUS, B);
1879
2/4
✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
40 if (e3) e1 = binaryOperator(e1, e3, ast::tokens::PLUS, B);
1880
3/6
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 12 times.
✓ Branch 3 taken 28 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
40 if (e4) e1 = binaryOperator(e1, e4, ast::tokens::PLUS, B);
1881
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 B.CreateStore(e1, ptrs[i]);
1882 }
1883
1884 12 return nullptr;
1885 };
1886
1887 static auto transform = [](auto out, auto mat, auto vec) {
1888 *out = mat->pretransform(*vec);
1889 };
1890
1891 using PretransformM3DV3D = void(openvdb::math::Vec3<double>*, openvdb::math::Mat3<double>*, openvdb::math::Vec3<double>*);
1892 using PretransformM3FV3F = void(openvdb::math::Vec3<float>*, openvdb::math::Mat3<float>*, openvdb::math::Vec3<float>*);
1893 using PretransformM4DV3D = void(openvdb::math::Vec3<double>*, openvdb::math::Mat4<double>*, openvdb::math::Vec3<double>*);
1894 using PretransformM4FV3F = void(openvdb::math::Vec3<float>*, openvdb::math::Mat4<float>*, openvdb::math::Vec3<float>*);
1895 using PretransformM4DV4D = void(openvdb::math::Vec4<double>*, openvdb::math::Mat4<double>*, openvdb::math::Vec4<double>*);
1896 using PretransformM4FV4F = void(openvdb::math::Vec4<float>*, openvdb::math::Mat4<float>*, openvdb::math::Vec4<float>*);
1897
1898 13 return FunctionBuilder("pretransform")
1899 26 .addSignature<PretransformM3DV3D, true>(generate, (PretransformM3DV3D*)(transform))
1900
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<PretransformM3FV3F, true>(generate, (PretransformM3FV3F*)(transform))
1901
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<PretransformM4DV3D, true>(generate, (PretransformM4DV3D*)(transform))
1902
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<PretransformM4FV3F, true>(generate, (PretransformM4FV3F*)(transform))
1903
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<PretransformM4DV4D, true>(generate, (PretransformM4DV4D*)(transform))
1904
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<PretransformM4FV4F, true>(generate, (PretransformM4FV4F*)(transform))
1905
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"vec", "mat"})
1906
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::NoAlias) // alloced by the function, always no alias
1907
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::WriteOnly)
1908
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(1, llvm::Attribute::ReadOnly)
1909
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(2, llvm::Attribute::ReadOnly)
1910
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
1911 13 .addFunctionAttribute(llvm::Attribute::InlineHint)
1912
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
1913
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
1914 .setDocumentation("Return the transformed vector by transpose of this matrix. "
1915 "This function is equivalent to pre-multiplying the matrix.")
1916
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
1917 }
1918
1919 13 inline FunctionGroup::UniquePtr axprescale(const FunctionOptions& op)
1920 {
1921 static auto generate =
1922
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 [](const std::vector<llvm::Value*>& args,
1923 llvm::IRBuilder<>& B) -> llvm::Value*
1924 {
1925 std::vector<llvm::Value*> m1, v1;
1926
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 arrayUnpack(args[0], m1, B, /*load*/false);
1927
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 arrayUnpack(args[1], v1, B, /*load*/true);
1928
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 assert(m1.size() == 16);
1929
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 assert(v1.size() == 3);
1930
1931 // modify first 3 mat rows, all columns
1932
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 8 times.
32 for (size_t row = 0; row < 3; ++row) {
1933
2/2
✓ Branch 0 taken 96 times.
✓ Branch 1 taken 24 times.
120 for (size_t col = 0; col < 4; ++col) {
1934 96 const size_t idx = (row*4) + col;
1935
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 96 times.
96 assert(idx <= 11);
1936
1/2
✓ Branch 2 taken 96 times.
✗ Branch 3 not taken.
96 llvm::Value* m1v = B.CreateLoad(m1[idx]);
1937
2/6
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 96 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
96 m1v = binaryOperator(m1v, v1[row], ast::tokens::MULTIPLY, B);
1938
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 B.CreateStore(m1v, m1[idx]);
1939 }
1940 }
1941 // @warning this is invalid for embedded IR
1942 8 return nullptr;
1943 };
1944
1945 static auto prescale = [](auto mat, auto vec) {
1946 mat->preScale(*vec);
1947 };
1948
1949 using PrescaleM4D = void(openvdb::math::Mat4<double>*, openvdb::math::Vec3<double>*);
1950 using PrescaleM4F = void(openvdb::math::Mat4<float>*, openvdb::math::Vec3<float>*);
1951
1952 13 return FunctionBuilder("prescale")
1953 26 .addSignature<PrescaleM4D>(generate, (PrescaleM4D*)(prescale))
1954
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<PrescaleM4F>(generate, (PrescaleM4F*)(prescale))
1955
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"transform", "vec"})
1956
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(1, llvm::Attribute::ReadOnly)
1957
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
1958 13 .addFunctionAttribute(llvm::Attribute::InlineHint)
1959
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
1960
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
1961 .setDocumentation("Pre-scale a given matrix by the provided vector.")
1962
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
1963 }
1964
1965 13 inline FunctionGroup::UniquePtr axtrace(const FunctionOptions& op)
1966 {
1967 static auto generate =
1968
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 [](const std::vector<llvm::Value*>& args,
1969 llvm::IRBuilder<>& B) -> llvm::Value*
1970 {
1971 std::vector<llvm::Value*> m1;
1972
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 arrayUnpack(args[0], m1, B, /*load*/true);
1973
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 const size_t dim = (m1.size() == 9 ? 3 : 4);
1974
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
8 assert(m1.size() == 9 || m1.size() == 16);
1975
1976
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 llvm::Value* result = binaryOperator(m1[0], m1[1+dim], ast::tokens::PLUS, B);
1977
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 result = binaryOperator(result, m1[2+(2*dim)], ast::tokens::PLUS, B);
1978
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (dim == 4) {
1979 result = binaryOperator(result, m1[3+(3*dim)], ast::tokens::PLUS, B);
1980 }
1981
1982 8 return result;
1983 };
1984
1985 static auto trace = [](const auto input) -> auto
1986 {
1987 using MatType = typename std::remove_pointer<decltype(input)>::type;
1988 using ElementT = typename openvdb::ValueTraits<MatType>::ElementType;
1989 ElementT value((*input)(static_cast<int>(0), static_cast<int>(0)));
1990 for (size_t i = 1; i < MatType::numRows(); ++i) {
1991 value += (*input)(static_cast<int>(i), static_cast<int>(i));
1992 }
1993 return value;
1994 };
1995
1996 using TraceM3D = double(openvdb::math::Mat3<double>*);
1997 using TraceM3F = float(openvdb::math::Mat3<float>*);
1998 using TraceM4D = double(openvdb::math::Mat4<double>*);
1999 using TraceM4F = float(openvdb::math::Mat4<float>*);
2000
2001 13 return FunctionBuilder("trace")
2002 26 .addSignature<TraceM3D>(generate, (TraceM3D*)(trace))
2003
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<TraceM3F>(generate, (TraceM3F*)(trace))
2004
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<TraceM4D>(generate, (TraceM4D*)(trace))
2005
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<TraceM4F>(generate, (TraceM4F*)(trace))
2006
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"mat"})
2007
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::ReadOnly)
2008
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
2009 13 .addFunctionAttribute(llvm::Attribute::InlineHint)
2010
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
2011
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
2012 .setDocumentation("Return the trace of a matrix, the sum of the diagonal elements.")
2013
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
2014 }
2015
2016 13 inline FunctionGroup::UniquePtr axtransform(const FunctionOptions& op)
2017 {
2018 static auto generate =
2019
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 [](const std::vector<llvm::Value*>& args,
2020 llvm::IRBuilder<>& B) -> llvm::Value*
2021 {
2022 std::vector<llvm::Value*> ptrs, m1, v1;
2023
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 arrayUnpack(args[0], ptrs, B, /*load*/false);
2024
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 arrayUnpack(args[1], v1, B, /*load*/true);
2025
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 arrayUnpack(args[2], m1, B, /*load*/true);
2026
2027 const size_t vec = v1.size();
2028
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
12 const size_t dim = (m1.size() == 9 ? 3 : 4);
2029
2030
3/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
12 assert(m1.size() == 9 || m1.size() == 16);
2031
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 assert(vec == 3 || vec == 4);
2032
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 assert(ptrs.size() == vec);
2033
2034 // vec * mat
2035 llvm::Value* e3 = nullptr, *e4 = nullptr;
2036
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 12 times.
52 for (size_t i = 0; i < vec; ++i) {
2037
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 llvm::Value* e1 = binaryOperator(v1[0], m1[i+(0*dim)], ast::tokens::MULTIPLY, B);
2038
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 llvm::Value* e2 = binaryOperator(v1[1], m1[i+(1*dim)], ast::tokens::MULTIPLY, B);
2039
2/4
✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
40 if (dim >= 3) e3 = binaryOperator(v1[2], m1[i+(2*dim)], ast::tokens::MULTIPLY, B);
2040
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 12 times.
40 if (dim == 4) {
2041
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 16 times.
28 if (vec == 3) e4 = m1[i+(3*dim)];
2042
2/4
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
16 else if (vec == 4) e4 = binaryOperator(v1[3], m1[i+(3*dim)], ast::tokens::MULTIPLY, B);
2043 }
2044
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 e1 = binaryOperator(e1, e2, ast::tokens::PLUS, B);
2045
2/4
✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
✓ Branch 3 taken 40 times.
✗ Branch 4 not taken.
40 if (e3) e1 = binaryOperator(e1, e3, ast::tokens::PLUS, B);
2046
3/6
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 12 times.
✓ Branch 3 taken 28 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
40 if (e4) e1 = binaryOperator(e1, e4, ast::tokens::PLUS, B);
2047
1/2
✓ Branch 1 taken 40 times.
✗ Branch 2 not taken.
40 B.CreateStore(e1, ptrs[i]);
2048 }
2049
2050 12 return nullptr;
2051 };
2052
2053 static auto transform = [](auto out, auto vec, auto mat) {
2054 *out = mat->transform(*vec);
2055 };
2056
2057 using TransformV3DM3D = void(openvdb::math::Vec3<double>*, openvdb::math::Vec3<double>*, openvdb::math::Mat3<double>*);
2058 using TransformV3FM3F = void(openvdb::math::Vec3<float>*, openvdb::math::Vec3<float>*, openvdb::math::Mat3<float>*);
2059 using TransformV3DM4D = void(openvdb::math::Vec3<double>*, openvdb::math::Vec3<double>*, openvdb::math::Mat4<double>*);
2060 using TransformV3FM4F = void(openvdb::math::Vec3<float>*, openvdb::math::Vec3<float>*, openvdb::math::Mat4<float>*);
2061 using TransformV4DM4D = void(openvdb::math::Vec4<double>*, openvdb::math::Vec4<double>*, openvdb::math::Mat4<double>*);
2062 using TransformV4FM4F = void(openvdb::math::Vec4<float>*, openvdb::math::Vec4<float>*, openvdb::math::Mat4<float>*);
2063
2064 13 return FunctionBuilder("transform")
2065 26 .addSignature<TransformV3DM3D, true>(generate, (TransformV3DM3D*)(transform))
2066
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<TransformV3FM3F, true>(generate, (TransformV3FM3F*)(transform))
2067
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<TransformV3DM4D, true>(generate, (TransformV3DM4D*)(transform))
2068
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<TransformV3FM4F, true>(generate, (TransformV3FM4F*)(transform))
2069
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<TransformV4DM4D, true>(generate, (TransformV4DM4D*)(transform))
2070
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<TransformV4FM4F, true>(generate, (TransformV4FM4F*)(transform))
2071
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"vec", "mat"})
2072
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::NoAlias) // alloced by the function, always no alias
2073
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::WriteOnly)
2074
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(1, llvm::Attribute::ReadOnly)
2075
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(2, llvm::Attribute::ReadOnly)
2076
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
2077 13 .addFunctionAttribute(llvm::Attribute::InlineHint)
2078
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
2079
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
2080 .setDocumentation("Return the transformed vector by the provided "
2081 "matrix. This function is equivalent to post-multiplying the matrix, i.e. vec * mult.")
2082
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
2083 }
2084
2085 13 inline FunctionGroup::UniquePtr axtranspose(const FunctionOptions& op)
2086 {
2087 static auto generate =
2088
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 [](const std::vector<llvm::Value*>& args,
2089 llvm::IRBuilder<>& B) -> llvm::Value*
2090 {
2091 std::vector<llvm::Value*> ptrs, m1;
2092
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 arrayUnpack(args[0], ptrs, B, /*load*/false);
2093
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 arrayUnpack(args[1], m1, B, /*load*/true);
2094
3/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
16 assert(m1.size() == 9 || m1.size() == 16);
2095
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 assert(ptrs.size() == m1.size());
2096
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 const size_t dim = m1.size() == 9 ? 3 : 4;
2097
2098
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 16 times.
72 for (size_t i = 0; i < dim; ++i) {
2099
2/2
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 56 times.
256 for (size_t j = 0; j < dim; ++j) {
2100 200 const size_t source = (i*dim) + j;
2101
1/2
✓ Branch 1 taken 200 times.
✗ Branch 2 not taken.
200 const size_t target = (j*dim) + i;
2102
1/2
✓ Branch 1 taken 200 times.
✗ Branch 2 not taken.
200 B.CreateStore(m1[source], ptrs[target]);
2103 }
2104 }
2105
2106 16 return nullptr;
2107 };
2108
2109 336 static auto transpose = [](auto out, auto in) {
2110 336 *out = in->transpose();
2111 336 };
2112
2113 using TransposeM3D = void(openvdb::math::Mat3<double>*, openvdb::math::Mat3<double>*);
2114 using TransposeM3F = void(openvdb::math::Mat3<float>*, openvdb::math::Mat3<float>*);
2115 using TransposeM4D = void(openvdb::math::Mat4<double>*, openvdb::math::Mat4<double>*);
2116 using TransposeM4F = void(openvdb::math::Mat4<float>*, openvdb::math::Mat4<float>*);
2117
2118 13 return FunctionBuilder("transpose")
2119 26 .addSignature<TransposeM3D, true>(generate, (TransposeM3D*)(transpose))
2120
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<TransposeM3F, true>(generate, (TransposeM3F*)(transpose))
2121
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<TransposeM4D, true>(generate, (TransposeM4D*)(transpose))
2122
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<TransposeM4F, true>(generate, (TransposeM4F*)(transpose))
2123
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"mat"})
2124
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::NoAlias) // alloced by the function, always no alias
2125
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::WriteOnly)
2126
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(1, llvm::Attribute::ReadOnly)
2127
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
2128 13 .addFunctionAttribute(llvm::Attribute::InlineHint)
2129
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
2130
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
2131 .setDocumentation("Returns the transpose of a matrix")
2132
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
2133 }
2134
2135 33 inline FunctionGroup::UniquePtr axadjoint(const FunctionOptions& op)
2136 {
2137 static auto generate =
2138
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 [](const std::vector<llvm::Value*>& args,
2139 llvm::IRBuilder<>& B) -> llvm::Value*
2140 {
2141
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 assert(args.size() == 2);
2142 std::vector<llvm::Value*> m1, m2;
2143
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 arrayUnpack(args[1], m1, B, /*load*/true);
2144
1/2
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
16 arrayUnpack(args[0], m2, B, /*load*/false); // args[0] is return type
2145
2/4
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
16 assert(m1.size() == 9 && m2.size() == 9);
2146
2147 144 auto mul_sub = [&](const size_t a, const size_t b, const size_t c, const size_t d) {
2148
3/6
✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 144 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 144 times.
✗ Branch 8 not taken.
144 return binaryOperator(
2149
1/2
✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
144 binaryOperator(m1[a], m1[b], ast::tokens::MULTIPLY, B),
2150 288 binaryOperator(m1[c], m1[d], ast::tokens::MULTIPLY, B),
2151
1/2
✓ Branch 1 taken 144 times.
✗ Branch 2 not taken.
288 ast::tokens::MINUS, B);
2152 16 };
2153
2154
2/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
16 B.CreateStore(mul_sub(4,8, 5,7), m2[0]);
2155
2/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
16 B.CreateStore(mul_sub(2,7, 1,8), m2[1]);
2156
2/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
16 B.CreateStore(mul_sub(1,5, 2,4), m2[2]);
2157
2/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
16 B.CreateStore(mul_sub(5,6, 3,8), m2[3]);
2158
2/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
16 B.CreateStore(mul_sub(0,8, 2,6), m2[4]);
2159
2/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
16 B.CreateStore(mul_sub(2,3, 0,5), m2[5]);
2160
2/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
16 B.CreateStore(mul_sub(3,7, 4,6), m2[6]);
2161
2/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
16 B.CreateStore(mul_sub(1,6, 0,7), m2[7]);
2162
2/4
✓ Branch 1 taken 16 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
16 B.CreateStore(mul_sub(0,4, 1,3), m2[8]);
2163 16 return nullptr;
2164 };
2165
2166 static auto adjoint = [](auto out, const auto in) {
2167 *out = in->adjoint();
2168 };
2169
2170 using AdjointM3D =
2171 void(openvdb::math::Mat3<double>*,
2172 openvdb::math::Mat3<double>*);
2173 using AjointM3F =
2174 void(openvdb::math::Mat3<float>*,
2175 openvdb::math::Mat3<float>*);
2176
2177 33 return FunctionBuilder("adjoint")
2178 66 .addSignature<AdjointM3D, true>(generate, (AdjointM3D*)(adjoint))
2179
1/4
✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
66 .addSignature<AjointM3F, true>(generate, (AjointM3F*)(adjoint))
2180
3/8
✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 33 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 33 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
66 .setArgumentNames({"input"} )
2181
1/2
✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
33 .addParameterAttribute(0, llvm::Attribute::NoAlias)
2182
1/2
✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
33 .addParameterAttribute(1, llvm::Attribute::ReadOnly)
2183
1/2
✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
33 .addFunctionAttribute(llvm::Attribute::NoUnwind)
2184 33 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
2185
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 17 times.
33 .setConstantFold(op.mConstantFoldCBindings)
2186
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 17 times.
33 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
2187 .setDocumentation("Returns the adjoint of a 3x3 matrix. That is, "
2188 "the transpose of its cofactor matrix.")
2189
1/2
✓ Branch 1 taken 33 times.
✗ Branch 2 not taken.
66 .get();
2190 }
2191
2192 13 inline FunctionGroup::UniquePtr axcofactor(const FunctionOptions& op)
2193 {
2194 static auto generate =
2195
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 [](const std::vector<llvm::Value*>& args,
2196 llvm::IRBuilder<>& B) -> llvm::Value*
2197 {
2198
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 assert(args.size() == 2);
2199 std::vector<llvm::Value*> m1, m2;
2200
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 arrayUnpack(args[1], m1, B, /*load*/true);
2201
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 arrayUnpack(args[0], m2, B, /*load*/false); // args[0] is return type
2202
2/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
8 assert(m1.size() == 9 && m2.size() == 9);
2203
2204 72 auto mul_sub = [&](const size_t a, const size_t b, const size_t c, const size_t d) {
2205
3/6
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 72 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 72 times.
✗ Branch 8 not taken.
72 return binaryOperator(
2206
1/2
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
72 binaryOperator(m1[a], m1[b], ast::tokens::MULTIPLY, B),
2207 144 binaryOperator(m1[c], m1[d], ast::tokens::MULTIPLY, B),
2208
1/2
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
144 ast::tokens::MINUS, B);
2209 8 };
2210
2211
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
8 B.CreateStore(mul_sub(4,8, 5,7), m2[0]);
2212
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
8 B.CreateStore(mul_sub(5,6, 3,8), m2[1]);
2213
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
8 B.CreateStore(mul_sub(3,7, 4,6), m2[2]);
2214
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
8 B.CreateStore(mul_sub(2,7, 1,8), m2[3]);
2215
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
8 B.CreateStore(mul_sub(0,8, 2,6), m2[4]);
2216
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
8 B.CreateStore(mul_sub(1,6, 0,7), m2[5]);
2217
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
8 B.CreateStore(mul_sub(1,5, 2,4), m2[6]);
2218
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
8 B.CreateStore(mul_sub(2,3, 0,5), m2[7]);
2219
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
8 B.CreateStore(mul_sub(0,4, 1,3), m2[8]);
2220 8 return nullptr;
2221 };
2222
2223 static auto cofactor = [](auto out, const auto in) {
2224 *out = in->cofactor();
2225 };
2226
2227 using CofactorM3D =
2228 void(openvdb::math::Mat3<double>*,
2229 openvdb::math::Mat3<double>*);
2230 using CofactorM3F =
2231 void(openvdb::math::Mat3<float>*,
2232 openvdb::math::Mat3<float>*);
2233
2234 13 return FunctionBuilder("cofactor")
2235 26 .addSignature<CofactorM3D, true>(generate, (CofactorM3D*)(cofactor))
2236
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<CofactorM3F, true>(generate, (CofactorM3F*)(cofactor))
2237
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"input"} )
2238
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::NoAlias)
2239
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(1, llvm::Attribute::ReadOnly)
2240
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
2241 13 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
2242
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
2243
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
2244 .setDocumentation("Returns the cofactor matrix of a 3x3 matrix. That is, "
2245 "the matrix of its cofactors.")
2246
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
2247 }
2248
2249 13 inline FunctionGroup::UniquePtr axinverse(const FunctionOptions& op)
2250 {
2251 auto generate =
2252
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 [op](const std::vector<llvm::Value*>& args,
2253 llvm::IRBuilder<>& B) -> llvm::Value*
2254 {
2255
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 assert(args.size() == 2);
2256
2257
3/6
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 8 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 8 times.
✗ Branch 10 not taken.
16 llvm::Value* adj = axadjoint(op)->execute({args[1]}, B);
2258 std::vector<llvm::Value*> m1, madj;
2259
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 arrayUnpack(adj, madj, B, /*load*/true);
2260
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 arrayUnpack(args[0], m1, B, /*load*/false); // result
2261
2/4
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
8 assert(madj.size() == 9 && m1.size() == 9);
2262
2263 // compute determinant of the input mat by reusing the adjoint's 0, 3 and 6 terms
2264
2/4
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
8 llvm::Value* m20 = B.CreateLoad(B.CreateConstGEP2_64(args[1], 0, 0));
2265
2/4
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
8 llvm::Value* m23 = B.CreateLoad(B.CreateConstGEP2_64(args[1], 0, 3));
2266
2/4
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 8 times.
✗ Branch 7 not taken.
8 llvm::Value* m26 = B.CreateLoad(B.CreateConstGEP2_64(args[1], 0, 6));
2267
2268 // compute det and store in c0
2269
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 llvm::Value* c0 = binaryOperator(madj[0], m20, ast::tokens::MULTIPLY, B);
2270
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 llvm::Value* c1 = binaryOperator(madj[1], m23, ast::tokens::MULTIPLY, B);
2271
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 llvm::Value* c2 = binaryOperator(madj[2], m26, ast::tokens::MULTIPLY, B);
2272
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 c0 = binaryOperator(c0, c1, ast::tokens::PLUS, B);
2273
2/4
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
8 c0 = binaryOperator(c0, c2, ast::tokens::PLUS, B);
2274
2275
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 llvm::Value* zero = llvm::ConstantFP::get(c0->getType(), 0.0);
2276
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 llvm::Value* detisnotzero = binaryOperator(c0, zero, ast::tokens::NOTEQUALS, B);
2277
2278 llvm::Function* base = B.GetInsertBlock()->getParent();
2279
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 llvm::BasicBlock* then = llvm::BasicBlock::Create(B.getContext(), "then", base);
2280
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 llvm::BasicBlock* post = llvm::BasicBlock::Create(B.getContext(), "post", base);
2281
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 B.CreateCondBr(detisnotzero, then, post);
2282
2283 B.SetInsertPoint(then);
2284
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 llvm::Value* one = llvm::ConstantFP::get(c0->getType(), 1.0);
2285
1/2
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
8 c0 = B.CreateFDiv(one, c0);
2286
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 8 times.
80 for (size_t i = 0; i < 9; ++i) {
2287
2/6
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 72 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
72 B.CreateStore(binaryOperator(madj[i], c0, ast::tokens::MULTIPLY, B), m1[i]);
2288 }
2289
2290
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 B.CreateRetVoid();
2291
2292 B.SetInsertPoint(post);
2293
2294 madj.clear();
2295
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 arrayUnpack(args[1], madj, B, /*load*/true);
2296
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 8 times.
80 for (size_t i = 0; i < 9; ++i) {
2297
1/2
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
72 B.CreateStore(madj[i], m1[i]);
2298 }
2299
2300 8 return nullptr;
2301 13 };
2302
2303 336 static auto inverse = [](auto out, const auto in) {
2304 try {
2305
2/2
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 84 times.
336 *out = in->inverse();
2306 }
2307 168 catch (const openvdb::ArithmeticError&) {
2308 168 *out = *in;
2309 }
2310 336 };
2311
2312 using InverseM3D =
2313 void(openvdb::math::Mat3<double>*,
2314 openvdb::math::Mat3<double>*);
2315 using InverseM3F =
2316 void(openvdb::math::Mat3<float>*,
2317 openvdb::math::Mat3<float>*);
2318
2319 13 return FunctionBuilder("inverse")
2320 26 .addSignature<InverseM3D, true>(generate, (InverseM3D*)(inverse))
2321
1/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
26 .addSignature<InverseM3F, true>(generate, (InverseM3F*)(inverse))
2322
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"input"} )
2323
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addDependency("adjoint")
2324
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::NoAlias)
2325
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(1, llvm::Attribute::ReadOnly)
2326
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
2327 13 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
2328
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
2329
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
2330 .setDocumentation("Return the inverse of a 3x3 matrix."
2331 "If the matrix is singular, returns the input matrix.")
2332
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
2333 }
2334
2335 ///////////////////////////////////////////////////////////////////////////
2336 ///////////////////////////////////////////////////////////////////////////
2337
2338 // Noise
2339
2340 13 inline FunctionGroup::UniquePtr axsimplexnoise(const FunctionOptions& op)
2341 {
2342 static auto simplexnoisex = [](double x) -> double {
2343 return SimplexNoise::noise(x, 0.0, 0.0);
2344 };
2345 static auto simplexnoisexy = [](double x, double y) -> double {
2346 return SimplexNoise::noise(x, y, 0.0);
2347 };
2348 static auto simplexnoisexyz = [](double x, double y, double z) -> double {
2349 return SimplexNoise::noise(x, y, z);
2350 };
2351 static auto simplexnoisev = [](const openvdb::math::Vec3<double>* v) -> double {
2352 return SimplexNoise::noise((*v)[0], (*v)[1], (*v)[2]);
2353 };
2354
2355 13 return FunctionBuilder("simplexnoise")
2356
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<double(double)>(simplexnoisex)
2357
2/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
26 .setArgumentNames({"x"})
2358 .setConstantFold(false)
2359
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<double(double, double)>(simplexnoisexy)
2360
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"x", "y"})
2361 .setConstantFold(false)
2362
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<double(double,double,double)>(simplexnoisexyz)
2363
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"x", "y", "z"})
2364 .setConstantFold(false)
2365
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<double(const openvdb::math::Vec3<double>*)>(simplexnoisev)
2366
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"pos"})
2367
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .addParameterAttribute(0, llvm::Attribute::ReadOnly)
2368 .setConstantFold(false)
2369
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
2370 .setDocumentation("Compute simplex noise at coordinates x, y and z. Coordinates which are "
2371 "not provided will be set to 0.")
2372
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
2373 }
2374
2375 13 inline FunctionGroup::UniquePtr axcurlsimplexnoise(const FunctionOptions& op)
2376 {
2377 using CurlSimplexNoiseV3D = void(double(*)[3], const double(*)[3]);
2378 using CurlSimplexNoiseD = void(double(*)[3], double, double, double);
2379
2380 13 return FunctionBuilder("curlsimplexnoise")
2381 .addSignature<CurlSimplexNoiseV3D, true>(
2382
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 (CurlSimplexNoiseV3D*)(openvdb::ax::math::curlnoise<SimplexNoise>))
2383
2/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
26 .setArgumentNames({"pos"})
2384
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::NoAlias) // alloced by the function, always no alias
2385
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::WriteOnly)
2386
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(1, llvm::Attribute::ReadOnly)
2387
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
2388 13 .addFunctionAttribute(llvm::Attribute::InlineHint)
2389
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .setConstantFold(op.mConstantFoldCBindings)
2390 .addSignature<CurlSimplexNoiseD, true>(
2391
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 (CurlSimplexNoiseD*)(openvdb::ax::math::curlnoise<SimplexNoise>))
2392
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"pos"})
2393
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::NoAlias) // alloced by the function, always no alias
2394
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::WriteOnly)
2395
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
2396 13 .addFunctionAttribute(llvm::Attribute::InlineHint)
2397
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
2398
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
2399 .setDocumentation("Generates divergence-free 3D noise, computed using a "
2400 "curl function on Simplex Noise.")
2401
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
2402 }
2403
2404
2405 ///////////////////////////////////////////////////////////////////////////
2406 ///////////////////////////////////////////////////////////////////////////
2407
2408 // Trig/Hyperbolic
2409
2410 /// @todo Depending on the platform, some of these methods may be available though
2411 /// LLVM as "intrinsics". To avoid conflicts, we currently only expose the C
2412 /// bindings. We should perhaps override the C Bindings if the method exists
2413 /// in LLVM, so long as it's clear that these methods may produce different
2414 /// results from stdlib.
2415 /// @note See the following LLVM files for some details:
2416 /// Analysis/TargetLibraryInfo.def
2417 /// Analysis/ConstantFolding.cpp
2418 /// Analysis/TargetLibraryInfo.cpp
2419 ///
2420
10/18
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 13 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 13 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 13 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 13 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 13 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 13 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 8 times.
✓ Branch 23 taken 5 times.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
47 DEFINE_AX_C_FP_BINDING(acos, "Computes the principal value of the arc cosine of the input.")
2421
9/18
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 1 times.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
3 DEFINE_AX_C_FP_BINDING(acosh, "Computes the inverse hyperbolic cosine of the input.")
2422
10/18
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 13 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 13 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 13 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 13 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 13 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 13 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 8 times.
✓ Branch 23 taken 5 times.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
47 DEFINE_AX_C_FP_BINDING(asin, "Computes the principal value of the arc sine of the input.")
2423
9/18
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 1 times.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
3 DEFINE_AX_C_FP_BINDING(asinh, "Computes the inverse hyperbolic sine of the input.")
2424
10/18
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 13 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 13 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 13 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 13 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 13 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 13 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 8 times.
✓ Branch 23 taken 5 times.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
47 DEFINE_AX_C_FP_BINDING(atan, "Computes the principal value of the arc tangent of the input.")
2425
9/18
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 1 times.
✓ Branch 25 taken 1 times.
✗ Branch 26 not taken.
3 DEFINE_AX_C_FP_BINDING(atanh, "Computes the inverse hyperbolic tangent of the input.")
2426
10/18
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 13 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 13 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 13 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 13 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 13 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 13 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 8 times.
✓ Branch 23 taken 5 times.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
47 DEFINE_AX_C_FP_BINDING(cosh, "Computes the hyperbolic cosine of the input.")
2427
10/18
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 13 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 13 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 13 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 13 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 13 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 13 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 8 times.
✓ Branch 23 taken 5 times.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
47 DEFINE_AX_C_FP_BINDING(sinh, "Computes the hyperbolic sine of the input.")
2428
10/18
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 13 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 13 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 13 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 13 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 13 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 13 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 8 times.
✓ Branch 23 taken 5 times.
✓ Branch 25 taken 13 times.
✗ Branch 26 not taken.
47 DEFINE_AX_C_FP_BINDING(tanh, "Computes the hyperbolic tangent of the input.")
2429
2430 13 inline FunctionGroup::UniquePtr axdegrees(const FunctionOptions& op)
2431 {
2432 static auto generate =
2433
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 [](const std::vector<llvm::Value*>& args,
2434 llvm::IRBuilder<>& B) -> llvm::Value*
2435 {
2436
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 assert(args.size() == 1);
2437
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 llvm::Value* arg = args.front();
2438 llvm::Value* pi180 = arg->getType()->isFloatTy() ?
2439 12 LLVMType<float>::get(B.getContext(), 180.f / openvdb::math::pi<float>()) :
2440
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 LLVMType<double>::get(B.getContext(), 180.0 / openvdb::math::pi<double>());
2441 24 return binaryOperator(arg, pi180, ast::tokens::MULTIPLY, B);
2442 };
2443
2444 13 return FunctionBuilder("degrees")
2445
1/2
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
26 .addSignature<double(double)>(generate)
2446
2/6
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
26 .addSignature<float(float)>(generate)
2447
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"radians"})
2448 .setConstantFold(true)
2449
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoRecurse)
2450
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
2451 13 .addFunctionAttribute(llvm::Attribute::InlineHint)
2452
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
2453 .setDocumentation("Converts the number of radians to degrees.")
2454
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
2455 }
2456
2457 13 inline FunctionGroup::UniquePtr axradians(const FunctionOptions& op)
2458 {
2459 static auto generate =
2460
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 [](const std::vector<llvm::Value*>& args,
2461 llvm::IRBuilder<>& B) -> llvm::Value*
2462 {
2463
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
24 assert(args.size() == 1);
2464
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 llvm::Value* arg = args.front();
2465 llvm::Value* pi180 = arg->getType()->isFloatTy() ?
2466 12 LLVMType<float>::get(B.getContext(), openvdb::math::pi<float>() / 180.f) :
2467
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 LLVMType<double>::get(B.getContext(), openvdb::math::pi<double>() / 180.0);
2468 24 return binaryOperator(arg, pi180, ast::tokens::MULTIPLY, B);
2469 };
2470
2471 13 return FunctionBuilder("radians")
2472
1/2
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
26 .addSignature<double(double)>(generate)
2473
2/6
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
26 .addSignature<float(float)>(generate)
2474
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"degrees"})
2475 .setConstantFold(true)
2476
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoRecurse)
2477
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
2478 13 .addFunctionAttribute(llvm::Attribute::InlineHint)
2479
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
2480 .setDocumentation("Converts the number of degrees to radians.")
2481
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
2482 }
2483
2484 13 inline FunctionGroup::UniquePtr axtan(const FunctionOptions& op)
2485 {
2486 // @todo consider using this IR implementation over std::tan, however
2487 // we then lose constant folding (as results don't match). Ideally
2488 // this ir implementation should exist at compile time as a valid
2489 // function for constant folding
2490 //
2491 // static auto generate =
2492 // [](const std::vector<llvm::Value*>& args,
2493 // const std::unordered_map<std::string, llvm::Value*>&,
2494 // llvm::IRBuilder<>& B) -> llvm::Value*
2495 // {
2496 // llvm::Module* M = B.GetInsertBlock()->getParent()->getParent();
2497 // llvm::Type* type = args[0]->getType();
2498 // llvm::Function* sinFunction =
2499 // llvm::Intrinsic::getDeclaration(M, llvm::Intrinsic::sin, type);
2500 // llvm::Function* cosFunction =
2501 // llvm::Intrinsic::getDeclaration(M, llvm::Intrinsic::cos, type);
2502
2503 // llvm::Value* sin = B.CreateCall(sinFunction, args[0]);
2504 // llvm::Value* cos = B.CreateCall(cosFunction, args[0]);
2505 // return binaryOperator(sin, cos, ast::tokens::DIVIDE, B);
2506 // };
2507
2508 13 return FunctionBuilder("tan")
2509
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<double(double)>((double(*)(double))(std::tan))
2510
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<float(float)>((float(*)(float))(std::tan))
2511
2/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
26 .setArgumentNames({"n"})
2512
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::ReadOnly)
2513
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoRecurse)
2514
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
2515 13 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
2516
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
2517
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
2518 .setDocumentation("Computes the tangent of arg (measured in radians).")
2519
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
2520 }
2521
2522 13 inline FunctionGroup::UniquePtr axatan2(const FunctionOptions& op)
2523 {
2524 13 return FunctionBuilder("atan2")
2525
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<double(double,double)>((double(*)(double,double))(std::atan2))
2526
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<float(float,float)>((float(*)(float,float))(std::atan2))
2527
2/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
26 .setArgumentNames({"y", "x"})
2528
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::ReadOnly)
2529
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoRecurse)
2530
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
2531 13 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
2532
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
2533
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
2534 .setDocumentation("Computes the arc tangent of y/x using the signs of arguments "
2535 "to determine the correct quadrant.")
2536
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
2537 }
2538
2539 ///////////////////////////////////////////////////////////////////////////
2540 ///////////////////////////////////////////////////////////////////////////
2541
2542 // String
2543
2544 13 inline FunctionGroup::UniquePtr axatoi(const FunctionOptions& op)
2545 {
2546 // WARNING: decltype removes the throw identifer from atoi. We should
2547 // use this are automatically update the function attributes as appropriate
2548 13 return FunctionBuilder("atoi")
2549
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<decltype(std::atoi)>(std::atoi)
2550
2/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
26 .setArgumentNames({"str"})
2551
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::ReadOnly)
2552
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::ReadOnly)
2553
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoRecurse)
2554
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
2555 13 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
2556
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
2557
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
2558 .setDocumentation("Parses the string input interpreting its "
2559 "content as an integral number, which is returned as a value of type int.")
2560
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
2561 }
2562
2563 13 inline FunctionGroup::UniquePtr axatof(const FunctionOptions& op)
2564 {
2565 // WARNING: decltype removes the throw identifer from atof. We should
2566 // use this are automatically update the function attributes as appropriate
2567 13 return FunctionBuilder("atof")
2568
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<decltype(std::atof)>(std::atof)
2569
2/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
26 .setArgumentNames({"str"})
2570
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::ReadOnly)
2571
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::ReadOnly)
2572
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoRecurse)
2573
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
2574 13 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
2575
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
2576
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
2577 .setDocumentation("Parses the string input, interpreting its "
2578 "content as a floating point number and returns its value as a double.")
2579
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
2580 }
2581
2582 13 inline FunctionGroup::UniquePtr axhash(const FunctionOptions& op)
2583 {
2584 252 static auto hash = [](const codegen::String* str) -> int64_t {
2585 252 return static_cast<int64_t>(std::hash<std::string>{}(str->str()));
2586 };
2587
2588 13 return FunctionBuilder("hash")
2589
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<int64_t(const codegen::String*)>((int64_t(*)(const codegen::String*))(hash))
2590
2/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
26 .setArgumentNames({"str"})
2591
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::ReadOnly)
2592
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::ReadOnly)
2593
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoRecurse)
2594
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
2595 13 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
2596
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
2597
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
2598 .setDocumentation("Return a hash of the provided string.")
2599
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
2600 }
2601
2602 ///////////////////////////////////////////////////////////////////////////
2603 ///////////////////////////////////////////////////////////////////////////
2604
2605 // Utility
2606
2607 3 inline FunctionGroup::UniquePtr axprint(const FunctionOptions& op)
2608 {
2609 static auto print = [](auto v) { std::cout << v << std::endl; };
2610 static auto printv = [](auto* v) { std::cout << *v << std::endl; };
2611 static auto printstr = [](const codegen::String* axstr) {
2612 std::cout << axstr->c_str() << std::endl;
2613 };
2614
2615 3 return FunctionBuilder("print")
2616
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .addSignature<void(double)>((void(*)(double))(print))
2617
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .addSignature<void(float)>((void(*)(float))(print))
2618
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .addSignature<void(int64_t)>((void(*)(int64_t))(print))
2619
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .addSignature<void(int32_t)>((void(*)(int32_t))(print))
2620
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
6 .setArgumentNames({"n"})
2621
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .addFunctionAttribute(llvm::Attribute::ReadOnly)
2622
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .addFunctionAttribute(llvm::Attribute::NoRecurse)
2623
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
2624 .setConstantFold(false /*never cf*/)
2625
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .addSignature<void(const codegen::String*)>((void(*)(const codegen::String*))(printstr))
2626
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .addSignature<void(openvdb::math::Vec2<int32_t>*)>((void(*)(openvdb::math::Vec2<int32_t>*))(printv))
2627
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .addSignature<void(openvdb::math::Vec2<float>*)>((void(*)(openvdb::math::Vec2<float>*))(printv))
2628
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .addSignature<void(openvdb::math::Vec2<double>*)>((void(*)(openvdb::math::Vec2<double>*))(printv))
2629
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .addSignature<void(openvdb::math::Vec3<int32_t>*)>((void(*)(openvdb::math::Vec3<int32_t>*))(printv))
2630
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .addSignature<void(openvdb::math::Vec3<float>*)>((void(*)(openvdb::math::Vec3<float>*))(printv))
2631
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .addSignature<void(openvdb::math::Vec3<double>*)>((void(*)(openvdb::math::Vec3<double>*))(printv))
2632
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .addSignature<void(openvdb::math::Vec4<int32_t>*)>((void(*)(openvdb::math::Vec4<int32_t>*))(printv))
2633
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .addSignature<void(openvdb::math::Vec4<float>*)>((void(*)(openvdb::math::Vec4<float>*))(printv))
2634
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .addSignature<void(openvdb::math::Vec4<double>*)>((void(*)(openvdb::math::Vec4<double>*))(printv))
2635
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .addSignature<void(openvdb::math::Mat3<float>*)>((void(*)(openvdb::math::Mat3<float>*))(printv))
2636
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .addSignature<void(openvdb::math::Mat3<double>*)>((void(*)(openvdb::math::Mat3<double>*))(printv))
2637
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .addSignature<void(openvdb::math::Mat4<float>*)>((void(*)(openvdb::math::Mat4<float>*))(printv))
2638
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .addSignature<void(openvdb::math::Mat4<double>*)>((void(*)(openvdb::math::Mat4<double>*))(printv))
2639 3 .addParameterAttribute(0, llvm::Attribute::ReadOnly)
2640
3/8
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
6 .setArgumentNames({"n"})
2641
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .addFunctionAttribute(llvm::Attribute::ReadOnly)
2642
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 .addFunctionAttribute(llvm::Attribute::NoRecurse)
2643
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
2644 .setConstantFold(false /*never cf*/)
2645
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
2646 .setDocumentation("Prints the input to the standard output stream. "
2647 "Warning: This will be run for every element.")
2648
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
6 .get();
2649 }
2650
2651 13 inline FunctionGroup::UniquePtr axargsort(const FunctionOptions& op)
2652 {
2653 1044 static auto argsort = [](auto out, const auto in){
2654 using VecType = typename std::remove_pointer<decltype(in)>::type;
2655 // initialize original index locations
2656 1044 std::iota(out->asPointer(), out->asPointer() + VecType::size, 0);
2657 // sort indexes based on comparing values in v
2658 // using std::stable_sort instead of std::sort
2659 // to avoid unnecessary index re-orderings
2660 // when v contains elements of equal values
2661 1044 std::stable_sort(out->asPointer(), out->asPointer() + VecType::size,
2662 2349 [&in](int32_t i1, int32_t i2) {return (*in)[i1] < (*in)[i2];});
2663 1044 };
2664
2665 using Argsort3D = void(openvdb::math::Vec3<int>*, openvdb::math::Vec3<double>*);
2666 using Argsort3F = void(openvdb::math::Vec3<int>*, openvdb::math::Vec3<float>*);
2667 using Argsort3I = void(openvdb::math::Vec3<int>*, openvdb::math::Vec3<int32_t>*);
2668 using Argsort4D = void(openvdb::math::Vec4<int>*, openvdb::math::Vec4<double>*);
2669 using Argsort4F = void(openvdb::math::Vec4<int>*, openvdb::math::Vec4<float>*);
2670 using Argsort4I = void(openvdb::math::Vec4<int>*, openvdb::math::Vec4<int32_t>*);
2671
2672 13 return FunctionBuilder("argsort")
2673
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<Argsort3D, true>((Argsort3D*)(argsort))
2674
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<Argsort3F, true>((Argsort3F*)(argsort))
2675
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<Argsort3I, true>((Argsort3I*)(argsort))
2676
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<Argsort4D, true>((Argsort4D*)(argsort))
2677
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<Argsort4F, true>((Argsort4F*)(argsort))
2678
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<Argsort4I, true>((Argsort4I*)(argsort))
2679
2/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
26 .setArgumentNames({"v"})
2680
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::NoAlias)
2681
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(1, llvm::Attribute::ReadOnly)
2682
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
2683 13 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
2684
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
2685
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
2686 .setDocumentation("Returns a vector of the indexes that would sort the input vector.")
2687
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
2688 }
2689
2690 13 inline FunctionGroup::UniquePtr axsort(const FunctionOptions& op)
2691 {
2692
1/2
✓ Branch 0 taken 87 times.
✗ Branch 1 not taken.
87 static auto sort3 = [](auto out, const auto in) {
2693 87 *out = in->sorted();
2694 87 };
2695
2696 static auto sort = [](auto out, const auto in) {
2697 using VecType = typename std::remove_pointer<decltype(out)>::type;
2698 *out = *in;
2699 std::sort(out->asPointer(), out->asPointer() + VecType::size);
2700 };
2701
2702 using Sort3D = void(openvdb::math::Vec3<double>*,openvdb::math::Vec3<double>*);
2703 using Sort3F = void(openvdb::math::Vec3<float>*,openvdb::math::Vec3<float>*);
2704 using Sort3I = void(openvdb::math::Vec3<int32_t>*, openvdb::math::Vec3<int32_t>*);
2705 using Sort4D = void(openvdb::math::Vec4<double>*,openvdb::math::Vec4<double>*);
2706 using Sort4F = void(openvdb::math::Vec4<float>*,openvdb::math::Vec4<float>*);
2707 using Sort4I = void(openvdb::math::Vec4<int32_t>*, openvdb::math::Vec4<int32_t>*);
2708
2709 13 return FunctionBuilder("sort")
2710
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<Sort3D, true>((Sort3D*)(sort3))
2711
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<Sort3F, true>((Sort3F*)(sort3))
2712
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<Sort3I, true>((Sort3I*)(sort3))
2713
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<Sort4D, true>((Sort4D*)(sort))
2714
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<Sort4F, true>((Sort4F*)(sort))
2715
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addSignature<Sort4I, true>((Sort4I*)(sort))
2716
2/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
26 .setArgumentNames({"v"})
2717
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::NoAlias)
2718
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(1, llvm::Attribute::ReadOnly)
2719
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
2720 13 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
2721
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
2722
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
2723 .setDocumentation("Returns the sorted result of the given vector.")
2724
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
2725 }
2726
2727 ///////////////////////////////////////////////////////////////////////////
2728 ///////////////////////////////////////////////////////////////////////////
2729
2730 // Colour
2731
2732 13 inline FunctionGroup::UniquePtr axhsvtorgb(const FunctionOptions& op)
2733 {
2734 auto generate =
2735
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 [op](const std::vector<llvm::Value*>& args,
2736 llvm::IRBuilder<>& B) -> llvm::Value*
2737 {
2738
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 assert(args.size() == 2);
2739 llvm::Function* base = B.GetInsertBlock()->getParent();
2740
2741 std::vector<llvm::Value*> hsv, rgb;
2742
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 arrayUnpack(args[0], rgb, B, /*load*/false); //output
2743
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 arrayUnpack(args[1], hsv, B, /*load*/true); //input
2744
2745
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 llvm::Type* precision = hsv[0]->getType();
2746
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 llvm::Value* zero = llvm::ConstantFP::get(precision, 0.0);
2747
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 llvm::Value* one = llvm::ConstantFP::get(precision, 1.0);
2748
2749 // wrap hue values to [0,1] domain, including negative values
2750 // i.e. -0.1 -> 0.9, 4.5 -> 0.5
2751
4/8
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 12 times.
✗ Branch 10 not taken.
24 hsv[0] = axfloormod(op)->execute({hsv[0], one}, B);
2752
2753 // clamp saturation values to [0,1]
2754
4/8
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 12 times.
✗ Branch 10 not taken.
24 hsv[1] = axclamp(op)->execute({hsv[1], zero, one}, B);
2755
2756
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 llvm::BasicBlock* then = llvm::BasicBlock::Create(B.getContext(), "then", base);
2757
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 llvm::BasicBlock* el = llvm::BasicBlock::Create(B.getContext(), "else", base);
2758
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 llvm::BasicBlock* post = llvm::BasicBlock::Create(B.getContext(), "post", base);
2759
2760
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 llvm::Value* hueisone = binaryOperator(hsv[0], one, ast::tokens::EQUALSEQUALS, B);
2761
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateCondBr(hueisone, then, el);
2762
2763
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 llvm::Value* h = insertStaticAlloca(B, precision);
2764
2765 B.SetInsertPoint(then);
2766 {
2767
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 llvm::Value* r = binaryOperator(hsv[0], zero, ast::tokens::MULTIPLY, B); // zero hue
2768
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(r, h);
2769
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateBr(post);
2770 }
2771 B.SetInsertPoint(el);
2772 {
2773
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 llvm::Value* six = llvm::ConstantFP::get(hsv[0]->getType(), 6.0);
2774
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 llvm::Value* r = binaryOperator(hsv[0], six, ast::tokens::MULTIPLY, B);
2775
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(r, h);
2776
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateBr(post);
2777 }
2778
2779 B.SetInsertPoint(post);
2780
2781
2/4
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
12 h = B.CreateLoad(h);
2782 12 llvm::Value* sat = hsv[1];
2783 12 llvm::Value* val = hsv[2];
2784
2785
3/6
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
24 llvm::Value* i = llvm_floor(op)->execute({h}, B);
2786 llvm::Value* f =
2787
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 binaryOperator(h, i, ast::tokens::MINUS, B);
2788 llvm::Value* p =
2789
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 binaryOperator(val,
2790 24 binaryOperator(one, sat, ast::tokens::MINUS, B),
2791
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 ast::tokens::MULTIPLY, B);
2792 llvm::Value* q =
2793
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
12 binaryOperator(val,
2794 binaryOperator(one,
2795 binaryOperator(sat, f,
2796 24 ast::tokens::MULTIPLY, B),
2797 ast::tokens::MINUS, B),
2798
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 ast::tokens::MULTIPLY, B);
2799 llvm::Value* t =
2800
3/6
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
12 binaryOperator(val,
2801 binaryOperator(one,
2802 binaryOperator(sat,
2803 binaryOperator(one, f,
2804 24 ast::tokens::MINUS, B),
2805 ast::tokens::MULTIPLY, B),
2806 24 ast::tokens::MINUS, B),
2807
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 ast::tokens::MULTIPLY, B);
2808
2809 // start main switch
2810
2811
2/4
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 12 times.
✗ Branch 6 not taken.
12 post = llvm::BasicBlock::Create(B.getContext(), "post", base);
2812
2813
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 i = arithmeticConversion(i, LLVMType<int64_t>::get(B.getContext()), B);
2814
2815
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 12 times.
84 for (int64_t j = 0; j <= 5; ++j)
2816 {
2817
1/2
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
72 llvm::BasicBlock* then = llvm::BasicBlock::Create(B.getContext(), "then", base);
2818
2/4
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 72 times.
✗ Branch 6 not taken.
72 llvm::BasicBlock* el = llvm::BasicBlock::Create(B.getContext(), "else", base);
2819
2820
1/2
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
72 llvm::Value* constant = LLVMType<int64_t>::get(B.getContext(), j);
2821
1/4
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
72 llvm::Value* switchv = binaryOperator(i, constant, ast::tokens::EQUALSEQUALS, B);
2822
1/2
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
72 B.CreateCondBr(switchv, then, el);
2823
2824 B.SetInsertPoint(then);
2825 {
2826 // The final logic for storing the RGB values
2827
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 60 times.
72 if (j == 0) {
2828
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(val, rgb[0]);
2829
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(t, rgb[1]);
2830
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(p, rgb[2]);
2831 }
2832
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 48 times.
60 else if (j == 1) {
2833
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(q, rgb[0]);
2834
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(val, rgb[1]);
2835
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(p, rgb[2]);
2836 }
2837
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 36 times.
48 else if (j == 2) {
2838
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(p, rgb[0]);
2839
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(val, rgb[1]);
2840
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(t, rgb[2]);
2841 }
2842
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 24 times.
36 else if (j == 3) {
2843
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(p, rgb[0]);
2844
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(q, rgb[1]);
2845
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(val, rgb[2]);
2846 }
2847
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 12 times.
24 else if (j == 4) {
2848
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(t, rgb[0]);
2849
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(p, rgb[1]);
2850
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(val, rgb[2]);
2851 }
2852
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 else if (j == 5) {
2853
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(val, rgb[0]);
2854
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(p, rgb[1]);
2855
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(q, rgb[2]);
2856 }
2857
2858
1/2
✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
72 B.CreateBr(post);
2859 }
2860 // set for next iteration
2861 B.SetInsertPoint(el);
2862 }
2863
2864 // Final case (hue > 1 || hue < 0), zero intialize
2865
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(zero, rgb[0]);
2866
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(zero, rgb[1]);
2867
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(zero, rgb[2]);
2868
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateBr(post);
2869
2870 B.SetInsertPoint(post);
2871
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
24 return B.CreateRetVoid();
2872 13 };
2873
2874 using HSVtoRGB3D = void(openvdb::math::Vec3<double>*,openvdb::math::Vec3<double>*);
2875 using HSVtoRGB3F = void(openvdb::math::Vec3<float>*,openvdb::math::Vec3<float>*);
2876
2877 13 return FunctionBuilder("hsvtorgb")
2878
1/2
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
26 .addSignature<HSVtoRGB3D, true>(generate)
2879
2/6
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
26 .addSignature<HSVtoRGB3F, true>(generate)
2880
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"input"} )
2881
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addDependency("floor")
2882
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addDependency("floormod")
2883
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addDependency("clamp")
2884
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::NoAlias)
2885
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(1, llvm::Attribute::ReadOnly)
2886
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
2887 13 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
2888
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
2889
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
2890 .setDocumentation("Convert HSV color space into RGB color space. Note "
2891 "that the input hue is wrapped to its periodic [0,1] values and "
2892 "the input saturation is clamped between [0,1].")
2893
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
2894 }
2895
2896 13 inline FunctionGroup::UniquePtr axrgbtohsv(const FunctionOptions& op)
2897 {
2898 auto generate =
2899
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 [op](const std::vector<llvm::Value*>& args,
2900 llvm::IRBuilder<>& B) -> llvm::Value*
2901 {
2902
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
12 assert(args.size() == 2);
2903 llvm::Function* base = B.GetInsertBlock()->getParent();
2904 llvm::LLVMContext& C = B.getContext();
2905
2906 std::vector<llvm::Value*> hsv, rgb;
2907
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 arrayUnpack(args[0], hsv, B, /*load*/false); //output
2908
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 arrayUnpack(args[1], rgb, B, /*load*/true); //input
2909
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 llvm::Type* precision = rgb[0]->getType();
2910
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 llvm::Value* zero = llvm::ConstantFP::get(precision, 0.0);
2911
2912
2913
3/6
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
24 llvm::Value* max = axmax(op)->execute({rgb[0], rgb[1]}, B);
2914
3/6
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
24 max = axmax(op)->execute({max, rgb[2]}, B);
2915
3/6
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
24 llvm::Value* min = axmin(op)->execute({rgb[0], rgb[1]}, B);
2916
3/6
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
24 min = axmin(op)->execute({min, rgb[2]}, B);
2917
2918
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
12 llvm::Value* range = binaryOperator(max, min, ast::tokens::MINUS, B);
2919
2920
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(zero, hsv[0]);
2921
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(zero, hsv[1]);
2922
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(max, hsv[2]);
2923
2924
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 llvm::BasicBlock* then = llvm::BasicBlock::Create(C, "then", base);
2925
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 llvm::BasicBlock* post = llvm::BasicBlock::Create(C, "post", base);
2926
2927
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 llvm::Value* maxneqzero = binaryOperator(max, zero, ast::tokens::NOTEQUALS, B);
2928
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateCondBr(maxneqzero, then, post);
2929
2930 B.SetInsertPoint(then);
2931 {
2932
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
12 llvm::Value* sat = binaryOperator(range, max, ast::tokens::DIVIDE, B);
2933
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(sat, hsv[1]);
2934
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateBr(post);
2935 }
2936
2937 B.SetInsertPoint(post);
2938
2939
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 llvm::Value* sat = B.CreateLoad(hsv[1]);
2940
2941
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 then = llvm::BasicBlock::Create(C, "then", base);
2942
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 post = llvm::BasicBlock::Create(C, "post", base);
2943
2944
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 llvm::Value* satneqzero = binaryOperator(sat, zero, ast::tokens::NOTEQUALS, B);
2945
2946
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateCondBr(satneqzero, then, post);
2947
2948 B.SetInsertPoint(then);
2949 {
2950
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 then = llvm::BasicBlock::Create(C, "then", base);
2951
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 llvm::BasicBlock* elif1 = llvm::BasicBlock::Create(C, "elif1", base);
2952
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 llvm::BasicBlock* el = llvm::BasicBlock::Create(C, "el", base);
2953
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 llvm::BasicBlock* end = llvm::BasicBlock::Create(C, "end", base);
2954
2955
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 llvm::Value* reqmax = binaryOperator(rgb[0], max, ast::tokens::EQUALSEQUALS, B);
2956
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateCondBr(reqmax, then, elif1);
2957
2958 B.SetInsertPoint(then);
2959 {
2960 llvm::Value* h =
2961
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
12 binaryOperator(
2962 24 binaryOperator(rgb[1], rgb[2], ast::tokens::MINUS, B),
2963 range,
2964
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
24 ast::tokens::DIVIDE, B);
2965
2966
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(h, hsv[0]);
2967
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateBr(end);
2968 }
2969
2970 B.SetInsertPoint(elif1);
2971 {
2972
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 then = llvm::BasicBlock::Create(C, "then", base);
2973
2974
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 llvm::Value* geqmax = binaryOperator(rgb[1], max, ast::tokens::EQUALSEQUALS, B);
2975
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateCondBr(geqmax, then, el);
2976
2977 B.SetInsertPoint(then);
2978 {
2979
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 llvm::Value* two = llvm::ConstantFP::get(precision, 2.0);
2980
2981 llvm::Value* h =
2982
3/6
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
12 binaryOperator(two,
2983 binaryOperator(
2984 24 binaryOperator(rgb[2], rgb[0], ast::tokens::MINUS, B),
2985 range,
2986 ast::tokens::DIVIDE, B),
2987
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
24 ast::tokens::PLUS, B);
2988
2989
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(h, hsv[0]);
2990
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateBr(end);
2991 }
2992 }
2993
2994 B.SetInsertPoint(el);
2995 {
2996
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 llvm::Value* four = llvm::ConstantFP::get(precision, 4.0);
2997
2998 llvm::Value* h =
2999
3/6
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 12 times.
✗ Branch 8 not taken.
12 binaryOperator(four,
3000 binaryOperator(
3001 24 binaryOperator(rgb[0], rgb[1], ast::tokens::MINUS, B),
3002 range,
3003 ast::tokens::DIVIDE, B),
3004
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
24 ast::tokens::PLUS, B);
3005
3006
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(h, hsv[0]);
3007
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateBr(end);
3008 }
3009
3010 B.SetInsertPoint(end);
3011
3012
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 llvm::Value* six = llvm::ConstantFP::get(precision, 6.0);
3013
3014
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 llvm::Value* h = B.CreateLoad(hsv[0]);
3015
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
12 h = binaryOperator(h, six, ast::tokens::DIVIDE, B);
3016
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(h, hsv[0]);
3017
3018
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 then = llvm::BasicBlock::Create(C, "then", base);
3019
3020
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 llvm::Value* hlesszero = binaryOperator(h, zero, ast::tokens::LESSTHAN, B);
3021
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateCondBr(hlesszero, then, post);
3022
3023 B.SetInsertPoint(then);
3024 {
3025
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 llvm::Value* one = llvm::ConstantFP::get(precision, 1.0);
3026
2/6
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 12 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
12 h = binaryOperator(h, one, ast::tokens::PLUS, B);
3027
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateStore(h, hsv[0]);
3028
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 B.CreateBr(post);
3029 }
3030 }
3031
3032 B.SetInsertPoint(post);
3033
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
24 return B.CreateRetVoid();
3034 13 };
3035
3036 using HSVtoRGB3D = void(openvdb::math::Vec3<double>*,openvdb::math::Vec3<double>*);
3037 using HSVtoRGB3F = void(openvdb::math::Vec3<float>*,openvdb::math::Vec3<float>*);
3038
3039 13 return FunctionBuilder("rgbtohsv")
3040
1/2
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
26 .addSignature<HSVtoRGB3D, true>(generate)
3041
2/6
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
26 .addSignature<HSVtoRGB3F, true>(generate)
3042
3/8
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
26 .setArgumentNames({"input"} )
3043
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addDependency("max")
3044
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addDependency("min")
3045
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(0, llvm::Attribute::NoAlias)
3046
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addParameterAttribute(1, llvm::Attribute::ReadOnly)
3047
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 .addFunctionAttribute(llvm::Attribute::NoUnwind)
3048 13 .addFunctionAttribute(llvm::Attribute::AlwaysInline)
3049
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setConstantFold(op.mConstantFoldCBindings)
3050
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5 times.
13 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
3051 .setDocumentation("Convert RGB color space into HSV color space.")
3052
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 .get();
3053 }
3054
3055 ///////////////////////////////////////////////////////////////////////////
3056 ///////////////////////////////////////////////////////////////////////////
3057
3058 // Custom
3059
3060 42 inline FunctionGroup::UniquePtr ax_external(const FunctionOptions& op)
3061 {
3062 208 static auto find = [](auto out, const void* const data, const codegen::String* const name)
3063 {
3064 using ValueType = typename std::remove_pointer<decltype(out)>::type;
3065 const ax::CustomData* const customData =
3066 static_cast<const ax::CustomData*>(data);
3067 208 const TypedMetadata<ValueType>* const metaData =
3068 customData->getData<TypedMetadata<ValueType>>(name->str());
3069
1/2
✓ Branch 0 taken 104 times.
✗ Branch 1 not taken.
208 *out = (metaData ? metaData->value() : zeroVal<ValueType>());
3070 208 };
3071
3072
3073 using FindF = void(float*, const void* const, const codegen::String* const);
3074 using FindV3F = void(openvdb::math::Vec3<float>*, const void* const, const codegen::String* const);
3075
3076 42 return FunctionBuilder("_external")
3077
1/2
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
42 .addSignature<FindF>((FindF*)(find))
3078
1/2
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
42 .addSignature<FindV3F>((FindV3F*)(find))
3079
2/4
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 42 times.
✗ Branch 5 not taken.
84 .setArgumentNames({"str", "custom_data", "result"})
3080
1/2
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
42 .addParameterAttribute(0, llvm::Attribute::NoAlias)
3081
1/2
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
42 .addParameterAttribute(0, llvm::Attribute::WriteOnly)
3082
1/2
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
42 .addParameterAttribute(1, llvm::Attribute::ReadOnly)
3083
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 18 times.
42 .addParameterAttribute(2, llvm::Attribute::ReadOnly)
3084 .setConstantFold(false)
3085
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 18 times.
42 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
3086 .setDocumentation("Internal function for looking up a custom float value.")
3087
1/2
✓ Branch 1 taken 42 times.
✗ Branch 2 not taken.
84 .get();
3088 }
3089
3090 14 inline FunctionGroup::UniquePtr axexternal(const FunctionOptions& op)
3091 {
3092 auto generate =
3093
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 [op](const std::vector<llvm::Value*>& args,
3094 llvm::IRBuilder<>& B) -> llvm::Value*
3095 {
3096 // Pull out the custom data from the parent function
3097 llvm::Function* compute = B.GetInsertBlock()->getParent();
3098
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 assert(compute);
3099
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
28 assert(std::string(compute->getName()).rfind("ax.compute", 0) == 0);
3100 14 llvm::Value* arg = extractArgument(compute, 0);
3101
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 assert(arg);
3102
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✓ Branch 5 taken 14 times.
✗ Branch 6 not taken.
14 assert(arg->getName() == "custom_data");
3103
3104 std::vector<llvm::Value*> inputs;
3105
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 inputs.reserve(2 + args.size());
3106
2/4
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
14 inputs.emplace_back(insertStaticAlloca(B, LLVMType<float>::get(B.getContext())));
3107
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 inputs.emplace_back(arg);
3108
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 inputs.insert(inputs.end(), args.begin(), args.end());
3109
2/4
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
14 ax_external(op)->execute(inputs, B);
3110
2/6
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
28 return B.CreateLoad(inputs.front());
3111 14 };
3112
3113 14 return FunctionBuilder("external")
3114
1/2
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
28 .addSignature<float(const codegen::String*)>(generate)
3115
3/8
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
28 .setArgumentNames({"str"})
3116
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 .addDependency("_external")
3117
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 .addParameterAttribute(0, llvm::Attribute::ReadOnly)
3118
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 .addFunctionAttribute(llvm::Attribute::ReadOnly)
3119
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6 times.
14 .addFunctionAttribute(llvm::Attribute::NoRecurse)
3120 .setConstantFold(false)
3121 .setEmbedIR(true) // always embed as we pass through function param "custom_data"
3122
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6 times.
14 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
3123 .setDocumentation("Find a custom user parameter with a given name of type 'float' "
3124 "in the Custom data provided to the AX compiler. If the data can not be found, "
3125 "or is not of the expected type 0.0f is returned.")
3126
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
28 .get();
3127 }
3128
3129 14 inline FunctionGroup::UniquePtr axexternalv(const FunctionOptions& op)
3130 {
3131 auto generate =
3132
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 [op](const std::vector<llvm::Value*>& args,
3133 llvm::IRBuilder<>& B) -> llvm::Value*
3134 {
3135 // Pull out the custom data from the parent function
3136 llvm::Function* compute = B.GetInsertBlock()->getParent();
3137
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 assert(compute);
3138
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
28 assert(std::string(compute->getName()).rfind("ax.compute", 0) == 0);
3139 14 llvm::Value* arg = extractArgument(compute, 0);
3140
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 assert(arg);
3141
2/4
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✓ Branch 5 taken 14 times.
✗ Branch 6 not taken.
14 assert(arg->getName() == "custom_data");
3142
3143 std::vector<llvm::Value*> inputs;
3144
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 inputs.reserve(2 + args.size());
3145
2/4
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
14 inputs.emplace_back(insertStaticAlloca(B, LLVMType<float[3]>::get(B.getContext())));
3146
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 inputs.emplace_back(arg);
3147
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 inputs.insert(inputs.end(), args.begin(), args.end());
3148
3/8
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 14 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
14 ax_external(op)->execute(inputs, B);
3149
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
28 return inputs.front();
3150 14 };
3151
3152 14 return FunctionBuilder("externalv")
3153
1/2
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
28 .addSignature<openvdb::math::Vec3<float>*(const codegen::String*)>(generate)
3154
3/8
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
28 .setArgumentNames({"str"})
3155
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 .addDependency("_external")
3156
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6 times.
14 .addParameterAttribute(0, llvm::Attribute::ReadOnly)
3157 .setConstantFold(false)
3158 .setEmbedIR(true) // always embed as we pass through function param "custom_data"
3159
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6 times.
14 .setPreferredImpl(op.mPrioritiseIR ? FunctionBuilder::IR : FunctionBuilder::C)
3160 .setDocumentation("Find a custom user parameter with a given name of type 'vector float' "
3161 "in the Custom data provided to the AX compiler. If the data can not be found, or is "
3162 "not of the expected type { 0.0f, 0.0f, 0.0f } is returned.")
3163
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
28 .get();
3164 }
3165
3166 ///////////////////////////////////////////////////////////////////////////
3167 ///////////////////////////////////////////////////////////////////////////
3168
3169
3170 void insertStringFunctions(FunctionRegistry& reg, const FunctionOptions* options = nullptr);
3171
3172 1486 void insertStandardFunctions(FunctionRegistry& registry,
3173 const FunctionOptions* options)
3174 {
3175
3/4
✓ Branch 0 taken 1485 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1485 times.
✗ Branch 3 not taken.
1486 const bool create = options && !options->mLazyFunctions;
3176 117394 auto add = [&](const std::string& name,
3177 const FunctionRegistry::ConstructorT creator,
3178 const bool internal = false)
3179 {
3180
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 117394 times.
117394 if (create) registry.insertAndCreate(name, creator, *options, internal);
3181 117394 else registry.insert(name, creator, internal);
3182 118880 };
3183
3184 // memory
3185
3186
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("axmalloc", axmalloc, true);
3187
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("axfree", axfree, true);
3188
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("axrealloc", axrealloc, true);
3189
3190 // llvm instrinsics
3191
3192
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("ceil", llvm_ceil);
3193
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("cos", llvm_cos);
3194
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("exp2", llvm_exp2);
3195
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("exp", llvm_exp);
3196
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("fabs", llvm_fabs);
3197
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("floor", llvm_floor);
3198
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("log10", llvm_log10);
3199
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("log2", llvm_log2);
3200
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("log", llvm_log);
3201
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("pow", llvm_pow);
3202
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("round", llvm_round);
3203
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("sin", llvm_sin);
3204
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("sqrt", llvm_sqrt);
3205
3206 // math
3207
3208
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("abs", axabs);
3209
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("cbrt", axcbrt);
3210
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("clamp", axclamp);
3211
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("cross", axcross);
3212
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("dot", axdot);
3213
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("euclideanmod", axeuclideanmod);
3214
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("fit", axfit);
3215
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("floormod", axfloormod);
3216
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("isfinite", axisfinite);
3217
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("isinf", axisinf);
3218
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("isnan", axisnan);
3219
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("length", axlength);
3220
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("lengthsq", axlengthsq);
3221
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("lerp", axlerp);
3222
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("max", axmax);
3223
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("min", axmin);
3224
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("normalize", axnormalize);
3225
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("rand", axrand);
3226
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("rand32", axrand32);
3227
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("sign", axsign);
3228
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("signbit", axsignbit);
3229
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("truncatemod", axtruncatemod);
3230
3231 // matrix math
3232
3233
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("adjoint", axadjoint);
3234
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("cofactor", axcofactor);
3235
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("determinant", axdeterminant);
3236
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("diag", axdiag);
3237
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("identity3", axidentity3);
3238
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("identity4", axidentity4);
3239
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("inverse", axinverse);
3240
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("mmmult", axmmmult, true);
3241
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("polardecompose", axpolardecompose);
3242
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("postscale", axpostscale);
3243
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("prescale", axprescale);
3244
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("pretransform", axpretransform);
3245
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("trace", axtrace);
3246
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("transform", axtransform);
3247
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("transpose", axtranspose);
3248
3249 // noise
3250
3251
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("simplexnoise", axsimplexnoise);
3252
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("curlsimplexnoise", axcurlsimplexnoise);
3253
3254 // trig
3255
3256
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("degrees", axdegrees);
3257
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("radians", axradians);
3258
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("acos", axacos);
3259
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("acosh", axacosh);
3260
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("asin", axasin);
3261
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("asinh", axasinh);
3262
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("atan", axatan);
3263
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("atan2", axatan2);
3264
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("atanh", axatanh);
3265
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("cosh", axcosh);
3266
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("sinh", axsinh);
3267
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("tan", axtan);
3268
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("tanh", axtanh);
3269
3270 // string
3271
3272
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("atoi", axatoi);
3273
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("atof", axatof);
3274
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("hash", axhash);
3275
3276 // util
3277
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("argsort", axargsort);
3278
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("sort", axsort);
3279
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("print", axprint);
3280
3281 // colour
3282
3283
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("hsvtorgb", axhsvtorgb);
3284
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("rgbtohsv", axrgbtohsv);
3285
3286 // custom
3287
3288
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("_external", ax_external, true);
3289
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("external", axexternal);
3290
2/4
✓ Branch 1 taken 1486 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1486 times.
✗ Branch 5 not taken.
1486 add("externalv", axexternalv);
3291
3292 1486 insertStringFunctions(registry, options);
3293 1486 }
3294
3295
3296 } // namespace codegen
3297 } // namespace ax
3298 } // namespace OPENVDB_VERSION_NAME
3299 } // namespace openvdb
3300
3301