Skip to content

Commit 34d5c42

Browse files
committed
LLVMCodeBuilder: Implement sqrt operator
1 parent e01d6ff commit 34d5c42

File tree

5 files changed

+64
-0
lines changed

5 files changed

+64
-0
lines changed

src/dev/engine/internal/icodebuilder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class ICodeBuilder
4242
virtual void createAbs() = 0;
4343
virtual void createFloor() = 0;
4444
virtual void createCeil() = 0;
45+
virtual void createSqrt() = 0;
4546

4647
virtual void beginIfStatement() = 0;
4748
virtual void beginElseBranch() = 0;

src/dev/engine/internal/llvmcodebuilder.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,18 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
238238
break;
239239
}
240240

241+
case Step::Type::Sqrt: {
242+
assert(step.args.size() == 1);
243+
const auto &arg = step.args[0];
244+
// sqrt(x) + 0.0
245+
// This avoids negative zero
246+
llvm::Constant *zero = llvm::ConstantFP::get(m_ctx, llvm::APFloat(0.0));
247+
llvm::Function *sqrtFunc = llvm::Intrinsic::getDeclaration(m_module.get(), llvm::Intrinsic::sqrt, m_builder.getDoubleTy());
248+
llvm::Value *num = removeNaN(castValue(arg.second, arg.first));
249+
step.functionReturnReg->value = m_builder.CreateFAdd(m_builder.CreateCall(sqrtFunc, num), zero);
250+
break;
251+
}
252+
241253
case Step::Type::Yield:
242254
if (!m_warp) {
243255
freeHeap();
@@ -631,6 +643,11 @@ void LLVMCodeBuilder::createCeil()
631643
createOp(Step::Type::Ceil, Compiler::StaticType::Number, Compiler::StaticType::Number, 1);
632644
}
633645

646+
void LLVMCodeBuilder::createSqrt()
647+
{
648+
createOp(Step::Type::Sqrt, Compiler::StaticType::Number, Compiler::StaticType::Number, 1);
649+
}
650+
634651
void LLVMCodeBuilder::beginIfStatement()
635652
{
636653
Step step(Step::Type::BeginIf);

src/dev/engine/internal/llvmcodebuilder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class LLVMCodeBuilder : public ICodeBuilder
4444
void createAbs() override;
4545
void createFloor() override;
4646
void createCeil() override;
47+
void createSqrt() override;
4748

4849
void beginIfStatement() override;
4950
void beginElseBranch() override;
@@ -92,6 +93,7 @@ class LLVMCodeBuilder : public ICodeBuilder
9293
Abs,
9394
Floor,
9495
Ceil,
96+
Sqrt,
9597
Yield,
9698
BeginIf,
9799
BeginElse,

test/dev/llvm/llvmcodebuilder_test.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,6 +1279,49 @@ TEST_F(LLVMCodeBuilderTest, Ceil)
12791279
addOpTest(nan, 0);
12801280
}
12811281

1282+
TEST_F(LLVMCodeBuilderTest, Sqrt)
1283+
{
1284+
std::string expected;
1285+
1286+
auto addOpTest = [this, &expected](Value v1, double expectedResult) {
1287+
createBuilder(true);
1288+
1289+
m_builder->addConstValue(v1);
1290+
m_builder->createSqrt();
1291+
m_builder->addFunctionCall("test_print_number", Compiler::StaticType::Void, { Compiler::StaticType::Number });
1292+
1293+
m_builder->addConstValue(v1);
1294+
m_builder->addFunctionCall("test_const_number", Compiler::StaticType::Number, { Compiler::StaticType::Number });
1295+
m_builder->createSqrt();
1296+
m_builder->addFunctionCall("test_print_number", Compiler::StaticType::Void, { Compiler::StaticType::Number });
1297+
1298+
std::stringstream stream;
1299+
stream << expectedResult;
1300+
std::string str = stream.str() + '\n';
1301+
std::string expected = str + str;
1302+
1303+
auto code = m_builder->finalize();
1304+
auto ctx = code->createExecutionContext(&m_target);
1305+
1306+
testing::internal::CaptureStdout();
1307+
code->run(ctx.get());
1308+
const std::string quotes1 = v1.isString() ? "\"" : "";
1309+
ASSERT_THAT(testing::internal::GetCapturedStdout(), Eq(expected)) << quotes1 << v1.toString() << quotes1;
1310+
};
1311+
1312+
static const double inf = std::numeric_limits<double>::infinity();
1313+
static const double nan = std::numeric_limits<double>::quiet_NaN();
1314+
1315+
addOpTest(16.0, 4.0);
1316+
addOpTest(0.04, 0.2);
1317+
addOpTest(0.0, 0.0);
1318+
addOpTest(-0.0, 0.0);
1319+
addOpTest(-4.0, -nan); // negative NaN shouldn't be a problem
1320+
addOpTest(inf, inf);
1321+
addOpTest(-inf, -nan);
1322+
addOpTest(nan, 0);
1323+
}
1324+
12821325
TEST_F(LLVMCodeBuilderTest, Yield)
12831326
{
12841327
auto build = [this]() {

test/mocks/codebuildermock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class CodeBuilderMock : public ICodeBuilder
3232
MOCK_METHOD(void, createAbs, (), (override));
3333
MOCK_METHOD(void, createFloor, (), (override));
3434
MOCK_METHOD(void, createCeil, (), (override));
35+
MOCK_METHOD(void, createSqrt, (), (override));
3536

3637
MOCK_METHOD(void, beginIfStatement, (), (override));
3738
MOCK_METHOD(void, beginElseBranch, (), (override));

0 commit comments

Comments
 (0)