Skip to content

Commit

Permalink
Int128 compiler-rt methods (Int128 literal support part 1) (#11206)
Browse files Browse the repository at this point in the history
Co-authored-by: Johannes Müller <straightshoota@gmail.com>
  • Loading branch information
BlobCodes and straight-shoota authored Sep 24, 2021
1 parent 592470a commit ae915ae
Show file tree
Hide file tree
Showing 12 changed files with 635 additions and 58 deletions.
6 changes: 2 additions & 4 deletions spec/compiler/codegen/arithmetics_spec.cr
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
require "../../spec_helper"

{% if flag?(:darwin) %}
# Int128 and UInt128 specs do not pass on win32 because of missing compiler-rt symbols
{% unless flag?(:win32) %}
SupportedInts = [UInt8, UInt16, UInt32, UInt64, UInt128, Int8, Int16, Int32, Int64, Int128]
SupportedIntsConversions = {
to_i8: Int8, to_i16: Int16, to_i32: Int32, to_i64: Int64, to_i128: Int128,
to_u8: UInt8, to_u16: UInt16, to_u32: UInt32, to_u64: UInt64, to_u128: UInt128,
}
{% else %}
# Skip Int128 and UInt128 on linux platforms due to compiler-rt dependency.
# PreviewOverflowFlags includes compiler_rt flag to support Int64 overflow
# detection in 32 bits platforms.
SupportedInts = [UInt8, UInt16, UInt32, UInt64, Int8, Int16, Int32, Int64]
SupportedIntsConversions = {
to_i8: Int8, to_i16: Int16, to_i32: Int32, to_i64: Int64,
Expand Down
93 changes: 93 additions & 0 deletions spec/std/crystal/compiler_rt/divmod128_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
require "spec"

# TODO: Replace helper methods with literals once possible

private def make_ti(a : Int128, b : Int128)
(a << 64) + b
end

private def make_tu(a : UInt128, b : UInt128)
(a << 64) + b
end

# Ported from:
# - https://github.com/llvm/llvm-project/blob/ce59ccd04023cab3a837da14079ca2dcbfebb70c/compiler-rt/test/builtins/Unit/umodti3_test.c
# - https://github.com/llvm/llvm-project/blob/ce59ccd04023cab3a837da14079ca2dcbfebb70c/compiler-rt/test/builtins/Unit/udivti3_test.c
# - https://github.com/llvm/llvm-project/blob/ce59ccd04023cab3a837da14079ca2dcbfebb70c/compiler-rt/test/builtins/Unit/modti3_test.c
# - https://github.com/llvm/llvm-project/blob/ce59ccd04023cab3a837da14079ca2dcbfebb70c/compiler-rt/test/builtins/Unit/divti3_test.c

private def test__divti3(a : Int128, b : Int128, expected : Int128, file = __FILE__, line = __LINE__)
it "passes compiler-rt builtins unit tests" do
actual = __divti3(a, b)
actual.should eq(expected), file: file, line: line
end
end

private def test__modti3(a : Int128, b : Int128, expected : Int128, file = __FILE__, line = __LINE__)
it "passes compiler-rt builtins unit tests" do
actual = __modti3(a, b)
actual.should eq(expected), file: file, line: line
end
end

private def test__udivti3(a : UInt128, b : UInt128, expected : UInt128, file = __FILE__, line = __LINE__)
it "passes compiler-rt builtins unit tests" do
actual = __udivti3(a, b)
actual.should eq(expected), file: file, line: line
end
end

private def test__umodti3(a : UInt128, b : UInt128, expected : UInt128, file = __FILE__, line = __LINE__)
it "passes compiler-rt builtins unit tests" do
actual = __umodti3(a, b)
actual.should eq(expected), file: file, line: line
end
end

describe "__divti3" do
test__divti3(0, 1, 0)
test__divti3(0, -1, 0)
test__divti3(2, 1, 2)
test__divti3(2, -1, -2)
test__divti3(-2, 1, -2)
test__divti3(-2, -1, 2)
test__divti3(make_ti(-9223372036854775808, 0x0), 1, make_ti(-9223372036854775808, 0x0))
test__divti3(make_ti(-9223372036854775808, 0x0), -1, make_ti(-9223372036854775808, 0x0))
test__divti3(make_ti(-9223372036854775808, 0x0), -2, make_ti(0x4000000000000000, 0x0))
test__divti3(make_ti(-9223372036854775808, 0x0), 2, make_ti(-0x4000000000000000, 0x0))
end

describe "__modti3" do
test__modti3(0, 1, 0)
test__modti3(0, -1, 0)

test__modti3(5, 3, 2)
test__modti3(5, -3, 2)
test__modti3(-5, 3, -2)
test__modti3(-5, -3, -2)

test__modti3(make_ti(-9223372036854775808, 0x0), 1, 0)
test__modti3(make_ti(-9223372036854775808, 0x0), -1, 0)
test__modti3(make_ti(-9223372036854775808, 0x0), 2, 0)
test__modti3(make_ti(-9223372036854775808, 0x0), -2, 0)
test__modti3(make_ti(-9223372036854775808, 0x0), 3, -2)
test__modti3(make_ti(-9223372036854775808, 0x0), -3, -2)
end

describe "__udivti3" do
test__udivti3(0, 1, 0)
test__udivti3(2, 1, 2)

test__udivti3(make_tu(0x0, 0x8000000000000000), 1, make_tu(0x0, 0x8000000000000000))
test__udivti3(make_tu(0x0, 0x8000000000000000), 2, make_tu(0x0, 0x4000000000000000))
test__udivti3(make_tu(0xffffffffffffffff, 0xffffffffffffffff), 2, make_tu(0x7fffffffffffffff, 0xffffffffffffffff))
end

describe "__umodti3" do
test__umodti3(0, 1, 0)
test__umodti3(2, 1, 0)

test__umodti3(make_tu(0x0, 0x8000000000000000), 1, 0)
test__umodti3(make_tu(0x0, 0x8000000000000000), 2, 0)
test__umodti3(make_tu(0xffffffffffffffff, 0xffffffffffffffff), 2, 1)
end
2 changes: 1 addition & 1 deletion spec/std/crystal/compiler_rt/mulodi4_spec.cr
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
require "spec"

# Ported from compiler-rt:test/builtins/Unit/mulodi4_test.c
# Ported from https://github.com/llvm/llvm-project/blob/ce59ccd04023cab3a837da14079ca2dcbfebb70c/compiler-rt/test/builtins/Unit/mulodi4_test.c

private def test__mulodi4(a : Int64, b : Int64, expected : Int64, expected_overflow : Int32, file = __FILE__, line = __LINE__)
it "passes compiler-rt builtins unit tests" do
Expand Down
76 changes: 76 additions & 0 deletions spec/std/crystal/compiler_rt/mulosi4_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
require "spec"

# Ported from https://github.com/llvm/llvm-project/blob/ce59ccd04023cab3a837da14079ca2dcbfebb70c/compiler-rt/test/builtins/Unit/mulosi4_test.c

private def test__mulosi4(a : Int32, b : Int32, expected : Int32, expected_overflow : Int32, file = __FILE__, line = __LINE__)
it "passes compiler-rt builtins unit tests" do
actual_overflow : Int32 = 0
actual = __mulosi4(a, b, pointerof(actual_overflow))
actual_overflow.should eq(expected_overflow), file: file, line: line
if !expected_overflow
actual.should eq(expected), file: file, line: line
end
end
end

describe "__mulosi4" do
test__mulosi4(0, 0, 0, 0)
test__mulosi4(0, 1, 0, 0)
test__mulosi4(1, 0, 0, 0)
test__mulosi4(0, 10, 0, 0)
test__mulosi4(10, 0, 0, 0)
test__mulosi4(0, 0x1234567, 0, 0)
test__mulosi4(0x1234567, 0, 0, 0)

test__mulosi4(0, -1, 0, 0)
test__mulosi4(-1, 0, 0, 0)
test__mulosi4(0, -10, 0, 0)
test__mulosi4(-10, 0, 0, 0)
test__mulosi4(0, 0x1234567, 0, 0)
test__mulosi4(0x1234567, 0, 0, 0)

test__mulosi4(1, 1, 1, 0)
test__mulosi4(1, 10, 10, 0)
test__mulosi4(10, 1, 10, 0)
test__mulosi4(1, 0x1234567, 0x1234567, 0)
test__mulosi4(0x1234567, 1, 0x1234567, 0)

test__mulosi4(1, -1, -1, 0)
test__mulosi4(1, -10, -10, 0)
test__mulosi4(-10, 1, -10, 0)
test__mulosi4(1, -0x1234567, -0x1234567, 0)
test__mulosi4(-0x1234567, 1, -0x1234567, 0)

test__mulosi4(0x7FFFFFFF, -2, -0x7fffffff, 1)
test__mulosi4(-2, 0x7FFFFFFF, -0x7fffffff, 1)
test__mulosi4(0x7FFFFFFF, -1, -0x7fffffff, 0)
test__mulosi4(-1, 0x7FFFFFFF, -0x7fffffff, 0)
test__mulosi4(0x7FFFFFFF, 0, 0, 0)
test__mulosi4(0, 0x7FFFFFFF, 0, 0)
test__mulosi4(0x7FFFFFFF, 1, 0x7FFFFFFF, 0)
test__mulosi4(1, 0x7FFFFFFF, 0x7FFFFFFF, 0)
test__mulosi4(0x7FFFFFFF, 2, -0x7fffffff, 1)
test__mulosi4(2, 0x7FFFFFFF, -0x7fffffff, 1)

test__mulosi4(-0x80000000, -2, -0x80000000, 1)
test__mulosi4(-2, -0x80000000, -0x80000000, 1)
test__mulosi4(-0x80000000, -1, -0x80000000, 1)
test__mulosi4(-1, -0x80000000, -0x80000000, 1)
test__mulosi4(-0x80000000, 0, 0, 0)
test__mulosi4(0, -0x80000000, 0, 0)
test__mulosi4(-0x80000000, 1, -0x80000000, 0)
test__mulosi4(1, -0x80000000, -0x80000000, 0)
test__mulosi4(-0x80000000, 2, -0x80000000, 1)
test__mulosi4(2, -0x80000000, -0x80000000, 1)

test__mulosi4(-0x7fffffff, -2, -0x7fffffff, 1)
test__mulosi4(-2, -0x7fffffff, -0x7fffffff, 1)
test__mulosi4(-0x7fffffff, -1, 0x7FFFFFFF, 0)
test__mulosi4(-1, -0x7fffffff, 0x7FFFFFFF, 0)
test__mulosi4(-0x7fffffff, 0, 0, 0)
test__mulosi4(0, -0x7fffffff, 0, 0)
test__mulosi4(-0x7fffffff, 1, -0x7fffffff, 0)
test__mulosi4(1, -0x7fffffff, -0x7fffffff, 0)
test__mulosi4(-0x7fffffff, 2, -0x80000000, 1)
test__mulosi4(2, -0x7fffffff, -0x80000000, 1)
end
151 changes: 151 additions & 0 deletions spec/std/crystal/compiler_rt/muloti4_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
require "spec"

# Ported from https://github.com/llvm/llvm-project/blob/ce59ccd04023cab3a837da14079ca2dcbfebb70c/compiler-rt/test/builtins/Unit/muloti4_test.c

private def test__muloti4(a : Int128, b : Int128, expected : Int128, expected_overflow : Int32, file = __FILE__, line = __LINE__)
it "passes compiler-rt builtins unit tests" do
actual_overflow : Int32 = 0
actual = __muloti4(a, b, pointerof(actual_overflow))
actual_overflow.should eq(expected_overflow), file: file, line: line
if !expected_overflow
actual.should eq(expected), file: file, line: line
end
end
end

# TODO: Replace helper methods with literals once possible

private def make_ti(a : Int128, b : Int128)
(a << 64) + b
end

describe "__muloti4" do
test__muloti4(0, 0, 0, 0)
test__muloti4(0, 1, 0, 0)
test__muloti4(1, 0, 0, 0)
test__muloti4(0, 10, 0, 0)
test__muloti4(10, 0, 0, 0)
test__muloti4(0, 81985529216486895, 0, 0)
test__muloti4(81985529216486895, 0, 0, 0)
test__muloti4(0, -1, 0, 0)
test__muloti4(-1, 0, 0, 0)
test__muloti4(0, -10, 0, 0)
test__muloti4(-10, 0, 0, 0)
test__muloti4(0, -81985529216486895, 0, 0)
test__muloti4(-81985529216486895, 0, 0, 0)
test__muloti4(1, 1, 1, 0)
test__muloti4(1, 10, 10, 0)
test__muloti4(10, 1, 10, 0)
test__muloti4(1, 81985529216486895, 81985529216486895, 0)
test__muloti4(81985529216486895, 1, 81985529216486895, 0)
test__muloti4(1, -1, -1, 0)
test__muloti4(1, -10, -10, 0)
test__muloti4(-10, 1, -10, 0)
test__muloti4(1, -81985529216486895, -81985529216486895, 0)
test__muloti4(-81985529216486895, 1, -81985529216486895, 0)
test__muloti4(3037000499, 3037000499, 9223372030926249001, 0)
test__muloti4(-3037000499, 3037000499, -9223372030926249001, 0)
test__muloti4(3037000499, -3037000499, -9223372030926249001, 0)
test__muloti4(-3037000499, -3037000499, 9223372030926249001, 0)
test__muloti4(4398046511103, 2097152, 9223372036852678656, 0)
test__muloti4(-4398046511103, 2097152, -9223372036852678656, 0)
test__muloti4(4398046511103, -2097152, -9223372036852678656, 0)
test__muloti4(-4398046511103, -2097152, 9223372036852678656, 0)
test__muloti4(2097152, 4398046511103, 9223372036852678656, 0)
test__muloti4(-2097152, 4398046511103, -9223372036852678656, 0)
test__muloti4(2097152, -4398046511103, -9223372036852678656, 0)
test__muloti4(-2097152, -4398046511103, 9223372036852678656, 0)
test__muloti4(make_ti(0x00000000000000B5, 0x04F333F9DE5BE000),
make_ti(0x0000000000000000, 0x00B504F333F9DE5B),
make_ti(0x7FFFFFFFFFFFF328, 0xDF915DA296E8A000), 0)
test__muloti4(make_ti(0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF),
-2,
make_ti(0x8000000000000000, 0x0000000000000001), 1)
test__muloti4(-2,
make_ti(0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF),
make_ti(0x8000000000000000, 0x0000000000000001), 1)
test__muloti4(make_ti(0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF),
-1,
make_ti(0x8000000000000000, 0x0000000000000001), 0)
test__muloti4(-1,
make_ti(0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF),
make_ti(0x8000000000000000, 0x0000000000000001), 0)
test__muloti4(make_ti(0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF),
0,
0, 0)
test__muloti4(0,
make_ti(0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF),
0, 0)
test__muloti4(make_ti(0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF),
1,
make_ti(0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 0)
test__muloti4(1,
make_ti(0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF),
make_ti(0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 0)
test__muloti4(make_ti(0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF),
2,
make_ti(0x8000000000000000, 0x0000000000000001), 1)
test__muloti4(2,
make_ti(0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF),
make_ti(0x8000000000000000, 0x0000000000000001), 1)
test__muloti4(make_ti(0x8000000000000000, 0x0000000000000000),
-2,
make_ti(0x8000000000000000, 0x0000000000000000), 1)
test__muloti4(-2,
make_ti(0x8000000000000000, 0x0000000000000000),
make_ti(0x8000000000000000, 0x0000000000000000), 1)
test__muloti4(make_ti(0x8000000000000000, 0x0000000000000000),
-1,
make_ti(0x8000000000000000, 0x0000000000000000), 1)
test__muloti4(-1,
make_ti(0x8000000000000000, 0x0000000000000000),
make_ti(0x8000000000000000, 0x0000000000000000), 1)
test__muloti4(make_ti(0x8000000000000000, 0x0000000000000000),
0,
0, 0)
test__muloti4(0,
make_ti(0x8000000000000000, 0x0000000000000000),
0, 0)
test__muloti4(make_ti(0x8000000000000000, 0x0000000000000000),
1,
make_ti(0x8000000000000000, 0x0000000000000000), 0)
test__muloti4(1,
make_ti(0x8000000000000000, 0x0000000000000000),
make_ti(0x8000000000000000, 0x0000000000000000), 0)
test__muloti4(make_ti(0x8000000000000000, 0x0000000000000000),
2,
make_ti(0x8000000000000000, 0x0000000000000000), 1)
test__muloti4(2,
make_ti(0x8000000000000000, 0x0000000000000000),
make_ti(0x8000000000000000, 0x0000000000000000), 1)
test__muloti4(make_ti(0x8000000000000000, 0x0000000000000001),
-2,
make_ti(0x8000000000000000, 0x0000000000000001), 1)
test__muloti4(-2,
make_ti(0x8000000000000000, 0x0000000000000001),
make_ti(0x8000000000000000, 0x0000000000000001), 1)
test__muloti4(make_ti(0x8000000000000000, 0x0000000000000001),
-1,
make_ti(0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 0)
test__muloti4(-1,
make_ti(0x8000000000000000, 0x0000000000000001),
make_ti(0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF), 0)
test__muloti4(make_ti(0x8000000000000000, 0x0000000000000001),
0,
0, 0)
test__muloti4(0,
make_ti(0x8000000000000000, 0x0000000000000001),
0, 0)
test__muloti4(make_ti(0x8000000000000000, 0x0000000000000001),
1,
make_ti(0x8000000000000000, 0x0000000000000001), 0)
test__muloti4(1,
make_ti(0x8000000000000000, 0x0000000000000001),
make_ti(0x8000000000000000, 0x0000000000000001), 0)
test__muloti4(make_ti(0x8000000000000000, 0x0000000000000001),
2,
make_ti(0x8000000000000000, 0x0000000000000000), 1)
test__muloti4(2,
make_ti(0x8000000000000000, 0x0000000000000001),
make_ti(0x8000000000000000, 0x0000000000000000), 1)
end
Loading

0 comments on commit ae915ae

Please sign in to comment.