Skip to content

Commit 379a12e

Browse files
committed
LLVMCodeBuilder: Implement lower than comparison
1 parent d146cf3 commit 379a12e

File tree

5 files changed

+69
-5
lines changed

5 files changed

+69
-5
lines changed

src/dev/engine/internal/icodebuilder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ class ICodeBuilder
3131

3232
virtual void createCmpEQ() = 0;
3333
virtual void createCmpGT() = 0;
34+
virtual void createCmpLT() = 0;
35+
3436
virtual void beginIfStatement() = 0;
3537
virtual void beginElseBranch() = 0;
3638
virtual void endIf() = 0;

src/dev/engine/internal/llvmcodebuilder.cpp

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,14 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
144144
break;
145145
}
146146

147+
case Step::Type::CmpLT: {
148+
assert(step.args.size() == 2);
149+
const auto &arg1 = step.args[0].second;
150+
const auto &arg2 = step.args[1].second;
151+
step.functionReturnReg->value = createComparison(arg1, arg2, Comparison::LT);
152+
break;
153+
}
154+
147155
case Step::Type::Yield:
148156
if (!m_warp) {
149157
freeHeap();
@@ -492,6 +500,11 @@ void LLVMCodeBuilder::createCmpGT()
492500
createOp(Step::Type::CmpGT, Compiler::StaticType::Bool, 2);
493501
}
494502

503+
void LLVMCodeBuilder::createCmpLT()
504+
{
505+
createOp(Step::Type::CmpLT, Compiler::StaticType::Bool, 2);
506+
}
507+
495508
void LLVMCodeBuilder::beginIfStatement()
496509
{
497510
Step step(Step::Type::BeginIf);
@@ -1036,8 +1049,25 @@ llvm::Value *LLVMCodeBuilder::createComparison(std::shared_ptr<Register> arg1, s
10361049
return m_builder.CreateAnd(m_builder.CreateNot(bothNan), m_builder.CreateSelect(nan, nanCmp, cmp));
10371050
}
10381051

1039-
case Comparison::LT:
1040-
return m_builder.CreateFCmpOLT(value1, value2);
1052+
case Comparison::LT: {
1053+
llvm::Value *bothNan = m_builder.CreateAnd(isNaN(value1), isNaN(value2)); // NaN == NaN
1054+
llvm::Value *cmp = m_builder.CreateFCmpOLT(value1, value2);
1055+
llvm::Value *nan;
1056+
llvm::Value *nanCmp;
1057+
1058+
if (optNumberBool == 1) {
1059+
nan = isNaN(value2);
1060+
nanCmp = m_builder.CreateNot(castValue(arg1, Compiler::StaticType::Bool));
1061+
} else if (optNumberBool == 2) {
1062+
nan = isNaN(value1);
1063+
nanCmp = castValue(arg2, Compiler::StaticType::Bool);
1064+
} else {
1065+
nan = isNaN(value2);
1066+
nanCmp = m_builder.CreateFCmpULT(value1, value2);
1067+
}
1068+
1069+
return m_builder.CreateAnd(m_builder.CreateNot(bothNan), m_builder.CreateSelect(nan, nanCmp, cmp));
1070+
}
10411071

10421072
default:
10431073
assert(false);
@@ -1056,7 +1086,8 @@ llvm::Value *LLVMCodeBuilder::createComparison(std::shared_ptr<Register> arg1, s
10561086
return m_builder.CreateAnd(value1, m_builder.CreateNot(value2));
10571087

10581088
case Comparison::LT:
1059-
return m_builder.CreateICmpSLT(value1, value2);
1089+
// value2 && !value1
1090+
return m_builder.CreateAnd(value2, m_builder.CreateNot(value1));
10601091

10611092
default:
10621093
assert(false);

src/dev/engine/internal/llvmcodebuilder.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ class LLVMCodeBuilder : public ICodeBuilder
3333

3434
void createCmpEQ() override;
3535
void createCmpGT() override;
36+
void createCmpLT() override;
37+
3638
void beginIfStatement() override;
3739
void beginElseBranch() override;
3840
void endIf() override;
@@ -71,6 +73,7 @@ class LLVMCodeBuilder : public ICodeBuilder
7173
Div,
7274
CmpEQ,
7375
CmpGT,
76+
CmpLT,
7477
Yield,
7578
BeginIf,
7679
BeginElse,

test/dev/llvm/llvmcodebuilder_test.cpp

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -595,9 +595,10 @@ TEST_F(LLVMCodeBuilderTest, EqualComparison)
595595
addOpTest(nan, "0");
596596
}
597597

598-
TEST_F(LLVMCodeBuilderTest, GreaterThanComparison)
598+
TEST_F(LLVMCodeBuilderTest, GreaterAndLowerThanComparison)
599599
{
600600
auto addOpTest = [this](Value v1, Value v2) {
601+
// GT
601602
createBuilder(true);
602603

603604
m_builder->addConstValue(v1);
@@ -622,7 +623,32 @@ TEST_F(LLVMCodeBuilderTest, GreaterThanComparison)
622623
code->run(ctx.get());
623624
const std::string quotes1 = v1.isString() ? "\"" : "";
624625
const std::string quotes2 = v2.isString() ? "\"" : "";
625-
ASSERT_THAT(testing::internal::GetCapturedStdout(), Eq(expected)) << quotes1 << v1.toString() << quotes1 << " " << quotes2 << v2.toString() << quotes2;
626+
ASSERT_THAT(testing::internal::GetCapturedStdout(), Eq(expected)) << "GT: " << quotes1 << v1.toString() << quotes1 << " " << quotes2 << v2.toString() << quotes2;
627+
628+
// LT
629+
createBuilder(true);
630+
631+
m_builder->addConstValue(v1);
632+
m_builder->addConstValue(v2);
633+
m_builder->createCmpLT();
634+
m_builder->addFunctionCall("test_print_string", Compiler::StaticType::Void, { Compiler::StaticType::String });
635+
636+
m_builder->addConstValue(v1);
637+
callConstFuncForType(v1.type());
638+
m_builder->addConstValue(v2);
639+
callConstFuncForType(v2.type());
640+
m_builder->createCmpLT();
641+
m_builder->addFunctionCall("test_print_string", Compiler::StaticType::Void, { Compiler::StaticType::String });
642+
643+
str = Value(v1 < v2).toString() + '\n';
644+
expected = str + str;
645+
646+
code = m_builder->finalize();
647+
ctx = code->createExecutionContext(&m_target);
648+
649+
testing::internal::CaptureStdout();
650+
code->run(ctx.get());
651+
ASSERT_THAT(testing::internal::GetCapturedStdout(), Eq(expected)) << "LT: " << quotes1 << v1.toString() << quotes1 << " " << quotes2 << v2.toString() << quotes2;
626652
};
627653

628654
addOpTest(10, 10);

test/mocks/codebuildermock.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ class CodeBuilderMock : public ICodeBuilder
2121

2222
MOCK_METHOD(void, createCmpEQ, (), (override));
2323
MOCK_METHOD(void, createCmpGT, (), (override));
24+
MOCK_METHOD(void, createCmpLT, (), (override));
25+
2426
MOCK_METHOD(void, beginIfStatement, (), (override));
2527
MOCK_METHOD(void, beginElseBranch, (), (override));
2628
MOCK_METHOD(void, endIf, (), (override));

0 commit comments

Comments
 (0)