Skip to content

Commit f6396e9

Browse files
committed
LLVMCodeBuilder: Add createRandomInt() method
1 parent 6a9b2f6 commit f6396e9

File tree

7 files changed

+73
-0
lines changed

7 files changed

+73
-0
lines changed

src/dev/engine/internal/icodebuilder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class ICodeBuilder
3737
virtual CompilerValue *createDiv(CompilerValue *operand1, CompilerValue *operand2) = 0;
3838

3939
virtual CompilerValue *createRandom(CompilerValue *from, CompilerValue *to) = 0;
40+
virtual CompilerValue *createRandomInt(CompilerValue *from, CompilerValue *to) = 0;
4041

4142
virtual CompilerValue *createCmpEQ(CompilerValue *operand1, CompilerValue *operand2) = 0;
4243
virtual CompilerValue *createCmpGT(CompilerValue *operand1, CompilerValue *operand2) = 0;

src/dev/engine/internal/llvm/llvmcodebuilder.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,16 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
223223
break;
224224
}
225225

226+
case LLVMInstruction::Type::RandomInt: {
227+
assert(step.args.size() == 2);
228+
const auto &arg1 = step.args[0];
229+
const auto &arg2 = step.args[1];
230+
llvm::Value *from = m_builder.CreateFPToSI(castValue(arg1.second, arg1.first), m_builder.getInt64Ty());
231+
llvm::Value *to = m_builder.CreateFPToSI(castValue(arg2.second, arg2.first), m_builder.getInt64Ty());
232+
step.functionReturnReg->value = m_builder.CreateCall(resolve_llvm_random_long(), { executionContextPtr, from, to });
233+
break;
234+
}
235+
226236
case LLVMInstruction::Type::CmpEQ: {
227237
assert(step.args.size() == 2);
228238
const auto &arg1 = step.args[0].second;
@@ -1126,6 +1136,11 @@ CompilerValue *LLVMCodeBuilder::createRandom(CompilerValue *from, CompilerValue
11261136
return createOp(LLVMInstruction::Type::Random, Compiler::StaticType::Number, Compiler::StaticType::Unknown, { from, to });
11271137
}
11281138

1139+
CompilerValue *LLVMCodeBuilder::createRandomInt(CompilerValue *from, CompilerValue *to)
1140+
{
1141+
return createOp(LLVMInstruction::Type::RandomInt, Compiler::StaticType::Number, Compiler::StaticType::Number, { from, to });
1142+
}
1143+
11291144
CompilerValue *LLVMCodeBuilder::createCmpEQ(CompilerValue *operand1, CompilerValue *operand2)
11301145
{
11311146
return createOp(LLVMInstruction::Type::CmpEQ, Compiler::StaticType::Bool, Compiler::StaticType::Number, { operand1, operand2 });
@@ -2384,6 +2399,12 @@ llvm::FunctionCallee LLVMCodeBuilder::resolve_llvm_random_double()
23842399
return resolveFunction("llvm_random_double", llvm::FunctionType::get(m_builder.getDoubleTy(), { pointerType, m_builder.getDoubleTy(), m_builder.getDoubleTy() }, false));
23852400
}
23862401

2402+
llvm::FunctionCallee LLVMCodeBuilder::resolve_llvm_random_long()
2403+
{
2404+
llvm::Type *pointerType = llvm::PointerType::get(llvm::Type::getInt8Ty(m_ctx), 0);
2405+
return resolveFunction("llvm_random_long", llvm::FunctionType::get(m_builder.getDoubleTy(), { pointerType, m_builder.getInt64Ty(), m_builder.getInt64Ty() }, false));
2406+
}
2407+
23872408
llvm::FunctionCallee LLVMCodeBuilder::resolve_llvm_random_bool()
23882409
{
23892410
llvm::Type *pointerType = llvm::PointerType::get(llvm::Type::getInt8Ty(m_ctx), 0);

src/dev/engine/internal/llvm/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
CompilerValue *createDiv(CompilerValue *operand1, CompilerValue *operand2) override;
4545

4646
CompilerValue *createRandom(CompilerValue *from, CompilerValue *to) override;
47+
CompilerValue *createRandomInt(CompilerValue *from, CompilerValue *to) override;
4748

4849
CompilerValue *createCmpEQ(CompilerValue *operand1, CompilerValue *operand2) override;
4950
CompilerValue *createCmpGT(CompilerValue *operand1, CompilerValue *operand2) override;
@@ -170,6 +171,7 @@ class LLVMCodeBuilder : public ICodeBuilder
170171
llvm::FunctionCallee resolve_list_to_string();
171172
llvm::FunctionCallee resolve_llvm_random();
172173
llvm::FunctionCallee resolve_llvm_random_double();
174+
llvm::FunctionCallee resolve_llvm_random_long();
173175
llvm::FunctionCallee resolve_llvm_random_bool();
174176
llvm::FunctionCallee resolve_strcasecmp();
175177

src/dev/engine/internal/llvm/llvmfunctions.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ extern "C"
1919
return value_doubleIsInt(from) && value_doubleIsInt(to) ? ctx->rng()->randint(from, to) : ctx->rng()->randintDouble(from, to);
2020
}
2121

22+
double llvm_random_long(ExecutionContext *ctx, long from, long to)
23+
{
24+
return ctx->rng()->randint(from, to);
25+
}
26+
2227
double llvm_random_bool(ExecutionContext *ctx, bool from, bool to)
2328
{
2429
return ctx->rng()->randint(from, to);

src/dev/engine/internal/llvm/llvminstruction.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ struct LLVMInstruction
1919
Mul,
2020
Div,
2121
Random,
22+
RandomInt,
2223
CmpEQ,
2324
CmpGT,
2425
CmpLT,

test/dev/llvm/llvmcodebuilder_test.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class LLVMCodeBuilderTest : public testing::Test
3030
Mul,
3131
Div,
3232
Random,
33+
RandomInt,
3334
CmpEQ,
3435
CmpGT,
3536
CmpLT,
@@ -98,6 +99,9 @@ class LLVMCodeBuilderTest : public testing::Test
9899
case OpType::Random:
99100
return m_builder->createRandom(arg1, arg2);
100101

102+
case OpType::RandomInt:
103+
return m_builder->createRandomInt(arg1, arg2);
104+
101105
case OpType::CmpEQ:
102106
return m_builder->createCmpEQ(arg1, arg2);
103107

@@ -203,6 +207,9 @@ class LLVMCodeBuilderTest : public testing::Test
203207
return v1.isInt() && v2.isInt() ? m_rng.randint(v1.toLong(), v2.toLong()) : m_rng.randintDouble(v1.toDouble(), v2.toDouble());
204208
}
205209

210+
case OpType::RandomInt:
211+
return m_rng.randint(v1.toLong(), v2.toLong());
212+
206213
case OpType::CmpEQ:
207214
return v1 == v2;
208215

@@ -727,6 +734,41 @@ TEST_F(LLVMCodeBuilderTest, Random)
727734
runOpTest(OpType::Random, -inf, inf, nan);
728735
}
729736

