Initial implementation of the 128-bit integers #35954

Closed
wants to merge 15 commits into
from

Conversation

Projects
None yet
@nagisa
Contributor

nagisa commented Aug 24, 2016

This commit introduces 128-bit integers. Stage 2 builds and produces a working compiler which understands and correctly handles 128-bit integers.

The general strategy used is to have rustc_i128 module which provides aliases for iu128, equal to iu64 in stage0 and iu128 later. Since nowhere in rustc we rely on large numbers being supported, this strategy is good enough to get past the first bootstrap stages to end up with a fully working 128-bit capable compiler.

This PR contains no compiler-rt implementations yet (will get around implementing anything necessary before landing) and I feel that I didn’t quite catch all the locations where iu64 need to be converted to iu128 in the compiler yet. No effort were made to update the Makefiles (will get around it tomorrow, I hope) or old trans (since it is getting removed soon anyway) either.

During implementation the only really problematic issue which has been discovered is that there seems to be no way to generate debug info for 128-bit discriminants (DIBuilder::createEnumerator takes 64bit value), so I didn’t put much effort into supporting the i128 discriminants at all.

All being said, the stage2 test suite seems to pass on a x86_64 linux machine. I don’t have any means to test any other targets (either virtualised or not) by myself at least till early autumn.

cc #35118

[plugin-breaking-change] due to changes to the AST.

@rust-highfive

This comment has been minimized.

Show comment
Hide comment
@rust-highfive

rust-highfive Aug 24, 2016

Collaborator

r? @arielb1

(rust_highfive has picked a reviewer for you, use r? to override)

Collaborator

rust-highfive commented Aug 24, 2016

r? @arielb1

(rust_highfive has picked a reviewer for you, use r? to override)

