ruby-llvm 2.9.1 → 2.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +3 -2
- data/ext/ruby-llvm-support/Rakefile +18 -0
- data/ext/ruby-llvm-support/support.cpp +12 -0
- data/lib/llvm/analysis.rb +22 -3
- data/lib/llvm/core/bitcode.rb +88 -0
- data/lib/llvm/core/builder.rb +401 -81
- data/lib/llvm/core/context.rb +5 -13
- data/lib/llvm/core/module.rb +6 -11
- data/lib/llvm/core/pass_manager.rb +27 -13
- data/lib/llvm/core/type.rb +29 -18
- data/lib/llvm/core/value.rb +32 -24
- data/lib/llvm/core.rb +1 -0
- data/lib/llvm/execution_engine.rb +45 -40
- data/lib/llvm/support.rb +22 -0
- data/lib/llvm/transforms/ipo.rb +6 -0
- data/lib/llvm/version.rb +4 -0
- data/lib/llvm.rb +3 -9
- data/test/array_test.rb +38 -0
- data/test/basic_block_test.rb +88 -0
- data/test/basic_test.rb +11 -0
- data/test/binary_operations_test.rb +58 -0
- data/test/bitcode_test.rb +25 -0
- data/test/branch_test.rb +57 -0
- data/test/call_test.rb +82 -0
- data/test/comparisons_test.rb +66 -0
- data/test/conversions_test.rb +86 -0
- data/test/double_test.rb +33 -0
- data/test/equality_test.rb +91 -0
- data/test/generic_value_test.rb +22 -0
- data/test/instruction_test.rb +32 -0
- data/test/ipo_test.rb +53 -0
- data/test/memory_access_test.rb +38 -0
- data/test/module_test.rb +21 -0
- data/test/parameter_collection_test.rb +28 -0
- data/test/phi_test.rb +33 -0
- data/test/select_test.rb +22 -0
- data/test/struct_test.rb +75 -0
- data/test/test_helper.rb +50 -0
- data/test/type_test.rb +15 -0
- data/test/vector_test.rb +64 -0
- metadata +116 -39
@@ -0,0 +1,88 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class BasicBlockTestCase < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
LLVM.init_x86
|
7
|
+
@module = LLVM::Module.new("BasicBlockTestCase")
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_basic_block_collection
|
11
|
+
@module.functions.add("test_basic_block_collection", [], LLVM.Void) do |fn|
|
12
|
+
coll = fn.basic_blocks
|
13
|
+
|
14
|
+
block1 = coll.append
|
15
|
+
assert_instance_of LLVM::BasicBlock, block1
|
16
|
+
|
17
|
+
assert_equal 1, coll.size
|
18
|
+
assert_equal coll.first, coll.last,
|
19
|
+
'Only one block exists in the function'
|
20
|
+
assert_equal coll.first, coll.entry,
|
21
|
+
'The entry block for the function is always the first block'
|
22
|
+
|
23
|
+
block2 = coll.append
|
24
|
+
assert_equal 2, coll.size
|
25
|
+
assert_equal block1, coll.first
|
26
|
+
assert_equal block2, coll.last
|
27
|
+
|
28
|
+
[ coll.each.to_a, coll.to_a ].each do |blocks|
|
29
|
+
assert_equal 2, blocks.size
|
30
|
+
assert_equal block1, blocks[0]
|
31
|
+
assert_equal block2, blocks[1]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_basic_block
|
37
|
+
@module.functions.add("test_basic_block", [], LLVM.Void) do |fn|
|
38
|
+
coll = fn.basic_blocks
|
39
|
+
|
40
|
+
block1 = coll.append
|
41
|
+
block2 = coll.append
|
42
|
+
|
43
|
+
assert_equal fn, block1.parent
|
44
|
+
assert_equal fn, block2.parent
|
45
|
+
|
46
|
+
assert_equal block2, block1.next
|
47
|
+
assert_equal block1, block2.previous
|
48
|
+
|
49
|
+
block1.build do |builder|
|
50
|
+
builder.br(block2)
|
51
|
+
end
|
52
|
+
|
53
|
+
block2.build do |builder|
|
54
|
+
builder.ret_void
|
55
|
+
end
|
56
|
+
|
57
|
+
assert_equal block1.first_instruction,
|
58
|
+
block1.last_instruction
|
59
|
+
assert_equal block2.first_instruction,
|
60
|
+
block2.last_instruction
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_basic_block_enumerable
|
65
|
+
@module.functions.add("test_basic_block_enumerable", [LLVM::Double], LLVM::Double) do |fn, arg|
|
66
|
+
block1 = fn.basic_blocks.append
|
67
|
+
|
68
|
+
[ block1.instructions.to_a, block1.instructions.each.to_a ].each do |insts|
|
69
|
+
assert_equal 0, insts.size, 'Empty basic block'
|
70
|
+
end
|
71
|
+
|
72
|
+
block1.build do |builder|
|
73
|
+
builder.ret(builder.fadd(arg, LLVM.Double(1.0)))
|
74
|
+
end
|
75
|
+
|
76
|
+
[ block1.instructions.to_a, block1.instructions.each.to_a ].each do |insts|
|
77
|
+
assert_equal 2, insts.size
|
78
|
+
assert_equal block1.first_instruction, insts[0] # deprecated
|
79
|
+
assert_equal block1.last_instruction, insts[1] # deprecated
|
80
|
+
assert_equal block1.instructions.first, insts[0]
|
81
|
+
assert_equal block1.instructions.last, insts[1]
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
data/test/basic_test.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class BasicOperationsTestCase < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
LLVM.init_x86
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_integer_binary_operations
|
10
|
+
integer_binary_operation_assertion(:add, 3, 2, 3 + 2)
|
11
|
+
integer_binary_operation_assertion(:sub, 3, 2, 3 - 2)
|
12
|
+
integer_binary_operation_assertion(:mul, 3, 2, 3 * 2)
|
13
|
+
integer_binary_operation_assertion(:udiv, 10, 2, 10 / 2)
|
14
|
+
integer_binary_operation_assertion(:sdiv, 10, 2, 10 / 2)
|
15
|
+
integer_binary_operation_assertion(:urem, 10, 3, 10 % 3)
|
16
|
+
integer_binary_operation_assertion(:srem, 10, 3, 10 % 3)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_integer_bitwise_binary_operations
|
20
|
+
integer_binary_operation_assertion(:shl, 2, 3, 2 << 3)
|
21
|
+
integer_binary_operation_assertion(:lshr, 16, 3, 16 >> 3)
|
22
|
+
integer_binary_operation_assertion(:ashr, 16, 3, 16 >> 3)
|
23
|
+
integer_binary_operation_assertion(:and, 2, 1, 2 & 1)
|
24
|
+
integer_binary_operation_assertion(:or, 2, 1, 2 | 1)
|
25
|
+
integer_binary_operation_assertion(:xor, 3, 2, 3 ^ 2)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_float_binary_operations
|
29
|
+
float_binary_operation_assertion(:fadd, 3.1, 2.2, 3.1 + 2.2)
|
30
|
+
float_binary_operation_assertion(:fsub, 3.1, 2.2, 3.1 - 2.2)
|
31
|
+
float_binary_operation_assertion(:fmul, 3.1, 2.2, 3.1 * 2.2)
|
32
|
+
float_binary_operation_assertion(:fdiv, 3.1, 2.2, 3.1 / 2.2)
|
33
|
+
float_binary_operation_assertion(:frem, 3.1, 2.2, 3.1 % 2.2)
|
34
|
+
end
|
35
|
+
|
36
|
+
def integer_binary_operation_assertion(operation, operand1, operand2, expected_result)
|
37
|
+
result = run_binary_operation(operation,
|
38
|
+
LLVM::Int(operand1), LLVM::Int(operand2),
|
39
|
+
LLVM::Int).to_i
|
40
|
+
assert_equal expected_result, result
|
41
|
+
end
|
42
|
+
|
43
|
+
def float_binary_operation_assertion(operation, operand1, operand2, expected_result)
|
44
|
+
result = run_binary_operation(operation,
|
45
|
+
LLVM::Float(operand1), LLVM::Float(operand2),
|
46
|
+
LLVM::Float).to_f
|
47
|
+
assert_in_delta expected_result, result, 0.001
|
48
|
+
end
|
49
|
+
|
50
|
+
def run_binary_operation(operation, operand1, operand2, return_type)
|
51
|
+
run_function([], [], return_type) do |builder, function, *arguments|
|
52
|
+
entry = function.basic_blocks.append
|
53
|
+
builder.position_at_end(entry)
|
54
|
+
builder.ret(builder.send(operation, operand1, operand2))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "tempfile"
|
3
|
+
|
4
|
+
class BitcodeTestCase < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
LLVM.init_x86
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_bitcode
|
10
|
+
test_module = define_module("test_module") do |mod|
|
11
|
+
define_function(mod, "test_function", [], LLVM::Int) do
|
12
|
+
|builder, function, *arguments|
|
13
|
+
entry = function.basic_blocks.append
|
14
|
+
builder.position_at_end(entry)
|
15
|
+
builder.ret(LLVM::Int(1))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
Tempfile.open("bitcode") do |tmp|
|
19
|
+
assert test_module.write_bitcode(tmp)
|
20
|
+
new_module = LLVM::Module.parse_bitcode(tmp.path)
|
21
|
+
result = run_function_on_module(new_module, "test_function").to_i
|
22
|
+
assert_equal 1, result
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/test/branch_test.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class BranchTestCase < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
LLVM.init_x86
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_branching
|
10
|
+
assert_equal 0, direct_jump_function().to_i
|
11
|
+
assert_equal 0, conditional_jump_function().to_i
|
12
|
+
assert_equal 0, switched_jump_function().to_i
|
13
|
+
end
|
14
|
+
|
15
|
+
def direct_jump_function
|
16
|
+
run_function([], [], LLVM::Int) do |builder, function, *arguments|
|
17
|
+
entry = function.basic_blocks.append
|
18
|
+
branch_1 = function.basic_blocks.append
|
19
|
+
branch_2 = function.basic_blocks.append
|
20
|
+
builder.position_at_end(entry)
|
21
|
+
builder.br(branch_2)
|
22
|
+
builder.position_at_end(branch_1)
|
23
|
+
builder.ret(LLVM::Int(1))
|
24
|
+
builder.position_at_end(branch_2)
|
25
|
+
builder.ret(LLVM::Int(0))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def conditional_jump_function
|
30
|
+
run_function([], [], LLVM::Int) do |builder, function, *arguments|
|
31
|
+
entry = function.basic_blocks.append
|
32
|
+
branch_1 = function.basic_blocks.append
|
33
|
+
branch_2 = function.basic_blocks.append
|
34
|
+
builder.position_at_end(entry)
|
35
|
+
builder.cond(builder.icmp(:eq, LLVM::Int(1), LLVM::Int(2)), branch_1, branch_2)
|
36
|
+
builder.position_at_end(branch_1)
|
37
|
+
builder.ret(LLVM::Int(1))
|
38
|
+
builder.position_at_end(branch_2)
|
39
|
+
builder.ret(LLVM::Int(0))
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def switched_jump_function
|
44
|
+
run_function([], [], LLVM::Int) do |builder, function, *arguments|
|
45
|
+
entry = function.basic_blocks.append
|
46
|
+
branch_1 = function.basic_blocks.append
|
47
|
+
branch_2 = function.basic_blocks.append
|
48
|
+
builder.position_at_end(entry)
|
49
|
+
switch = builder.switch(LLVM::Int(1), branch_1, LLVM::Int(1) => branch_2)
|
50
|
+
builder.position_at_end(branch_1)
|
51
|
+
builder.ret(LLVM::Int(1))
|
52
|
+
builder.position_at_end(branch_2)
|
53
|
+
builder.ret(LLVM::Int(0))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
data/test/call_test.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class CallTestCase < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
LLVM.init_x86
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_simple_call
|
10
|
+
test_module = define_module("test_module") do |host_module|
|
11
|
+
define_function(host_module, "test_function", [], LLVM::Int) do |builder, function, *arguments|
|
12
|
+
entry = function.basic_blocks.append
|
13
|
+
builder.position_at_end(entry)
|
14
|
+
builder.ret(LLVM::Int(1))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
assert_equal 1, run_function_on_module(test_module, "test_function").to_i
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_nested_call
|
21
|
+
test_module = define_module("test_module") do |host_module|
|
22
|
+
function_1 = define_function(host_module, "test_function_1", [], LLVM::Int) do |builder, function, *arguments|
|
23
|
+
entry = function.basic_blocks.append
|
24
|
+
builder.position_at_end(entry)
|
25
|
+
builder.ret(LLVM::Int(1))
|
26
|
+
end
|
27
|
+
function_2 = define_function(host_module, "test_function_2", [], LLVM::Int) do |builder, function, *arguments|
|
28
|
+
entry = function.basic_blocks.append
|
29
|
+
builder.position_at_end(entry)
|
30
|
+
builder.ret(builder.call(function_1))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
assert_equal 1, run_function_on_module(test_module, "test_function_2").to_i
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_recursive_call
|
37
|
+
test_module = define_module("test_module") do |host_module|
|
38
|
+
define_function(host_module, "test_function", [LLVM::Int], LLVM::Int) do |builder, function, *arguments|
|
39
|
+
entry = function.basic_blocks.append
|
40
|
+
recurse = function.basic_blocks.append
|
41
|
+
exit = function.basic_blocks.append
|
42
|
+
builder.position_at_end(entry)
|
43
|
+
builder.cond(builder.icmp(:uge, arguments.first, LLVM::Int(5)), exit, recurse)
|
44
|
+
builder.position_at_end(recurse)
|
45
|
+
result = builder.call(function, builder.add(arguments.first, LLVM::Int(1)))
|
46
|
+
builder.br(exit)
|
47
|
+
builder.position_at_end(exit)
|
48
|
+
builder.ret(builder.phi(LLVM::Int, entry => arguments.first, recurse => result))
|
49
|
+
end
|
50
|
+
end
|
51
|
+
assert_equal 5, run_function_on_module(test_module, "test_function", 1).to_i
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_external
|
55
|
+
test_module = define_module("test_module") do |host_module|
|
56
|
+
external = host_module.functions.add("abs", [LLVM::Int], LLVM::Int)
|
57
|
+
define_function(host_module, "test_function", [LLVM::Int], LLVM::Int) do |builder, function, *arguments|
|
58
|
+
entry = function.basic_blocks.append
|
59
|
+
builder.position_at_end(entry)
|
60
|
+
builder.ret(builder.call(external, arguments.first))
|
61
|
+
end
|
62
|
+
end
|
63
|
+
assert_equal -10.abs, run_function_on_module(test_module, "test_function", -10).to_i
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_external_string
|
67
|
+
test_module = define_module("test_module") do |host_module|
|
68
|
+
global = host_module.globals.add(LLVM::Array(LLVM::Int8, 5), "path")
|
69
|
+
global.linkage = :internal
|
70
|
+
global.initializer = LLVM::ConstantArray.string("PATH")
|
71
|
+
external = host_module.functions.add("getenv", [LLVM::Pointer(LLVM::Int8)], LLVM::Pointer(LLVM::Int8))
|
72
|
+
define_function(host_module, "test_function", [], LLVM::Pointer(LLVM::Int8)) do |builder, function, *arguments|
|
73
|
+
entry = function.basic_blocks.append
|
74
|
+
builder.position_at_end(entry)
|
75
|
+
parameter = builder.gep(global, [LLVM::Int(0), LLVM::Int(0)])
|
76
|
+
builder.ret(builder.call(external, parameter))
|
77
|
+
end
|
78
|
+
end
|
79
|
+
assert_equal ENV["PATH"], run_function_on_module(test_module, "test_function").to_ptr.read_pointer.read_string
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class ComparisonsTestCase < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
LLVM.init_x86
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_integer_comparison
|
10
|
+
integer_comparison_assertion(:eq, 1, 1, LLVM_SIGNED, LLVM_TRUE)
|
11
|
+
integer_comparison_assertion(:ne, 1, 1, LLVM_SIGNED, LLVM_FALSE)
|
12
|
+
integer_comparison_assertion(:ugt, 2, 2, LLVM_UNSIGNED, LLVM_FALSE)
|
13
|
+
integer_comparison_assertion(:uge, 2, 1, LLVM_UNSIGNED, LLVM_TRUE)
|
14
|
+
integer_comparison_assertion(:ult, 1, 1, LLVM_UNSIGNED, LLVM_FALSE)
|
15
|
+
integer_comparison_assertion(:ule, 1, 2, LLVM_UNSIGNED, LLVM_TRUE)
|
16
|
+
integer_comparison_assertion(:sgt, -2, 2, LLVM_SIGNED, LLVM_FALSE)
|
17
|
+
integer_comparison_assertion(:sge, -2, 1, LLVM_SIGNED, LLVM_FALSE)
|
18
|
+
integer_comparison_assertion(:slt, -1, 2, LLVM_SIGNED, LLVM_TRUE)
|
19
|
+
integer_comparison_assertion(:sle, -1, 2, LLVM_SIGNED, LLVM_TRUE)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_float_comparison
|
23
|
+
float_comparison_assertion(:oeq, 1.0, 1.0, LLVM_TRUE)
|
24
|
+
float_comparison_assertion(:one, 1.0, 1.0, LLVM_FALSE)
|
25
|
+
float_comparison_assertion(:ogt, 2.0, 2.0, LLVM_FALSE)
|
26
|
+
float_comparison_assertion(:oge, 2.0, 1.0, LLVM_TRUE)
|
27
|
+
float_comparison_assertion(:olt, 1.0, 1.0, LLVM_FALSE)
|
28
|
+
float_comparison_assertion(:ole, 1.0, 2.0, LLVM_TRUE)
|
29
|
+
float_comparison_assertion(:ord, 1.0, 2.0, LLVM_TRUE)
|
30
|
+
float_comparison_assertion(:ueq, 1.0, 1.0, LLVM_TRUE)
|
31
|
+
float_comparison_assertion(:une, 1.0, 1.0, LLVM_FALSE)
|
32
|
+
float_comparison_assertion(:ugt, 2.0, 2.0, LLVM_FALSE)
|
33
|
+
float_comparison_assertion(:uge, 2.0, 1.0, LLVM_TRUE)
|
34
|
+
float_comparison_assertion(:ult, 1.0, 1.0, LLVM_FALSE)
|
35
|
+
float_comparison_assertion(:ule, 1.0, 2.0, LLVM_TRUE)
|
36
|
+
float_comparison_assertion(:uno, 1.0, 2.0, LLVM_FALSE)
|
37
|
+
end
|
38
|
+
|
39
|
+
def integer_comparison_assertion(operation, operand1, operand2, signed, expected_result)
|
40
|
+
result = run_comparison_operation(:icmp,
|
41
|
+
operation,
|
42
|
+
LLVM::Int.from_i(operand1, signed),
|
43
|
+
LLVM::Int.from_i(operand2, signed),
|
44
|
+
LLVM::Int1).to_i(false)
|
45
|
+
assert_equal expected_result, result
|
46
|
+
end
|
47
|
+
|
48
|
+
def float_comparison_assertion(operation, operand1, operand2, expected_result)
|
49
|
+
result = run_comparison_operation(:fcmp,
|
50
|
+
operation,
|
51
|
+
LLVM::Float(operand1),
|
52
|
+
LLVM::Float(operand2),
|
53
|
+
LLVM::Int1).to_i(false)
|
54
|
+
assert_equal expected_result, result
|
55
|
+
end
|
56
|
+
|
57
|
+
def run_comparison_operation(comparison_operation, comparison_operator,
|
58
|
+
operand1, operand2, return_type)
|
59
|
+
run_function([], [], return_type) do |builder, function, *arguments|
|
60
|
+
entry = function.basic_blocks.append
|
61
|
+
builder.position_at_end(entry)
|
62
|
+
builder.ret(builder.send(comparison_operation, comparison_operator, operand1, operand2))
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class ConversionsTestCase < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
LLVM.init_x86
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_trunc_to
|
10
|
+
integer_conversion_assertion(:trunc, LLVM::Int32.from_i(257), LLVM::Int8, LLVM_UNSIGNED, 1)
|
11
|
+
integer_conversion_assertion(:trunc, LLVM::Int32.from_i(123), LLVM::Int1, LLVM_UNSIGNED, 1)
|
12
|
+
integer_conversion_assertion(:trunc, LLVM::Int32.from_i(122), LLVM::Int1, LLVM_UNSIGNED, 0)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_zext_to
|
16
|
+
integer_conversion_assertion(:zext, LLVM::Int16.from_i(257), LLVM::Int32, LLVM_UNSIGNED, 257)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_sext_to
|
20
|
+
integer_conversion_assertion(:sext, LLVM::Int1.from_i(1), LLVM::Int32, LLVM_SIGNED, -1)
|
21
|
+
integer_conversion_assertion(:sext, LLVM::Int8.from_i(-1), LLVM::Int16, LLVM_UNSIGNED, 65535)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_fptrunc_to
|
25
|
+
float_conversion_assertion(:fp_trunc, LLVM::Double(123.0), LLVM::Float, 123.0)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_fpext_to
|
29
|
+
float_conversion_assertion(:fp_ext, LLVM::Float(123.0), LLVM::Double, 123.0)
|
30
|
+
float_conversion_assertion(:fp_ext, LLVM::Float(123.0), LLVM::Float, 123.0)
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_fptoui_to
|
34
|
+
different_type_assertion(:fp2ui, LLVM::Double(123.3), LLVM::Int32, :integer, 123)
|
35
|
+
different_type_assertion(:fp2ui, LLVM::Double(0.7), LLVM::Int32, :integer, 0)
|
36
|
+
different_type_assertion(:fp2ui, LLVM::Double(1.7), LLVM::Int32, :integer, 1)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_fptosi_to
|
40
|
+
different_type_assertion(:fp2si, LLVM::Double(-123.3), LLVM::Int32, :integer, -123)
|
41
|
+
different_type_assertion(:fp2si, LLVM::Double(0.7), LLVM::Int32, :integer, 0)
|
42
|
+
different_type_assertion(:fp2si, LLVM::Double(1.7), LLVM::Int32, :integer, 1)
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_uitofp_to
|
46
|
+
different_type_assertion(:ui2fp, LLVM::Int32.from_i(257), LLVM::Float, :float, 257.0)
|
47
|
+
different_type_assertion(:ui2fp, LLVM::Int8.from_i(-1), LLVM::Double, :float, 255.0)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_sitofp_to
|
51
|
+
different_type_assertion(:si2fp, LLVM::Int32.from_i(257), LLVM::Float, :float, 257.0)
|
52
|
+
different_type_assertion(:si2fp, LLVM::Int8.from_i(-1), LLVM::Double, :float, -1.0)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_bitcast_to
|
56
|
+
different_type_assertion(:bit_cast, LLVM::Int8.from_i(255), LLVM::Int8, :integer, -1)
|
57
|
+
end
|
58
|
+
|
59
|
+
def integer_conversion_assertion(operation, operand, return_type, signed, expected_result)
|
60
|
+
result = run_conversion_operation(operation, operand, return_type)
|
61
|
+
assert_equal expected_result, result.to_i(signed)
|
62
|
+
end
|
63
|
+
|
64
|
+
def float_conversion_assertion(operation, operand, return_type, expected_result)
|
65
|
+
result = run_conversion_operation(operation, operand, return_type)
|
66
|
+
assert_in_delta expected_result, result.to_f(return_type), 0.001
|
67
|
+
end
|
68
|
+
|
69
|
+
def different_type_assertion(operation, operand, return_type, assertion_type, expected_result)
|
70
|
+
result = run_conversion_operation(operation, operand, return_type)
|
71
|
+
if assertion_type == :integer
|
72
|
+
assert_equal expected_result, result.to_i
|
73
|
+
else
|
74
|
+
assert_in_delta expected_result, result.to_f(return_type), 0.001
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def run_conversion_operation(operation, operand, return_type)
|
79
|
+
run_function([], [], return_type) do |builder, function, *arguments|
|
80
|
+
entry = function.basic_blocks.append
|
81
|
+
builder.position_at_end(entry)
|
82
|
+
builder.ret(builder.send(operation, operand, return_type))
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
data/test/double_test.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class DoubleTestCase < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
LLVM.init_x86
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_double
|
9
|
+
mod = LLVM::Module.new("Double Test")
|
10
|
+
mod.functions.add(:sin, [LLVM::Double], LLVM::Double)
|
11
|
+
|
12
|
+
builder = LLVM::Builder.new
|
13
|
+
|
14
|
+
mod.functions.add('test', [LLVM::Double], LLVM::Double) do |fun, p0|
|
15
|
+
p0.name = 'x'
|
16
|
+
|
17
|
+
bb = fun.basic_blocks.append
|
18
|
+
builder.position_at_end(bb)
|
19
|
+
|
20
|
+
builder.ret(builder.fadd(p0, LLVM::Double(1.0)))
|
21
|
+
end
|
22
|
+
|
23
|
+
engine = LLVM::JITCompiler.new(mod)
|
24
|
+
|
25
|
+
arg = 5.0
|
26
|
+
result = engine.run_function(mod.functions["test"], arg)
|
27
|
+
assert_equal arg+1, result.to_f(LLVM::Double)
|
28
|
+
|
29
|
+
assert_in_delta(Math.sin(1.0),
|
30
|
+
engine.run_function(mod.functions["sin"], 1.0).to_f(LLVM::Double),
|
31
|
+
1e-10)
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "llvm/core"
|
3
|
+
|
4
|
+
class EqualityTestCase < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
LLVM.init_x86
|
7
|
+
end
|
8
|
+
|
9
|
+
class MyModule < LLVM::Module; end
|
10
|
+
class MyInt < LLVM::Int32; end
|
11
|
+
class MyType < LLVM::Type; end
|
12
|
+
class MyFunction < LLVM::Function; end
|
13
|
+
|
14
|
+
def assert_equalities(options)
|
15
|
+
map = {
|
16
|
+
:equal => method(:assert_equal),
|
17
|
+
:not_equal => method(:assert_not_equal),
|
18
|
+
:same => method(:assert_same),
|
19
|
+
:not_same => method(:assert_not_same),
|
20
|
+
:eql => lambda {|n, m, name| assert n.eql?(m), name },
|
21
|
+
:not_eql => lambda {|n, m, name| assert !n.eql?(m), name },
|
22
|
+
}
|
23
|
+
|
24
|
+
map.each do |name, callable|
|
25
|
+
options[name].combination(2).each do |n, m|
|
26
|
+
callable.call(n, m, name.to_s)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_int_value
|
33
|
+
int1 = LLVM::Int32.from_i(1)
|
34
|
+
int2 = LLVM::Int32.from_ptr(int1.to_ptr)
|
35
|
+
int3 = LLVM::Int32.from_i(2)
|
36
|
+
int4 = MyInt.from_ptr(int1.to_ptr)
|
37
|
+
|
38
|
+
assert_equalities :equal => [int1, int2, int4],
|
39
|
+
:not_equal => [int1, int3],
|
40
|
+
:same => [int1, int1],
|
41
|
+
:not_same => [int1, int2, int3, int4],
|
42
|
+
:eql => [int1, int2],
|
43
|
+
:not_eql => [int1, int3, int4]
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_module
|
47
|
+
mod1 = LLVM::Module.new('test')
|
48
|
+
mod2 = LLVM::Module.from_ptr(mod1.to_ptr)
|
49
|
+
mod3 = LLVM::Module.new('dummy')
|
50
|
+
mod4 = MyModule.from_ptr(mod1.to_ptr)
|
51
|
+
|
52
|
+
assert_equalities :equal => [mod1, mod2, mod4],
|
53
|
+
:not_equal => [mod1, mod3],
|
54
|
+
:same => [mod1, mod1],
|
55
|
+
:not_same => [mod1, mod2, mod3, mod4],
|
56
|
+
:eql => [mod1, mod2],
|
57
|
+
:not_eql => [mod1, mod3, mod4]
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_type
|
61
|
+
type1 = LLVM::Float.type
|
62
|
+
type2 = LLVM::Type.from_ptr(type1.to_ptr)
|
63
|
+
type3 = LLVM::Double.type
|
64
|
+
type4 = MyType.from_ptr(type1.to_ptr)
|
65
|
+
|
66
|
+
assert_equalities :equal => [type1, type2, type4],
|
67
|
+
:not_equal => [type1, type3],
|
68
|
+
:same => [type1, type1],
|
69
|
+
:not_same => [type1, type2, type3, type4],
|
70
|
+
:eql => [type1, type2],
|
71
|
+
:not_eql => [type1, type3, type4]
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_function
|
75
|
+
mod = LLVM::Module.new('test')
|
76
|
+
|
77
|
+
fn1 = mod.functions.add('test1', LLVM.Void)
|
78
|
+
fn2 = LLVM::Function.from_ptr(fn1.to_ptr)
|
79
|
+
fn3 = mod.functions.add('test2', LLVM.Void)
|
80
|
+
fn4 = MyFunction.from_ptr(fn1.to_ptr)
|
81
|
+
|
82
|
+
assert_equalities :equal => [fn1, fn2, fn4],
|
83
|
+
:not_equal => [fn1, fn3],
|
84
|
+
:same => [fn1, fn1],
|
85
|
+
:not_same => [fn1, fn2, fn3, fn4],
|
86
|
+
:eql => [fn1, fn2],
|
87
|
+
:not_eql => [fn1, fn3, fn4]
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class GenericValueTestCase < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def setup
|
6
|
+
LLVM.init_x86
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_from_i
|
10
|
+
assert_equal 2, LLVM::GenericValue.from_i(2).to_i
|
11
|
+
assert_equal 2 ,LLVM::GenericValue.from_i(2.2).to_i
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_from_float
|
15
|
+
assert_in_delta 2.2, LLVM::GenericValue.from_f(2.2).to_f, 1e-6
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_from_double
|
19
|
+
assert_in_delta 2.2, LLVM::GenericValue.from_d(2.2).to_f(LLVM::Double), 1e-6
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class InstructionTestCase < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
LLVM.init_x86
|
6
|
+
@module = LLVM::Module.new("InstructionTestCase")
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_instruction
|
10
|
+
fn = @module.functions.add("test_instruction", [LLVM::Double], LLVM::Double) do |fn, arg|
|
11
|
+
fn.basic_blocks.append.build do |builder|
|
12
|
+
builder.ret(
|
13
|
+
builder.fadd(arg, LLVM.Double(3.0)))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
entry = fn.basic_blocks.entry
|
18
|
+
|
19
|
+
inst1 = entry.instructions.first
|
20
|
+
inst2 = entry.instructions.last
|
21
|
+
|
22
|
+
assert_kind_of LLVM::Instruction, inst1
|
23
|
+
assert_kind_of LLVM::Instruction, inst2
|
24
|
+
|
25
|
+
assert_equal inst2, inst1.next
|
26
|
+
assert_equal inst1, inst2.previous
|
27
|
+
assert_equal entry, inst1.parent
|
28
|
+
assert_equal entry, inst2.parent
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|