737+
TEST_F(LLVMCodeBuilderTest, RandomInt)
738+
{
739+
EXPECT_CALL(m_rng, randint(-45, 12)).Times(3).WillRepeatedly(Return(-18));
740+
runOpTest(OpType::RandomInt, -45, 12);
741+
742+
EXPECT_CALL(m_rng, randint(-45, 12)).Times(3).WillRepeatedly(Return(5));
743+
runOpTest(OpType::RandomInt, -45.0, 12.0);
744+
745+
EXPECT_CALL(m_rng, randint(12, 6)).Times(3).WillRepeatedly(Return(3));
746+
runOpTest(OpType::RandomInt, 12, 6.05);
747+
748+
EXPECT_CALL(m_rng, randint(-78, -45)).Times(3).WillRepeatedly(Return(-59));
749+
runOpTest(OpType::RandomInt, -78.686, -45);
750+
751+
EXPECT_CALL(m_rng, randint(-45, 12)).Times(3).WillRepeatedly(Return(0));
752+
runOpTest(OpType::RandomInt, "-45", "12");
753+
754+
EXPECT_CALL(m_rng, randint(-45, 12)).Times(3).WillRepeatedly(Return(5));
755+
runOpTest(OpType::RandomInt, "-45.0", "12");
756+
757+
EXPECT_CALL(m_rng, randint(-45, 12)).Times(3).WillRepeatedly(Return(-15));
758+
runOpTest(OpType::RandomInt, "-45", "12.0");
759+
760+
EXPECT_CALL(m_rng, randint(0, 1)).Times(3).WillRepeatedly(Return(1));
761+
runOpTest(OpType::RandomInt, false, true);
762+
763+
EXPECT_CALL(m_rng, randint(1, 5)).Times(3).WillRepeatedly(Return(1));
764+
runOpTest(OpType::RandomInt, true, 5);
765+
766+
EXPECT_CALL(m_rng, randint(8, 0)).Times(3).WillRepeatedly(Return(1));
767+
runOpTest(OpType::RandomInt, 8, false);
768+
769+
// NOTE: Infinity, -Infinity and NaN behavior is undefined
770+
}
771+
730772
TEST_F(LLVMCodeBuilderTest, EqualComparison)
731773
{
732774
runOpTest(OpType::CmpEQ, 10, 10);

test/mocks/codebuildermock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class CodeBuilderMock : public ICodeBuilder
2727
MOCK_METHOD(CompilerValue *, createDiv, (CompilerValue *, CompilerValue *), (override));
2828

2929
MOCK_METHOD(CompilerValue *, createRandom, (CompilerValue *, CompilerValue *), (override));
30+
MOCK_METHOD(CompilerValue *, createRandomInt, (CompilerValue *, CompilerValue *), (override));
3031

3132
MOCK_METHOD(CompilerValue *, createCmpEQ, (CompilerValue *, CompilerValue *), (override));
3233
MOCK_METHOD(CompilerValue *, createCmpGT, (CompilerValue *, CompilerValue *), (override));

0 commit comments

Comments
 (0)