src/libserialize/serialize.rs
pub trait Encoder {
type Error;
// Primitive types:
fn emit_nil(&mut self) -> Result<(), Self::Error>;
fn emit_uint(&mut self, v: usize) -> Result<(), Self::Error>;
+ fn emit_u128(&mut self, v: u128) -> Result<(), Self::Error>;

This comment has been minimized.

@eddyb

eddyb Aug 24, 2016

Member

This is scary, but I think since rustc-serialize on crates.io is separate and deriving wasn't changed, it should work?

@eddyb

eddyb Aug 24, 2016

Member

This is scary, but I think since rustc-serialize on crates.io is separate and deriving wasn't changed, it should work?

This comment has been minimized.

@nagisa

nagisa Aug 24, 2016

Contributor

Yeah I guess. I’m more worried about a similar addition to the Hash trait.

@nagisa

nagisa Aug 24, 2016

Contributor

Yeah I guess. I’m more worried about a similar addition to the Hash trait.

src/librbml/leb128.rs
-pub fn write_signed_leb128(out: &mut Vec<u8>, start_position: usize, mut value: i64) -> usize {
- let mut position = start_position;
+pub fn write_signed_leb128(out: &mut Vec<u8>, start_position: usize, value: i128) -> usize {
+ write_unsigned_leb128(out, start_position, value as u128)

This comment has been minimized.

@kennytm

kennytm Aug 24, 2016

Member

Won't this change how signed numbers are serialized? For instance -1 was written as 7f, but now would become ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 03.

@kennytm

kennytm Aug 24, 2016

Member

Won't this change how signed numbers are serialized? For instance -1 was written as 7f, but now would become ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 03.

src/libsyntax/ast.rs
}
}
- pub fn val_to_string(&self, val: i64) -> String {
+ pub fn val_to_string(&self, val: i128) -> String {
// cast to a u64 so we can correctly print INT64_MIN. All integral types
// are parsed as u64, so we wouldn't want to print an extra negative

This comment has been minimized.

@kennytm

kennytm Aug 24, 2016

Member

nit: cast to a u128 so we can correctly print INT128_MIN etc.

@kennytm

kennytm Aug 24, 2016

Member

nit: cast to a u128 so we can correctly print INT128_MIN etc.

+ /// Write a single `u128` into this hasher.
+ #[inline]
+ #[unstable(feature = "i128", issue = "35118")]
+ fn write_u128(&mut self, i: u128) {

This comment has been minimized.

@nagisa

nagisa Aug 24, 2016

Contributor

cc @rust-lang/libs is an addition like this fine stability wise? Note it adds a default method to a stable trait.

@nagisa

nagisa Aug 24, 2016

Contributor

cc @rust-lang/libs is an addition like this fine stability wise? Note it adds a default method to a stable trait.

This comment has been minimized.

@sfackler

sfackler Aug 24, 2016

Member

It should be fine since there's a default impl, yeah.

@sfackler

sfackler Aug 24, 2016

Member

It should be fine since there's a default impl, yeah.

This comment has been minimized.

@pnkfelix

pnkfelix Sep 23, 2016

Member

Isn't there a pathological scenario where another trait also adds the same method and thus code that imports both traits must now resort to UFCS?

(I don't think it matters that in this case one of the args is the new u128 type, since method resolution won't use the signature argument types )

@pnkfelix

pnkfelix Sep 23, 2016

Member

Isn't there a pathological scenario where another trait also adds the same method and thus code that imports both traits must now resort to UFCS?

(I don't think it matters that in this case one of the args is the new u128 type, since method resolution won't use the signature argument types )

This comment has been minimized.

@aturon

aturon Sep 26, 2016

Member

@pnkfelix Yes, such a scenario exists in theory, but is explicitly allowed by our semver rules (which, in general, permit changes that may require client-side disambiguation).

@aturon

aturon Sep 26, 2016

Member

@pnkfelix Yes, such a scenario exists in theory, but is explicitly allowed by our semver rules (which, in general, permit changes that may require client-side disambiguation).

src/libsyntax/feature_gate.rs
+ (active, never_type, "1.13.0", Some(35121)),
+
+ // The `i128` type
+ (active, i128_type, "1.13.0", Some(35118))

This comment has been minimized.

@nagisa

nagisa Aug 24, 2016

Contributor

Note to self: probably will have to be come 1.14.0 before landing.

@nagisa

nagisa Aug 24, 2016

Contributor

Note to self: probably will have to be come 1.14.0 before landing.

@bors

This comment has been minimized.

Show comment
Hide comment
@bors

bors Aug 25, 2016

Contributor

☔️ The latest upstream changes (presumably #35764) made this pull request unmergeable. Please resolve the merge conflicts.

Contributor

bors commented Aug 25, 2016

☔️ The latest upstream changes (presumably #35764) made this pull request unmergeable. Please resolve the merge conflicts.

@bors

This comment has been minimized.

Show comment
Hide comment
@bors

bors Aug 26, 2016

Contributor

☔️ The latest upstream changes (presumably #35906) made this pull request unmergeable. Please resolve the merge conflicts.

Contributor

bors commented Aug 26, 2016

☔️ The latest upstream changes (presumably #35906) made this pull request unmergeable. Please resolve the merge conflicts.

@bors

This comment has been minimized.

Show comment
Hide comment
@bors

bors Aug 30, 2016

Contributor

☔️ The latest upstream changes (presumably #36066) made this pull request unmergeable. Please resolve the merge conflicts.

Contributor

bors commented Aug 30, 2016

☔️ The latest upstream changes (presumably #36066) made this pull request unmergeable. Please resolve the merge conflicts.

@est31

This comment has been minimized.

Show comment
Hide comment
@est31

est31 Sep 26, 2016

Contributor

Any news on this? It would be really great to have 128 bit integer support.

Contributor

est31 commented Sep 26, 2016

Any news on this? It would be really great to have 128 bit integer support.

@nagisa

This comment has been minimized.

Show comment
Hide comment
@nagisa

nagisa Sep 26, 2016

Contributor

Was waiting on #35021 to land; didn’t notice it had already. May rebase and finish this tomorrow.

Contributor

nagisa commented Sep 26, 2016

Was waiting on #35021 to land; didn’t notice it had already. May rebase and finish this tomorrow.

nagisa added some commits Aug 23, 2016

Such large. Very 128. Much bits.
This commit introduces 128-bit integers. Stage 2 builds and produces a working compiler which
understands and supports 128-bit integers throughout.

The general strategy used is to have rustc_i128 module which provides aliases for iu128, equal to
iu64 in stage9 and iu128 later. Since nowhere in rustc we rely on large numbers being supported,
this strategy is good enough to get past the first bootstrap stages to end up with a fully working
128-bit capable compiler.

In order for this strategy to work, number of locations had to be changed to use associated
max_value/min_value instead of MAX/MIN constants as well as the min_value (or was it max_value?)
had to be changed to use xor instead of shift so both 64-bit and 128-bit based consteval works
(former not necessarily producing the right results in stage1).
Feature gate the 128 bit types
Dangling a carrot in front of a donkey.
Fix LEB128 to work with the stage1
Stage 1 can’t really handle negative 128-bit literals, but an equivalent bit-not is fine
impl Step for iu128
Also fix the leb128 tests
Add a way to retrieve constant value in 128 bits
Fixes rebase fallout, makes code correct in presence of 128-bit constants.
Implement emit_iu128 for json serialiser
Causes ICEs otherwise while trying to dump AST
@durka

This comment has been minimized.

Show comment
Hide comment
@durka

durka Sep 29, 2016

Contributor

Does this affect intrinsics::discriminant_value() and mem::discriminant() if the maximum discriminant size is now iu128? It kinda sucks to make such functions slow-by-default if most computers don't have 128-bit-wide registers and have to emulate it, but maybe that's not an issue.

Contributor

durka commented Sep 29, 2016

Does this affect intrinsics::discriminant_value() and mem::discriminant() if the maximum discriminant size is now iu128? It kinda sucks to make such functions slow-by-default if most computers don't have 128-bit-wide registers and have to emulate it, but maybe that's not an issue.

@nagisa

This comment has been minimized.

Show comment
Hide comment
@nagisa

nagisa Oct 2, 2016

Contributor

Status update: I have some intrinsics ported, but I can’t get the multiplication to work for some reason, I’ll need more time to investigate that.

Does this affect intrinsics::discriminant_value() and mem::discriminant() if the maximum discriminant size is now iu128

Eventually we’ll want to make this happen. In optimised code LLVM should be pretty smart about not using the whole 128 bits when it doesn’t need to. Moreover storage of i128 is not that much slower than storage of i64, so it should be of little concern.

Contributor

nagisa commented Oct 2, 2016

Status update: I have some intrinsics ported, but I can’t get the multiplication to work for some reason, I’ll need more time to investigate that.

Does this affect intrinsics::discriminant_value() and mem::discriminant() if the maximum discriminant size is now iu128

Eventually we’ll want to make this happen. In optimised code LLVM should be pretty smart about not using the whole 128 bits when it doesn’t need to. Moreover storage of i128 is not that much slower than storage of i64, so it should be of little concern.

@jdub jdub referenced this pull request in jameysharp/corrode Oct 4, 2016

Open

implement int128 #74

@alexcrichton

This comment has been minimized.

Show comment
Hide comment
@alexcrichton

alexcrichton Oct 31, 2016

Member

ping @nagisa, any update on this?

Member

alexcrichton commented Oct 31, 2016

ping @nagisa, any update on this?

cmr added a commit to cmr/rust-crypto that referenced this pull request Nov 6, 2016

[WIP] hs1: use u128 instead of BigInt
With a better algorithm (based on Horner's Method, as recommended
by Ted Krovetz), a bigint isn't necessary, just 64-64 multiplication.
This addresses the XXX_QUESTION around NH and Hash.

Further efficiency is gained by avoiding a physical modulo operation,
instead using the identity (a % (2^61 - 1)) = (a >> 61) + (a & (2^61 -1)),
and borrow's from Ted's reference implementation.

This pulls in the extprim crate as an interim measure until
rust-lang/rust#35954 is released, which
provides native 128-bit words.

@est31 est31 referenced this pull request Nov 20, 2016

Closed

i128 and u128 support #37900

2 of 2 tasks complete
@nagisa

This comment has been minimized.

Show comment
Hide comment
@nagisa

nagisa Nov 21, 2016

Contributor

@est31 is working on finishing this in the issue referenced above.

Contributor

nagisa commented Nov 21, 2016

@est31 is working on finishing this in the issue referenced above.

@nagisa nagisa closed this Nov 21, 2016

bors added a commit that referenced this pull request Dec 4, 2016

Auto merge of #37900 - est31:i128, r=eddyb
i128 and u128 support

Adds support for 128-bit integers. Rebased version of #35954 , with additional improvements.

Thanks @nagisa for mentoring this PR!

Some of the problems that were resolved:

* [x] Confirm that intrinsics work on 32 bit platforms and fix them if needed

* Wait for #37906 to get fixed, so that work on intrinsics can be completed *(worked around by merging the PR on my local setup)*

* [x] Investigate and fix linkcheck failure

[plugin-breaking-change]

cc #35118

bors added a commit that referenced this pull request Dec 4, 2016

Auto merge of #37900 - est31:i128, r=eddyb
i128 and u128 support

Adds support for 128-bit integers. Rebased version of #35954 , with additional improvements.

Thanks @nagisa for mentoring this PR!

Some of the problems that were resolved:

* [x] Confirm that intrinsics work on 32 bit platforms and fix them if needed

* Wait for #37906 to get fixed, so that work on intrinsics can be completed *(worked around by merging the PR on my local setup)*

* [x] Investigate and fix linkcheck failure

[plugin-breaking-change]

cc #35118

bors added a commit that referenced this pull request Dec 4, 2016

Auto merge of #37900 - est31:i128, r=eddyb
i128 and u128 support

Adds support for 128-bit integers. Rebased version of #35954 , with additional improvements.

Thanks @nagisa for mentoring this PR!

Some of the problems that were resolved:

* [x] Confirm that intrinsics work on 32 bit platforms and fix them if needed

* Wait for #37906 to get fixed, so that work on intrinsics can be completed *(worked around by merging the PR on my local setup)*

* [x] Investigate and fix linkcheck failure

[plugin-breaking-change]

cc #35118

bors added a commit that referenced this pull request Dec 4, 2016

Auto merge of #37900 - est31:i128, r=eddyb
i128 and u128 support

Adds support for 128-bit integers. Rebased version of #35954 , with additional improvements.

Thanks @nagisa for mentoring this PR!

Some of the problems that were resolved:

* [x] Confirm that intrinsics work on 32 bit platforms and fix them if needed

* Wait for #37906 to get fixed, so that work on intrinsics can be completed *(worked around by merging the PR on my local setup)*

* [x] Investigate and fix linkcheck failure

[plugin-breaking-change]

cc #35118

bors added a commit that referenced this pull request Dec 8, 2016

Auto merge of #37900 - est31:i128, r=eddyb
i128 and u128 support

Adds support for 128-bit integers. Rebased version of #35954 , with additional improvements.

Thanks @nagisa for mentoring this PR!

Some of the problems that were resolved:

* [x] Confirm that intrinsics work on 32 bit platforms and fix them if needed

* Wait for #37906 to get fixed, so that work on intrinsics can be completed *(worked around by merging the PR on my local setup)*

* [x] Investigate and fix linkcheck failure

[plugin-breaking-change]

cc #35118

bors added a commit that referenced this pull request Dec 8, 2016

Auto merge of #37900 - est31:i128, r=eddyb
i128 and u128 support

Adds support for 128-bit integers. Rebased version of #35954 , with additional improvements.

Thanks @nagisa for mentoring this PR!

Some of the problems that were resolved:

* [x] Confirm that intrinsics work on 32 bit platforms and fix them if needed

* Wait for #37906 to get fixed, so that work on intrinsics can be completed *(worked around by merging the PR on my local setup)*

* [x] Investigate and fix linkcheck failure

[plugin-breaking-change]

cc #35118

bors added a commit that referenced this pull request Dec 8, 2016

Auto merge of #37900 - est31:i128, r=eddyb
i128 and u128 support

Adds support for 128-bit integers. Rebased version of #35954 , with additional improvements.

Thanks @nagisa for mentoring this PR!

Some of the problems that were resolved:

* [x] Confirm that intrinsics work on 32 bit platforms and fix them if needed

* Wait for #37906 to get fixed, so that work on intrinsics can be completed *(worked around by merging the PR on my local setup)*

* [x] Investigate and fix linkcheck failure

[plugin-breaking-change]

cc #35118

bors added a commit that referenced this pull request Dec 14, 2016

Auto merge of #37900 - est31:i128, r=eddyb
i128 and u128 support

Adds support for 128-bit integers. Rebased version of #35954 , with additional improvements.

Thanks @nagisa for mentoring this PR!

Some of the problems that were resolved:

* [x] Confirm that intrinsics work on 32 bit platforms and fix them if needed

* Wait for #37906 to get fixed, so that work on intrinsics can be completed *(worked around by merging the PR on my local setup)*

* [x] Investigate and fix linkcheck failure

[plugin-breaking-change]

cc #35118

@est31 est31 referenced this pull request Dec 20, 2016

Merged

i128 and u128 support #38482

bors added a commit that referenced this pull request Dec 20, 2016

Auto merge of #38482 - est31:i128, r=eddyb
i128 and u128 support

Brings i128 and u128 support to nightly rust, behind a feature flag. The goal of this PR is to do the bulk of the work for 128 bit integer support. Smaller but just as tricky features needed for stabilisation like 128 bit enum discriminants are left for future PRs.

Rebased version of  #37900, which in turn was a rebase + improvement of #35954 . Sadly I couldn't reopen #37900 due to github. There goes my premium position in the homu queue...

[plugin-breaking-change]

cc #35118 (tracking issue)

bors added a commit that referenced this pull request Dec 21, 2016

Auto merge of #38482 - est31:i128, r=eddyb
i128 and u128 support

Brings i128 and u128 support to nightly rust, behind a feature flag. The goal of this PR is to do the bulk of the work for 128 bit integer support. Smaller but just as tricky features needed for stabilisation like 128 bit enum discriminants are left for future PRs.

Rebased version of  #37900, which in turn was a rebase + improvement of #35954 . Sadly I couldn't reopen #37900 due to github. There goes my premium position in the homu queue...

[plugin-breaking-change]

cc #35118 (tracking issue)

bors added a commit that referenced this pull request Dec 21, 2016

Auto merge of #38482 - est31:i128, r=eddyb
i128 and u128 support

Brings i128 and u128 support to nightly rust, behind a feature flag. The goal of this PR is to do the bulk of the work for 128 bit integer support. Smaller but just as tricky features needed for stabilisation like 128 bit enum discriminants are left for future PRs.

Rebased version of  #37900, which in turn was a rebase + improvement of #35954 . Sadly I couldn't reopen #37900 due to github. There goes my premium position in the homu queue...

[plugin-breaking-change]

cc #35118 (tracking issue)

bors added a commit that referenced this pull request Dec 30, 2016

Auto merge of #38482 - est31:i128, r=eddyb
i128 and u128 support

Brings i128 and u128 support to nightly rust, behind a feature flag. The goal of this PR is to do the bulk of the work for 128 bit integer support. Smaller but just as tricky features needed for stabilisation like 128 bit enum discriminants are left for future PRs.

Rebased version of  #37900, which in turn was a rebase + improvement of #35954 . Sadly I couldn't reopen #37900 due to github. There goes my premium position in the homu queue...

[plugin-breaking-change]

cc #35118 (tracking issue)

bors added a commit that referenced this pull request Dec 30, 2016

Auto merge of #38482 - est31:i128, r=eddyb
i128 and u128 support

Brings i128 and u128 support to nightly rust, behind a feature flag. The goal of this PR is to do the bulk of the work for 128 bit integer support. Smaller but just as tricky features needed for stabilisation like 128 bit enum discriminants are left for future PRs.

Rebased version of  #37900, which in turn was a rebase + improvement of #35954 . Sadly I couldn't reopen #37900 due to github. There goes my premium position in the homu queue...

[plugin-breaking-change]

cc #35118 (tracking issue)

bors added a commit that referenced this pull request Dec 31, 2016

Auto merge of #38482 - est31:i128, r=eddyb
i128 and u128 support

Brings i128 and u128 support to nightly rust, behind a feature flag. The goal of this PR is to do the bulk of the work for 128 bit integer support. Smaller but just as tricky features needed for stabilisation like 128 bit enum discriminants are left for future PRs.

Rebased version of  #37900, which in turn was a rebase + improvement of #35954 . Sadly I couldn't reopen #37900 due to github. There goes my premium position in the homu queue...

[plugin-breaking-change]

cc #35118 (tracking issue)

bors added a commit that referenced this pull request Dec 31, 2016

Auto merge of #38482 - est31:i128, r=eddyb
i128 and u128 support

Brings i128 and u128 support to nightly rust, behind a feature flag. The goal of this PR is to do the bulk of the work for 128 bit integer support. Smaller but just as tricky features needed for stabilisation like 128 bit enum discriminants are left for future PRs.

Rebased version of  #37900, which in turn was a rebase + improvement of #35954 . Sadly I couldn't reopen #37900 due to github. There goes my premium position in the homu queue...

[plugin-breaking-change]

cc #35118 (tracking issue)

bors added a commit that referenced this pull request Dec 31, 2016

Auto merge of #38482 - est31:i128, r=eddyb
i128 and u128 support

Brings i128 and u128 support to nightly rust, behind a feature flag. The goal of this PR is to do the bulk of the work for 128 bit integer support. Smaller but just as tricky features needed for stabilisation like 128 bit enum discriminants are left for future PRs.

Rebased version of  #37900, which in turn was a rebase + improvement of #35954 . Sadly I couldn't reopen #37900 due to github. There goes my premium position in the homu queue...

[plugin-breaking-change]

cc #35118 (tracking issue)

@harpocrates harpocrates referenced this pull request in harpocrates/language-rust Jan 16, 2017

Closed

Add support for 128-bit integers #8

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment