Skip to content

[powerpc64le] rustc 1.74.0 built by mrustc thinks u128::BITS is 64 #363

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
lnikkila opened this issue May 18, 2025 · 2 comments
Open

[powerpc64le] rustc 1.74.0 built by mrustc thinks u128::BITS is 64 #363

lnikkila opened this issue May 18, 2025 · 2 comments

Comments

@lnikkila
Copy link

lnikkila commented May 18, 2025

First of all, thank you for your work on this monumental project!

I've been attempting to bootstrap rustc 1.74.0 on powerpc64le. I ran into a couple of small issues, will open a separate issue for the other one, which was easy to work around, but this latter one seems fairly mysterious to me.

The first sign is that the mrustc-built rustc fails to build the stdlib:

error[E0308]: mismatched types
    --> /var/tmp/mrustc/rustc-1.74.0-src/vendor/time-0.3.22/src/format_description/well_known/iso8601/adt_hack.rs:94:38
     |
94   |         EncodedConfig::from_be_bytes(bytes)
     |         ---------------------------- ^^^^^ expected an array with a fixed size of 16 elements, found one with 8 elements
     |         |
     |         arguments to this function are incorrect
     |

The related code comes from here, where EncodedConfig is an alias for u128:
https://github.com/time-rs/time/blob/v0.3.22/time/src/format_description/well_known/iso8601/adt_hack.rs#L58

I then wrote this test case, which succeeds with mrustc, but fails with the mrustc-built rustc:

$ cat foo.rs
fn main() {
  assert_eq!(128, u128::BITS);
}
$ ./bin/mrustc -L output-1.74.0/ foo.rs
$ ./foo
$ ./run_rustc/output-1.74.0/prefix-s/bin/rustc foo.rs
$ ./foo
thread 'main' panicked at foo.rs:2:3:
assertion `left == right` failed
  left: 128
 right: 64

u128::BITS comes from here:
https://github.com/rust-lang/rust/blob/1.74.0/library/core/src/num/uint_macros.rs#L59

For the record, swapping out u128::BITS with u128::MAX.count_ones() results in the correct value.

To my novice eyes this seems like some kind of problem with const evaluation, so I enabled MRUSTC_DEBUG='Constant Evaluate', but this output looks alright, assuming 80000000 is big-endian 0x80 = 128:

$ grep -R 'evaluate_constant: <u128>::BITS = ValueRef'
output-1.74.0/rustc-build/libcore.rlib_dbg.txt:Constant Evaluate-     evaluate_constant: <u128>::BITS = ValueRef({0+4}80000000)
output-1.74.0/libcore.rlib_dbg.txt:Constant Evaluate-     evaluate_constant: <u128>::BITS = ValueRef({0+4}80000000)

I'll keep updating this issue once I look into this more.

Build info

I'm building this on GNU Guix with this environment:

guix shell -e '(@ (gnu system) %base-packages)' \
  -e '(map cdr ((@ (guix build-system gnu) standard-packages)))' \
  --container --emulate-fhs --network --pure \
  cmake curl git perl pkg-config python zlib

Lightly edited build-1.74.0.sh:

#!/bin/bash
set -e
export CC=gcc CXX=g++ LLVM_TARGETS=PowerPC MRUSTC_DEBUG='Constant Evaluate' PARLEVEL=64 RUSTC_TARGET=powerpc64le-unknown-linux-gnu
export RUSTC_VERSION=1.74.0 MRUSTC_TARGET_VER=1.74 OUTDIR_SUF=-1.74.0
# Enables use of ccache in mrustc if it's available (i.e. ccache is on PATH)
command -v ccache >/dev/null && export MRUSTC_CCACHE=1
make
make RUSTCSRC
make -f minicargo.mk LIBS $@
make test $@
make local_tests $@

RUSTC_INSTALL_BINDIR=bin make -f minicargo.mk output-1.74.0/rustc $@
./output-1.74.0/rustc --version

LIBGIT2_SYS_USE_PKG_CONFIG=1 make -f minicargo.mk -j ${PARLEVEL:-1} output-1.74.0/cargo $@
./output-1.74.0/cargo --version

