Since discriminants do not support i128 yet, lets just calculate the boundaries within the 64 bits
that are supported. This also avoids an issue with bootstrapping on 32 bit systems due to #38727.
There was a linker error on 32 bit platforms with optimisations turned off,
complaining that there was an undefined reference to "rust_eh_personality",
when compiling the rustc_const_math as stage1 artifact.
Apparently the compiler_builtins crate includes a call to "rust_eh_personality".
If compiled for 64 bits, this call doesn't appear, which explains why the linker
error only happens on 32 bit platforms, and optimisations will get it removed
on 32 bit as well.
There were two origins of the call:
1. A for loop where apparently the compiler wasn't sure
whether next() could panic or not, and therefore generated a landing
pad for the worst case. The minimal reproducible example is "for _ in 0..sr { }".
2. A default impl of uabs where the compiler apparently wasn't sure either
whether iabs() could panic or not. Many thanks to nagisa for
contributing the fix.
This commit also puts extern "C" to the intrinsics, as this is generally a
good thing to do.
* shift so that no panics are generated (otherwise results in linker error)
* no_std as insurance to not get into issues with errors like "cannot satisfy dependencies so `rustc_i128` only shows up once" (pure guessing here, but it doesn't hurt...)
The check inside compiler-rt file int_types.h to #define CRT_HAS_128BIT
looks like:
#if (defined(__LP64__) || defined(__wasm__)) && \
!(defined(__mips__) && defined(__clang__))
#define CRT_HAS_128BIT
#endif
Windows uses LLP64 instead of LP64, so it doesn't ship with the C based
intrinsics.
Also, add libcompiler_builtins to the list of crates that may have platform
specific checks (like the ones we just added).
llvm::LLVMConstIntGetZExtValue doesn't accept values with more than 64 bits.
This fixes an LLVM assertion error when compiling libcore with stage1:
src/llvm/include/llvm/ADT/APInt.h:1336:
uint64_t llvm::APInt::getZExtValue() const:
Assertion `getActiveBits() <= 64 && "Too many bits for uint64_t"' failed.
Fixes rebase fallout, makes code correct in presence of 128-bit constants.
This commit includes manual merge conflict resolution changes from a rebase by @est31.
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).
This commit includes manual merge conflict resolution changes from a rebase by @est31.