ruby-llvm-next 10.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +30 -0
  3. data/README.md +67 -0
  4. data/ext/ruby-llvm-support/Rakefile +110 -0
  5. data/ext/ruby-llvm-support/support.cpp +32 -0
  6. data/lib/llvm.rb +29 -0
  7. data/lib/llvm/analysis.rb +49 -0
  8. data/lib/llvm/analysis_ffi.rb +77 -0
  9. data/lib/llvm/config.rb +10 -0
  10. data/lib/llvm/core.rb +97 -0
  11. data/lib/llvm/core/bitcode.rb +84 -0
  12. data/lib/llvm/core/bitcode_ffi.rb +132 -0
  13. data/lib/llvm/core/builder.rb +944 -0
  14. data/lib/llvm/core/context.rb +24 -0
  15. data/lib/llvm/core/module.rb +240 -0
  16. data/lib/llvm/core/pass_manager.rb +80 -0
  17. data/lib/llvm/core/type.rb +210 -0
  18. data/lib/llvm/core/value.rb +1005 -0
  19. data/lib/llvm/core_ffi.rb +6021 -0
  20. data/lib/llvm/execution_engine.rb +323 -0
  21. data/lib/llvm/execution_engine_ffi.rb +421 -0
  22. data/lib/llvm/linker.rb +16 -0
  23. data/lib/llvm/linker_ffi.rb +44 -0
  24. data/lib/llvm/support.rb +38 -0
  25. data/lib/llvm/target.rb +318 -0
  26. data/lib/llvm/target_ffi.rb +628 -0
  27. data/lib/llvm/transforms/builder.rb +107 -0
  28. data/lib/llvm/transforms/builder_ffi.rb +117 -0
  29. data/lib/llvm/transforms/ipo.rb +78 -0
  30. data/lib/llvm/transforms/ipo_ffi.rb +127 -0
  31. data/lib/llvm/transforms/scalar.rb +152 -0
  32. data/lib/llvm/transforms/scalar_ffi.rb +344 -0
  33. data/lib/llvm/transforms/vectorize.rb +22 -0
  34. data/lib/llvm/transforms/vectorize_ffi.rb +38 -0
  35. data/lib/llvm/version.rb +5 -0
  36. data/test/array_test.rb +38 -0
  37. data/test/basic_block_test.rb +87 -0
  38. data/test/binary_operations_test.rb +58 -0
  39. data/test/bitcode_test.rb +24 -0
  40. data/test/branch_test.rb +57 -0
  41. data/test/call_test.rb +82 -0
  42. data/test/comparisons_test.rb +66 -0
  43. data/test/conversions_test.rb +92 -0
  44. data/test/double_test.rb +34 -0
  45. data/test/equality_test.rb +89 -0
  46. data/test/function_test.rb +100 -0
  47. data/test/generic_value_test.rb +22 -0
  48. data/test/instruction_test.rb +30 -0
  49. data/test/ipo_test.rb +53 -0
  50. data/test/linker_test.rb +37 -0
  51. data/test/mcjit_test.rb +94 -0
  52. data/test/memory_access_test.rb +38 -0
  53. data/test/module_test.rb +93 -0
  54. data/test/parameter_collection_test.rb +28 -0
  55. data/test/pass_manager_builder_test.rb +53 -0
  56. data/test/phi_test.rb +33 -0
  57. data/test/select_test.rb +22 -0
  58. data/test/struct_test.rb +98 -0
  59. data/test/target_test.rb +113 -0
  60. data/test/test_helper.rb +62 -0
  61. data/test/type_test.rb +15 -0
  62. data/test/vector_test.rb +64 -0
  63. metadata +240 -0
@@ -0,0 +1,87 @@
1
+ require "test_helper"
2
+
3
+ class BasicBlockTestCase < Minitest::Test
4
+
5
+ def setup
6
+ LLVM.init_jit
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
@@ -0,0 +1,58 @@
1
+ require "test_helper"
2
+
3
+ class BasicOperationsTestCase < Minitest::Test
4
+
5
+ def setup
6
+ LLVM.init_jit
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,24 @@
1
+ require "test_helper"
2
+ require "tempfile"
3
+
4
+ class BitcodeTestCase < Minitest::Test
5
+ def setup
6
+ LLVM.init_jit
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 |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
+ Tempfile.open("bitcode") do |tmp|
18
+ assert test_module.write_bitcode(tmp)
19
+ new_module = LLVM::Module.parse_bitcode(tmp.path)
20
+ result = run_function_on_module(new_module, "test_function").to_i
21
+ assert_equal 1, result
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,57 @@
1
+ require "test_helper"
2
+
3
+ class BranchTestCase < Minitest::Test
4
+
5
+ def setup
6
+ LLVM.init_jit
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
@@ -0,0 +1,82 @@
1
+ require "test_helper"
2
+
3
+ class CallTestCase < Minitest::Test
4
+
5
+ def setup
6
+ LLVM.init_jit
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 < Minitest::Test
4
+
5
+ def setup
6
+ LLVM.init_jit
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,92 @@
1
+ require "test_helper"
2
+
3
+ class ConversionsTestCase < Minitest::Test
4
+
5
+ def setup
6
+ LLVM.init_jit
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 test_int64
60
+ integer_conversion_assertion(:zext, LLVM::Int64.from_i(2**62 + 123), LLVM::Int64, LLVM_SIGNED, 2**62 + 123)
61
+ integer_conversion_assertion(:zext, LLVM::Int64.from_i(-2**62 - 123), LLVM::Int64, LLVM_SIGNED, -2**62 - 123)
62
+ integer_conversion_assertion(:zext, LLVM::Int64.from_i(2**63 + 123), LLVM::Int64, LLVM_UNSIGNED, 2**63 + 123)
63
+ end
64
+
65
+ def integer_conversion_assertion(operation, operand, return_type, signed, expected_result)
66
+ result = run_conversion_operation(operation, operand, return_type)
67
+ assert_equal expected_result, result.to_i(signed)
68
+ end
69
+
70
+ def float_conversion_assertion(operation, operand, return_type, expected_result)
71
+ result = run_conversion_operation(operation, operand, return_type)
72
+ assert_in_delta expected_result, result.to_f(return_type), 0.001
73
+ end
74
+
75
+ def different_type_assertion(operation, operand, return_type, assertion_type, expected_result)
76
+ result = run_conversion_operation(operation, operand, return_type)
77
+ if assertion_type == :integer
78
+ assert_equal expected_result, result.to_i
79
+ else
80
+ assert_in_delta expected_result, result.to_f(return_type), 0.001
81
+ end
82
+ end
83
+
84
+ def run_conversion_operation(operation, operand, return_type)
85
+ run_function([], [], return_type) do |builder, function, *arguments|
86
+ entry = function.basic_blocks.append
87
+ builder.position_at_end(entry)
88
+ builder.ret(builder.send(operation, operand, return_type))
89
+ end
90
+ end
91
+
92
+ end