#./output-1.74.0/rustc samples/no_core.rs
#./output-1.74.0/rustc samples/1.rs
make -C run_rustc -j ${PARLEVEL:-1} $@

Whatever other diagnostic info I could think of:

$ uname -a
Linux guix 6.12.21-gnu #1 SMP 1 ppc64le GNU/Linux
$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/gnu/store/hfmcgblfdpwghgzr6v9mp7253r51dalj-gcc-11.4.0/libexec/gcc/powerpc64le-unknown-linux-gnu/11.4.0/lto-wrapper
Target: powerpc64le-unknown-linux-gnu
Configured with: 
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 11.4.0 (GCC) 
$ ./bin/mrustc -Z print-cfgs
Setup: V V V
(0.00 s) Setup: DONE
Target Load: V V V
(0.00 s) Target Load: DONE
>rust_compiler=mrustc
>target_abi=llvm
>target_arch=powerpc64
>target_endian=little
>target_env=gnu
>target_family=unix
>target_has_atomic=8
>target_has_atomic=16
>target_has_atomic=32
>target_has_atomic=64
>target_has_atomic=ptr
>target_has_atomic=cas
>target_has_atomic_equal_alignment=8
>target_has_atomic_equal_alignment=16
>target_has_atomic_equal_alignment=32
>target_has_atomic_equal_alignment=64
>target_has_atomic_equal_alignment=ptr
>target_has_atomic_load_store=8
>target_has_atomic_load_store=16
>target_has_atomic_load_store=32
>target_has_atomic_load_store=64
>target_has_atomic_load_store=ptr
>target_os=linux
>target_pointer_width=64
>target_vendor=gnu
>target_vendor=
>linux
>unix
@bjorn3
Copy link
Contributor

bjorn3 commented May 19, 2025

80000000

Isn't this u64::MAX as hex number?

@lnikkila
Copy link
Author

@bjorn3 I thought that too until I looked at the other values which look big-endian, here's a longer snippet:

$ grep -R 'evaluate_constant: <u[0-9]*>::BITS = ValueRef'
output-1.74.0/rustc-build/libcore.rlib_dbg.txt:Constant Evaluate-     evaluate_constant: <u8>::BITS = ValueRef({0+4}08000000)
output-1.74.0/rustc-build/libcore.rlib_dbg.txt:Constant Evaluate-     evaluate_constant: <u16>::BITS = ValueRef({0+4}10000000)
output-1.74.0/rustc-build/libcore.rlib_dbg.txt:Constant Evaluate-     evaluate_constant: <u32>::BITS = ValueRef({0+4}20000000)
output-1.74.0/rustc-build/libcore.rlib_dbg.txt:Constant Evaluate-     evaluate_constant: <u64>::BITS = ValueRef({0+4}40000000)
output-1.74.0/rustc-build/libcore.rlib_dbg.txt:Constant Evaluate-     evaluate_constant: <u128>::BITS = ValueRef({0+4}80000000)
output-1.74.0/libcore.rlib_dbg.txt:Constant Evaluate-     evaluate_constant: <u8>::BITS = ValueRef({0+4}08000000)
output-1.74.0/libcore.rlib_dbg.txt:Constant Evaluate-     evaluate_constant: <u16>::BITS = ValueRef({0+4}10000000)
output-1.74.0/libcore.rlib_dbg.txt:Constant Evaluate-     evaluate_constant: <u32>::BITS = ValueRef({0+4}20000000)
output-1.74.0/libcore.rlib_dbg.txt:Constant Evaluate-     evaluate_constant: <u64>::BITS = ValueRef({0+4}40000000)
output-1.74.0/libcore.rlib_dbg.txt:Constant Evaluate-     evaluate_constant: <u128>::BITS = ValueRef({0+4}80000000)

I believe that comes from here:

void fmt(::std::ostream& os, size_t ofs, size_t len) const override {
assert(ofs <= length);
assert(ofs+len <= length);
for(size_t i = 0; i < len; i ++) {
if(i != 0 && (ofs+i) % 8 == 0)
os << " ";
putb_hex(os, this->data[ofs + i]);
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants