GCC Code Coverage Report


Directory: ../
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 96.2% 101 / 0 / 105
Functions: 100.0% 5 / 0 / 5
Branches: 51.3% 159 / 0 / 310

src/irgenerator/GenBuiltinFunctions.cpp
Line Branch Exec Source
1 // Copyright (c) 2021-2026 ChilliBits. All rights reserved.
2
3 #include "IRGenerator.h"
4
5 #include <ast/ASTNodes.h>
6 #include <driver/Driver.h>
7 #include <global/GlobalResourceManager.h>
8 #include <global/TypeRegistry.h>
9 #include <typechecker/Builtins.h>
10 #include <typechecker/TypeChecker.h>
11
12 #include <llvm/IR/InlineAsm.h>
13 #include <llvm/IR/Module.h>
14
15 namespace spice::compiler {
16
17 1777 std::any IRGenerator::visitBuiltinCall(const FctCallNode *node) {
18 // If we have a compile time value, but the computation is still there, we can simply use this constant value
19
2/2
✓ Branch 3 → 4 taken 206 times.
✓ Branch 3 → 10 taken 1571 times.
1777 if (node->hasCompileTimeValue(manIdx)) {
20
2/4
✓ Branch 5 → 6 taken 206 times.
✗ Branch 5 → 25 not taken.
✓ Branch 6 → 7 taken 206 times.
✗ Branch 6 → 25 not taken.
206 llvm::Constant *value = getConst(node->getCompileTimeValue(manIdx), node->getEvaluatedSymbolType(manIdx), node);
21
1/2
✓ Branch 7 → 8 taken 206 times.
✗ Branch 7 → 26 not taken.
412 return LLVMExprResult{.constant = value};
22 }
23
24 // If we need to perform runtime actions, call the specified IRGenerator delegate
25
2/4
✓ Branch 11 → 12 taken 1571 times.
✗ Branch 11 → 27 not taken.
✓ Branch 12 → 13 taken 1571 times.
✗ Branch 12 → 14 not taken.
1571 assert(BUILTIN_FUNCTIONS_MAP.contains(node->fqFunctionName) && "Builtin function not implemented!");
26
1/2
✓ Branch 16 → 17 taken 1571 times.
✗ Branch 16 → 28 not taken.
1571 const BuiltinFunctionInfo &info = BUILTIN_FUNCTIONS_MAP.find(node->fqFunctionName)->second;
27
1/2
✗ Branch 18 → 19 not taken.
✓ Branch 18 → 20 taken 1571 times.
1571 assert(info.irGeneratorVisitMethod != nullptr);
28
1/2
✗ Branch 20 → 21 not taken.
✓ Branch 20 → 22 taken 1571 times.
1571 return (this->*info.irGeneratorVisitMethod)(node);
29 }
30
31 806 std::any IRGenerator::visitBuiltinPrintfCall(const FctCallNode *node) {
32 // Retrieve templated string
33
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 806 times.
806 assert(node->hasArgs);
34 806 const ExprNode *firstArg = node->argLst->args.front();
35
5/10
✓ Branch 5 → 6 taken 806 times.
✗ Branch 5 → 133 not taken.
✓ Branch 6 → 7 taken 806 times.
✗ Branch 6 → 133 not taken.
✓ Branch 7 → 8 taken 806 times.
✗ Branch 7 → 11 not taken.
✓ Branch 8 → 9 taken 806 times.
✗ Branch 8 → 133 not taken.
✓ Branch 9 → 10 taken 806 times.
✗ Branch 9 → 11 not taken.
806 assert(firstArg->getEvaluatedSymbolType(manIdx).is(TY_STRING) && firstArg->hasCompileTimeValue(manIdx));
36
1/2
✓ Branch 12 → 13 taken 806 times.
✗ Branch 12 → 133 not taken.
806 const size_t stringOffset = firstArg->getCompileTimeValue(manIdx).stringValueOffset;
37
2/4
✓ Branch 13 → 14 taken 806 times.
✗ Branch 13 → 133 not taken.
✓ Branch 14 → 15 taken 806 times.
✗ Branch 14 → 133 not taken.
806 const std::string templatedString = resourceManager.compileTimeStringValues.at(stringOffset);
38
39 // Push the template string as first argument
40 806 std::vector<llvm::Value *> printfArgs;
41
2/4
✓ Branch 17 → 18 taken 806 times.
✗ Branch 17 → 93 not taken.
✓ Branch 18 → 19 taken 806 times.
✗ Branch 18 → 91 not taken.
1612 llvm::Constant *templateString = createGlobalStringConst("printf.str.", templatedString, node->codeLoc);
42
1/2
✓ Branch 21 → 22 taken 806 times.
✗ Branch 21 → 97 not taken.
806 printfArgs.push_back(templateString);
43
44 // Collect replacement arguments
45
2/2
✓ Branch 73 → 23 taken 666 times.
✓ Branch 73 → 74 taken 806 times.
1472 for (size_t argIdx = 1; argIdx < node->argLst->args.size(); argIdx++) {
46
1/2
✓ Branch 23 → 24 taken 666 times.
✗ Branch 23 → 124 not taken.
666 const ExprNode *arg = node->argLst->args.at(argIdx);
47 // Retrieve type of argument
48
1/2
✓ Branch 24 → 25 taken 666 times.
✗ Branch 24 → 124 not taken.
666 const QualType argSymbolType = arg->getEvaluatedSymbolType(manIdx);
49
50 // Re-map some values
51 llvm::Value *argVal;
52
2/4
✓ Branch 25 → 26 taken 666 times.
✗ Branch 25 → 124 not taken.
✗ Branch 26 → 27 not taken.
✓ Branch 26 → 39 taken 666 times.
666 if (argSymbolType.isArray()) {
53 // ToDo: Check if GEP can be removed
54 llvm::Value *argValPtr = resolveAddress(arg);
55 llvm::Value *indices[2] = {builder.getInt64(0), builder.getInt32(0)};
56 llvm::Type *argType = argSymbolType.toLLVMType(sourceFile);
57 argVal = insertInBoundsGEP(argType, argValPtr, indices);
58
4/6
✓ Branch 39 → 40 taken 666 times.
✗ Branch 39 → 106 not taken.
✓ Branch 40 → 41 taken 666 times.
✗ Branch 40 → 106 not taken.
✓ Branch 41 → 42 taken 61 times.
✓ Branch 41 → 59 taken 605 times.
666 } else if (argSymbolType.getBase().isStringObj()) {
59
1/2
✓ Branch 42 → 43 taken 61 times.
✗ Branch 42 → 124 not taken.
61 llvm::Value *argValPtr = resolveAddress(arg);
60
2/4
✓ Branch 43 → 44 taken 61 times.
✗ Branch 43 → 107 not taken.
✓ Branch 44 → 45 taken 61 times.
✗ Branch 44 → 107 not taken.
61 llvm::Type *argBaseType = argSymbolType.getBase().toLLVMType(sourceFile);
61
1/2
✓ Branch 48 → 49 taken 61 times.
✗ Branch 48 → 108 not taken.
61 argValPtr = insertStructGEP(argBaseType, argValPtr, 0);
62
3/6
✓ Branch 53 → 54 taken 61 times.
✗ Branch 53 → 116 not taken.
✓ Branch 54 → 55 taken 61 times.
✗ Branch 54 → 114 not taken.
✓ Branch 55 → 56 taken 61 times.
✗ Branch 55 → 114 not taken.
122 argVal = insertLoad(builder.getPtrTy(), argValPtr);
63 } else {
64
1/2
✓ Branch 59 → 60 taken 605 times.
✗ Branch 59 → 124 not taken.
605 argVal = resolveValue(arg);
65 }
66
67 // Extend all integer types lower than 32 bit to 32 bit
68
4/6
✓ Branch 61 → 62 taken 666 times.
✗ Branch 61 → 121 not taken.
✓ Branch 62 → 63 taken 666 times.
✗ Branch 62 → 120 not taken.
✓ Branch 63 → 64 taken 102 times.
✓ Branch 63 → 70 taken 564 times.
666 if (argSymbolType.removeReferenceWrapper().isOneOf({TY_SHORT, TY_BYTE, TY_CHAR, TY_BOOL}))
69
5/10
✓ Branch 64 → 65 taken 102 times.
✗ Branch 64 → 123 not taken.
✓ Branch 65 → 66 taken 102 times.
✗ Branch 65 → 122 not taken.
✓ Branch 66 → 67 taken 102 times.
✗ Branch 66 → 122 not taken.
✓ Branch 67 → 68 taken 102 times.
✗ Branch 67 → 122 not taken.
✓ Branch 68 → 69 taken 102 times.
✗ Branch 68 → 122 not taken.
102 argVal = builder.CreateIntCast(argVal, builder.getInt32Ty(), argSymbolType.removeReferenceWrapper().isSigned());
70
71
1/2
✓ Branch 70 → 71 taken 666 times.
✗ Branch 70 → 124 not taken.
666 printfArgs.push_back(argVal);
72 }
73
74 // Call printf function
75
1/2
✓ Branch 74 → 75 taken 806 times.
✗ Branch 74 → 129 not taken.
806 llvm::Function *printfFct = stdFunctionManager.getPrintfFct();
76
3/6
✓ Branch 75 → 76 taken 806 times.
✗ Branch 75 → 127 not taken.
✓ Branch 77 → 78 taken 806 times.
✗ Branch 77 → 125 not taken.
✓ Branch 78 → 79 taken 806 times.
✗ Branch 78 → 125 not taken.
806 llvm::CallInst *callInst = builder.CreateCall(printfFct, printfArgs);
77
78 // Add noundef attribute to return value and all arguments
79
1/2
✓ Branch 79 → 80 taken 806 times.
✗ Branch 79 → 129 not taken.
806 callInst->addRetAttr(llvm::Attribute::NoUndef);
80
2/2
✓ Branch 84 → 81 taken 1472 times.
✓ Branch 84 → 85 taken 806 times.
2278 for (size_t i = 0; i < printfArgs.size(); i++)
81
1/2
✓ Branch 81 → 82 taken 1472 times.
✗ Branch 81 → 129 not taken.
1472 callInst->addParamAttr(i, llvm::Attribute::NoUndef);
82
83
1/2
✓ Branch 85 → 86 taken 806 times.
✗ Branch 85 → 128 not taken.
1612 return LLVMExprResult{.value = callInst};
84 806 }
85
86 35 std::any IRGenerator::visitBuiltinLenCall(const FctCallNode *node) {
87
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 35 times.
35 assert(node->fqFunctionName == BUILTIN_FCT_NAME_LEN);
88
89 // Check if the length is fixed and known via the symbol type
90 35 const ExprNode *argNode = node->argLst->args.front();
91
1/2
✓ Branch 7 → 8 taken 35 times.
✗ Branch 7 → 28 not taken.
35 QualType symbolType = argNode->getEvaluatedSymbolType(manIdx);
92
1/2
✓ Branch 8 → 9 taken 35 times.
✗ Branch 8 → 22 not taken.
35 symbolType = symbolType.removeReferenceWrapper();
93
2/4
✓ Branch 9 → 10 taken 35 times.
✗ Branch 9 → 28 not taken.
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 35 times.
35 assert(symbolType.is(TY_STRING));
94
95
1/2
✓ Branch 12 → 13 taken 35 times.
✗ Branch 12 → 28 not taken.
35 llvm::Function *getRawLengthFct = stdFunctionManager.getStringGetRawLengthStringFct();
96
4/8
✓ Branch 13 → 14 taken 35 times.
✗ Branch 13 → 26 not taken.
✓ Branch 14 → 15 taken 35 times.
✗ Branch 14 → 24 not taken.
✓ Branch 16 → 17 taken 35 times.
✗ Branch 16 → 23 not taken.
✓ Branch 17 → 18 taken 35 times.
✗ Branch 17 → 23 not taken.
35 llvm::Value *lengthValue = builder.CreateCall(getRawLengthFct, resolveValue(argNode));
97
1/2
✓ Branch 18 → 19 taken 35 times.
✗ Branch 18 → 27 not taken.
70 return LLVMExprResult{.value = lengthValue};
98 }
99
100 729 std::any IRGenerator::visitBuiltinPanicCall(const FctCallNode *node) {
101
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 729 times.
729 assert(node->fqFunctionName == BUILTIN_FCT_NAME_PANIC);
102
103
1/2
✓ Branch 6 → 7 taken 729 times.
✗ Branch 6 → 158 not taken.
729 llvm::PointerType *ptrTy = builder.getPtrTy();
104
105 // Get value for stderr
106 llvm::Value *stdErr;
107
2/2
✓ Branch 8 → 9 taken 11 times.
✓ Branch 8 → 16 taken 718 times.
729 if (cliOptions.targetTriple.isOSWindows()) {
108
1/2
✓ Branch 9 → 10 taken 11 times.
✗ Branch 9 → 158 not taken.
11 llvm::Function *getAcrtIOFuncFct = stdFunctionManager.getAcrtIOFuncFct();
109
4/8
✓ Branch 10 → 11 taken 11 times.
✗ Branch 10 → 99 not taken.
✓ Branch 11 → 12 taken 11 times.
✗ Branch 11 → 97 not taken.
✓ Branch 13 → 14 taken 11 times.
✗ Branch 13 → 96 not taken.
✓ Branch 14 → 15 taken 11 times.
✗ Branch 14 → 96 not taken.
11 stdErr = builder.CreateCall(getAcrtIOFuncFct, {builder.getInt32(/*constant for stderr*/ 2)});
110 } else {
111
3/4
✓ Branch 16 → 17 taken 718 times.
✗ Branch 16 → 158 not taken.
✓ Branch 17 → 18 taken 11 times.
✓ Branch 17 → 19 taken 707 times.
718 const char *globalName = cliOptions.targetTriple.isOSDarwin() ? "__stderrp" : "stderr";
112
2/4
✓ Branch 20 → 21 taken 718 times.
✗ Branch 20 → 100 not taken.
✓ Branch 21 → 22 taken 718 times.
✗ Branch 21 → 100 not taken.
718 module->getOrInsertGlobal(globalName, ptrTy);
113
2/4
✓ Branch 22 → 23 taken 718 times.
✗ Branch 22 → 101 not taken.
✓ Branch 23 → 24 taken 718 times.
✗ Branch 23 → 101 not taken.
718 llvm::GlobalVariable *stdErrPtr = module->getNamedGlobal(globalName);
114
1/2
✓ Branch 24 → 25 taken 718 times.
✗ Branch 24 → 158 not taken.
718 stdErrPtr->setLinkage(llvm::GlobalVariable::ExternalLinkage);
115 718 stdErrPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Local);
116
2/4
✓ Branch 26 → 27 taken 718 times.
✗ Branch 26 → 102 not taken.
✓ Branch 27 → 28 taken 718 times.
✗ Branch 27 → 102 not taken.
718 stdErrPtr->setAlignment(llvm::MaybeAlign(8));
117
2/4
✓ Branch 30 → 31 taken 718 times.
✗ Branch 30 → 105 not taken.
✓ Branch 31 → 32 taken 718 times.
✗ Branch 31 → 103 not taken.
1436 stdErr = insertLoad(ptrTy, stdErrPtr);
118 }
119
120 // Create constant for error message
121
1/2
✓ Branch 35 → 36 taken 729 times.
✗ Branch 35 → 158 not taken.
729 const std::string codeLoc = node->codeLoc.toPrettyString();
122
5/10
✓ Branch 36 → 37 taken 729 times.
✗ Branch 36 → 119 not taken.
✓ Branch 37 → 38 taken 729 times.
✗ Branch 37 → 115 not taken.
✓ Branch 38 → 39 taken 729 times.
✗ Branch 38 → 113 not taken.
✓ Branch 39 → 40 taken 729 times.
✗ Branch 39 → 111 not taken.
✓ Branch 40 → 41 taken 729 times.
✗ Branch 40 → 109 not taken.
729 const std::string templateStr = "Program panicked at " + codeLoc + ": %s\n" + node->getErrorMessage() + "\n";
123
4/8
✓ Branch 47 → 48 taken 729 times.
✗ Branch 47 → 126 not taken.
✓ Branch 48 → 49 taken 729 times.
✗ Branch 48 → 124 not taken.
✓ Branch 49 → 50 taken 729 times.
✗ Branch 49 → 122 not taken.
✓ Branch 51 → 52 taken 729 times.
✗ Branch 51 → 121 not taken.
1458 llvm::GlobalVariable *globalString = builder.CreateGlobalString(templateStr, getUnusedGlobalName(ANON_GLOBAL_STRING_NAME));
124
125 // If the output should be comparable, fix alignment to 4 bytes
126
1/2
✓ Branch 55 → 56 taken 729 times.
✗ Branch 55 → 59 not taken.
729 if (cliOptions.comparableOutput)
127
2/4
✓ Branch 56 → 57 taken 729 times.
✗ Branch 56 → 132 not taken.
✓ Branch 57 → 58 taken 729 times.
✗ Branch 57 → 132 not taken.
729 globalString->setAlignment(llvm::Align(4));
128
129 // Get actual error message
130
1/2
✗ Branch 59 → 60 not taken.
✓ Branch 59 → 61 taken 729 times.
729 assert(node->hasArgs);
131 729 const ExprNode *assignExpr = node->argLst->args.front();
132
1/2
✓ Branch 62 → 63 taken 729 times.
✗ Branch 62 → 154 not taken.
729 llvm::Value *errorObjPtr = resolveAddress(assignExpr);
133
2/4
✓ Branch 63 → 64 taken 729 times.
✗ Branch 63 → 154 not taken.
✓ Branch 64 → 65 taken 729 times.
✗ Branch 64 → 154 not taken.
729 llvm::Type *errorObjTy = assignExpr->getEvaluatedSymbolType(manIdx).toLLVMType(sourceFile);
134
1/2
✓ Branch 68 → 69 taken 729 times.
✗ Branch 68 → 133 not taken.
729 llvm::Value *errorMessagePtr = insertStructGEP(errorObjTy, errorObjPtr, 1);
135
2/4
✓ Branch 73 → 74 taken 729 times.
✗ Branch 73 → 141 not taken.
✓ Branch 74 → 75 taken 729 times.
✗ Branch 74 → 139 not taken.
729 llvm::Value *errorMessage = insertLoad(ptrTy, errorMessagePtr);
136
137 // Print the error message to stderr
138
1/2
✓ Branch 77 → 78 taken 729 times.
✗ Branch 77 → 154 not taken.
729 llvm::Function *fprintfFct = stdFunctionManager.getFPrintfFct();
139
3/6
✓ Branch 78 → 79 taken 729 times.
✗ Branch 78 → 148 not taken.
✓ Branch 80 → 81 taken 729 times.
✗ Branch 80 → 145 not taken.
✓ Branch 81 → 82 taken 729 times.
✗ Branch 81 → 145 not taken.
729 builder.CreateCall(fprintfFct, {stdErr, globalString, errorMessage});
140
141 // Cleanup the scope before calling exit()
142 // Unreachable below counts as terminator
143
2/4
✓ Branch 82 → 83 taken 729 times.
✗ Branch 82 → 154 not taken.
✓ Branch 83 → 84 taken 729 times.
✗ Branch 83 → 154 not taken.
729 terminateBlock(node->getNextOuterStmtLst());
144
145 // Generate call to exit()
146
1/2
✓ Branch 84 → 85 taken 729 times.
✗ Branch 84 → 154 not taken.
729 llvm::Function *exitFct = stdFunctionManager.getExitFct();
147
4/8
✓ Branch 85 → 86 taken 729 times.
✗ Branch 85 → 152 not taken.
✓ Branch 86 → 87 taken 729 times.
✗ Branch 86 → 150 not taken.
✓ Branch 88 → 89 taken 729 times.
✗ Branch 88 → 149 not taken.
✓ Branch 89 → 90 taken 729 times.
✗ Branch 89 → 149 not taken.
729 builder.CreateCall(exitFct, builder.getInt32(EXIT_FAILURE));
148 // Create unreachable instruction
149
1/2
✓ Branch 90 → 91 taken 729 times.
✗ Branch 90 → 154 not taken.
729 builder.CreateUnreachable();
150
151
1/2
✓ Branch 91 → 92 taken 729 times.
✗ Branch 91 → 153 not taken.
1458 return nullptr;
152 729 }
153
154 1 std::any IRGenerator::visitBuiltinSyscallCall(const FctCallNode *node) {
155
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 1 time.
1 assert(node->fqFunctionName == BUILTIN_FCT_NAME_SYSCALL);
156
157 // Determine the required number of operands.
158 // (We assume at least one argument is provided: the syscall number)
159
1/2
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 1 time.
1 assert(node->hasArgs);
160 1 const auto requiredRegs = static_cast<uint8_t>(node->argLst->args.size());
161
2/4
✓ Branch 9 → 10 taken 1 time.
✗ Branch 9 → 12 not taken.
✓ Branch 10 → 11 taken 1 time.
✗ Branch 10 → 12 not taken.
1 assert(requiredRegs >= 1 && requiredRegs <= 6);
162
163 // Create the asm and constraint strings based on the required number of registers.
164
1/2
✓ Branch 13 → 14 taken 1 time.
✗ Branch 13 → 85 not taken.
1 const std::string asmString = getSysCallAsmString(requiredRegs);
165
1/2
✓ Branch 14 → 15 taken 1 time.
✗ Branch 14 → 83 not taken.
1 const std::string constraints = getSysCallConstraintString(requiredRegs);
166
167 // Create the LLVM function type for the inline asm with only the needed operands.
168
1/2
✓ Branch 15 → 16 taken 1 time.
✗ Branch 15 → 81 not taken.
1 llvm::Type *int64Ty = builder.getInt64Ty();
169
1/2
✓ Branch 18 → 19 taken 1 time.
✗ Branch 18 → 61 not taken.
1 const std::vector argTypes(requiredRegs, int64Ty);
170
2/4
✓ Branch 21 → 22 taken 1 time.
✗ Branch 21 → 64 not taken.
✓ Branch 22 → 23 taken 1 time.
✗ Branch 22 → 64 not taken.
1 llvm::FunctionType *fctType = llvm::FunctionType::get(builder.getVoidTy(), argTypes, false);
171
1/2
✓ Branch 25 → 26 taken 1 time.
✗ Branch 25 → 65 not taken.
1 llvm::InlineAsm *inlineAsm = llvm::InlineAsm::get(fctType, asmString, constraints, true);
172
173 // Build the argument list (each provided argument is converted to i64).
174 1 std::vector<llvm::Value *> argValues;
175
1/2
✓ Branch 26 → 27 taken 1 time.
✗ Branch 26 → 77 not taken.
1 argValues.reserve(requiredRegs);
176
2/2
✓ Branch 48 → 28 taken 4 times.
✓ Branch 48 → 49 taken 1 time.
5 for (uint8_t i = 0; i < requiredRegs; i++) {
177
1/2
✓ Branch 28 → 29 taken 4 times.
✗ Branch 28 → 77 not taken.
4 const ExprNode *argNode = node->argLst->args.at(i);
178
1/2
✓ Branch 29 → 30 taken 4 times.
✗ Branch 29 → 77 not taken.
4 const QualType &argType = argNode->getEvaluatedSymbolType(manIdx);
179
2/4
✓ Branch 30 → 31 taken 4 times.
✗ Branch 30 → 67 not taken.
✗ Branch 31 → 32 not taken.
✓ Branch 31 → 33 taken 4 times.
4 assert(argType.isOneOf({TY_INT, TY_LONG, TY_SHORT, TY_BOOL, TY_BYTE, TY_PTR, TY_STRING}));
180
3/4
✓ Branch 33 → 34 taken 4 times.
✗ Branch 33 → 68 not taken.
✓ Branch 34 → 35 taken 1 time.
✓ Branch 34 → 41 taken 3 times.
4 if (argType.isOneOf({TY_PTR, TY_STRING}))
181
5/10
✓ Branch 35 → 36 taken 1 time.
✗ Branch 35 → 69 not taken.
✓ Branch 36 → 37 taken 1 time.
✗ Branch 36 → 69 not taken.
✓ Branch 37 → 38 taken 1 time.
✗ Branch 37 → 69 not taken.
✓ Branch 38 → 39 taken 1 time.
✗ Branch 38 → 69 not taken.
✓ Branch 39 → 40 taken 1 time.
✗ Branch 39 → 69 not taken.
1 argValues.push_back(builder.CreatePtrToInt(resolveValue(argNode), builder.getInt64Ty()));
182 else
183
5/10
✓ Branch 41 → 42 taken 3 times.
✗ Branch 41 → 71 not taken.
✓ Branch 42 → 43 taken 3 times.
✗ Branch 42 → 71 not taken.
✓ Branch 43 → 44 taken 3 times.
✗ Branch 43 → 71 not taken.
✓ Branch 44 → 45 taken 3 times.
✗ Branch 44 → 71 not taken.
✓ Branch 45 → 46 taken 3 times.
✗ Branch 45 → 71 not taken.
3 argValues.push_back(builder.CreateZExt(resolveValue(argNode), builder.getInt64Ty()));
184 }
185
186 // Generate the call using only the required number of arguments.
187
3/6
✓ Branch 49 → 50 taken 1 time.
✗ Branch 49 → 75 not taken.
✓ Branch 51 → 52 taken 1 time.
✗ Branch 51 → 73 not taken.
✓ Branch 52 → 53 taken 1 time.
✗ Branch 52 → 73 not taken.
1 llvm::Value *result = builder.CreateCall(inlineAsm, argValues);
188
189
1/2
✓ Branch 53 → 54 taken 1 time.
✗ Branch 53 → 76 not taken.
2 return LLVMExprResult{.value = result};
190 1 }
191
192 } // namespace spice::compiler
193