rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.27k stars 12.58k forks source link

extern-fn-explicit-align fails on ppc64le #122767

Closed nikic closed 5 months ago

nikic commented 6 months ago

The test fails with assertion:

test: test.c:80: many_args: Assertion `h.a == 1' failed.

This is the case at least on 1.76 and 1.77, haven't checked other versions. cc @cuviper

Full error:

``` ---- [run-make] tests/run-make/extern-fn-explicit-align stdout ---- error: make failed status: exit status: 2 command: cd "/builddir/build/BUILD/rustc-1.76.0-src/tests/run-make/extern-fn-explicit-align" && env -u CARGO_MAKEFLAGS -u MAKEFLAGS -u MFLAGS -u RUSTFLAGS AR="/usr/bin/ar" CC="gcc -ffunction-sections -fdata-sections -fPIC -m64 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection" CXX="g++ -ffunction-sections -fdata-sections -fPIC -m64 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection" HOST_RPATH_DIR="/builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/stage2/lib" LD_LIB_PATH_ENVVAR="LD_LIBRARY_PATH" LLVM_BIN_DIR="/usr/bin" LLVM_COMPONENTS="aarch64 aarch64asmparser aarch64codegen aarch64desc aarch64disassembler aarch64info aarch64utils aggressiveinstcombine all all-targets amdgpu amdgpuasmparser amdgpucodegen amdgpudesc amdgpudisassembler amdgpuinfo amdgputargetmca amdgpuutils analysis arm armasmparser armcodegen armdesc armdisassembler arminfo armutils asmparser asmprinter avr avrasmparser avrcodegen avrdesc avrdisassembler avrinfo binaryformat bitreader bitstreamreader bitwriter bpf bpfasmparser bpfcodegen bpfdesc bpfdisassembler bpfinfo cfguard codegen codegentypes core coroutines coverage debuginfobtf debuginfocodeview debuginfodwarf debuginfogsym debuginfologicalview debuginfomsf debuginfopdb demangle dlltooldriver dwarflinker dwarflinkerparallel dwp engine executionengine extensions filecheck frontendhlsl frontendopenacc frontendopenmp fuzzercli fuzzmutate globalisel hexagon hexagonasmparser hexagoncodegen hexagondesc hexagondisassembler hexagoninfo instcombine instrumentation interfacestub interpreter ipo irprinter irreader jitlink lanai lanaiasmparser lanaicodegen lanaidesc lanaidisassembler lanaiinfo libdriver lineeditor linker loongarch loongarchasmparser loongarchcodegen loongarchdesc loongarchdisassembler loongarchinfo lto mc mca mcdisassembler mcjit mcparser mips mipsasmparser mipscodegen mipsdesc mipsdisassembler mipsinfo mirparser msp430 msp430asmparser msp430codegen msp430desc msp430disassembler msp430info native nativecodegen nvptx nvptxcodegen nvptxdesc nvptxinfo objcarcopts objcopy object objectyaml option orcjit orcshared orctargetprocess passes perfjitevents powerpc powerpcasmparser powerpccodegen powerpcdesc powerpcdisassembler powerpcinfo profiledata remarks riscv riscvasmparser riscvcodegen riscvdesc riscvdisassembler riscvinfo riscvtargetmca runtimedyld scalaropts selectiondag sparc sparcasmparser sparccodegen sparcdesc sparcdisassembler sparcinfo support symbolize systemz systemzasmparser systemzcodegen systemzdesc systemzdisassembler systemzinfo tablegen target targetparser textapi transformutils ve veasmparser vecodegen vectorize vedesc vedisassembler veinfo webassembly webassemblyasmparser webassemblycodegen webassemblydesc webassemblydisassembler webassemblyinfo webassemblyutils windowsdriver windowsmanifest x86 x86asmparser x86codegen x86desc x86disassembler x86info x86targetmca xcore xcorecodegen xcoredesc xcoredisassembler xcoreinfo xray" LLVM_FILECHECK="/usr/bin/FileCheck" PYTHON="/usr/bin/python3" RUSTC="/builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/stage2/bin/rustc" RUSTC_LINKER="gcc" RUSTDOC="/builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/stage2/bin/rustdoc" RUST_BUILD_STAGE="stage2-powerpc64le-unknown-linux-gnu" S="/builddir/build/BUILD/rustc-1.76.0-src" TARGET="powerpc64le-unknown-linux-gnu" TARGET_RPATH_DIR="/builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/stage2/lib/rustlib/powerpc64le-unknown-linux-gnu/lib" TMPDIR="/builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/test/run-make/extern-fn-explicit-align/extern-fn-explicit-align" "make" --- stdout ------------------------------- gcc -ffunction-sections -fdata-sections -fPIC -m64 -flto=auto -ffat-lto-objects -fexceptions -g -grecord-gcc-switches -pipe -Wall -Werror=format-security -Wp,-U_FORTIFY_SOURCE,-D_FORTIFY_SOURCE=3 -Wp,-D_GLIBCXX_ASSERTIONS -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mcpu=power8 -mtune=power8 -fasynchronous-unwind-tables -fstack-clash-protection -v -c -o /builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/test/run-make/extern-fn-explicit-align/extern-fn-explicit-align/libtest.o test.c /usr/bin/ar crus /builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/test/run-make/extern-fn-explicit-align/extern-fn-explicit-align/libtest.a /builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/test/run-make/extern-fn-explicit-align/extern-fn-explicit-align/libtest.o LD_LIBRARY_PATH="/builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/test/run-make/extern-fn-explicit-align/extern-fn-explicit-align:/builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/stage2/lib:/builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/stage0-bootstrap-tools/powerpc64le-unknown-linux-gnu/release/deps:/usr/lib" '/builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/stage2/bin/rustc' --out-dir /builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/test/run-make/extern-fn-explicit-align/extern-fn-explicit-align -L /builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/test/run-make/extern-fn-explicit-align/extern-fn-explicit-align -Ainternal_features -Clinker='gcc' test.rs LD_LIBRARY_PATH="/builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/test/run-make/extern-fn-explicit-align/extern-fn-explicit-align:/builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/stage2/lib/rustlib/powerpc64le-unknown-linux-gnu/lib:/builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/stage0-bootstrap-tools/powerpc64le-unknown-linux-gnu/release/deps:/usr/lib" /builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/test/run-make/extern-fn-explicit-align/extern-fn-explicit-align/test || exit 1 rm /builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/test/run-make/extern-fn-explicit-align/extern-fn-explicit-align/libtest.o ------------------------------------------ --- stderr ------------------------------- Using built-in specs. Reading specs from /usr/lib/rpm/redhat/redhat-hardened-cc1 Reading specs from /usr/lib/rpm/redhat/redhat-annobin-cc1 COLLECT_GCC=gcc OFFLOAD_TARGET_NAMES=nvptx-none OFFLOAD_TARGET_DEFAULT=1 Target: ppc64le-redhat-linux Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,objc,obj-c++,ada,go,m2,lto --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-targets=powerpcle-linux --disable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --enable-libstdcxx-backtrace --with-libstdcxx-zoneinfo=/usr/share/zoneinfo --with-linker-hash-style=gnu --enable-plugin --enable-initfini-array --with-isl=/builddir/build/BUILD/gcc-14.0.1-20240127/obj-ppc64le-redhat-linux/isl-install --enable-offload-targets=nvptx-none --enable-offload-defaulted --without-cuda-driver --enable-gnu-indirect-function --enable-secureplt --with-long-double-128 --with-long-double-format=ieee --with-cpu-32=power8 --with-tune-32=power8 --with-cpu-64=power8 --with-tune-64=power8 --build=ppc64le-redhat-linux --with-build-config=bootstrap-lto --enable-link-serialization=1 Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 14.0.1 20240127 (Red Hat 14.0.1-0) (GCC) COLLECT_GCC_OPTIONS='-ffunction-sections' '-fdata-sections' '-fPIC' '-flto=auto' '-ffat-lto-objects' '-fexceptions' '-g' '-grecord-gcc-switches' '-pipe' '-Wall' '-Werror=format-security' '-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1' '-fstack-protector-strong' '-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1' '-m64' '-mcpu=power8' '-mtune=power8' '-fasynchronous-unwind-tables' '-fstack-clash-protection' '-v' '-c' '-o' '/builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/test/run-make/extern-fn-explicit-align/extern-fn-explicit-align/libtest.o' '-dumpdir' '/builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/test/run-make/extern-fn-explicit-align/extern-fn-explicit-align/' /usr/libexec/gcc/ppc64le-redhat-linux/14/cc1 -quiet -v -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 -D_GLIBCXX_ASSERTIONS test.c -msecure-plt -quiet -dumpdir /builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/test/run-make/extern-fn-explicit-align/extern-fn-explicit-align/ -dumpbase libtest.c -dumpbase-ext .c -m64 -mcpu=power8 -mtune=power8 -g -grecord-gcc-switches -Wall -Werror=format-security -version -ffunction-sections -fdata-sections -fPIC -flto=auto -ffat-lto-objects -fexceptions -fstack-protector-strong -fasynchronous-unwind-tables -fstack-clash-protection -iplugindir=/usr/lib/gcc/ppc64le-redhat-linux/14/plugin -fplugin=gcc-annobin -o - | as -v -a64 -mpower8 -many -mlittle -o /builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/test/run-make/extern-fn-explicit-align/extern-fn-explicit-align/libtest.o GNU C17 (GCC) version 14.0.1 20240127 (Red Hat 14.0.1-0) (ppc64le-redhat-linux) compiled by GNU C version 14.0.1 20240127 (Red Hat 14.0.1-0), GMP version 6.2.1, MPFR version 4.2.1, MPC version 1.3.1, isl version isl-0.24-GMP GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Versions of loaded plugins: gcc-annobin: Version 12.38 ignoring nonexistent directory "/usr/lib/gcc/ppc64le-redhat-linux/14/include-fixed" ignoring nonexistent directory "/usr/lib/gcc/ppc64le-redhat-linux/14/../../../../ppc64le-redhat-linux/include" #include "..." search starts here: #include <...> search starts here: /usr/lib/gcc/ppc64le-redhat-linux/14/include /usr/local/include /usr/include End of search list. GNU assembler version 2.41 (ppc64le-redhat-linux) using BFD version version 2.41-32.fc40 Compiler executable checksum: 91d9916cac3c9748599357c30e999228 In file included from /usr/include/assert.h:35, from test.c:1: /usr/include/features.h:414:4: warning: #warning _FORTIFY_SOURCE requires compiling with optimization (-O) [-Wcpp] 414 | # warning _FORTIFY_SOURCE requires compiling with optimization (-O) | ^~~~~~~ COMPILER_PATH=/usr/libexec/gcc/ppc64le-redhat-linux/14/:/usr/libexec/gcc/ppc64le-redhat-linux/14/:/usr/libexec/gcc/ppc64le-redhat-linux/:/usr/lib/gcc/ppc64le-redhat-linux/14/:/usr/lib/gcc/ppc64le-redhat-linux/ LIBRARY_PATH=/usr/lib/gcc/ppc64le-redhat-linux/14/:/usr/lib/gcc/ppc64le-redhat-linux/14/../../../../lib64/:/lib/../lib64/:/usr/lib/../lib64/:/usr/lib/gcc/ppc64le-redhat-linux/14/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-ffunction-sections' '-fdata-sections' '-fPIC' '-flto=auto' '-ffat-lto-objects' '-fexceptions' '-g' '-grecord-gcc-switches' '-pipe' '-Wall' '-Werror=format-security' '-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1' '-fstack-protector-strong' '-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1' '-m64' '-mcpu=power8' '-mtune=power8' '-fasynchronous-unwind-tables' '-fstack-clash-protection' '-v' '-c' '-o' '/builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/test/run-make/extern-fn-explicit-align/extern-fn-explicit-align/libtest.o' '-dumpdir' '/builddir/build/BUILD/rustc-1.76.0-src/build/powerpc64le-unknown-linux-gnu/test/run-make/extern-fn-explicit-align/extern-fn-explicit-align/libtest.' test: test.c:80: many_args: Assertion `h.a == 1' failed. make: *** [Makefile:6: all] Error 1 ```
nikic commented 6 months ago

Rust: https://rust.godbolt.org/z/z4fsMK7sf Clang (and GCC): https://clang.godbolt.org/z/c3j4h4faP

The struct in question is:

#[repr(C)]
#[repr(align(16))]
pub struct TwoU64s {
    pub a: u64,
    pub b: u64,
}

Rust passes it as [2 x i64], while clang passes it as [1 x i128]. The GCC behavior appears to agree with Clang.

cc @erikdesjardins because I know how much you love ABI bugs related to overaligned structs :P

nikic commented 6 months ago

I think the problem is that Rust hardcodes the use of i64 here: https://github.com/rust-lang/rust/blob/b7dcabe55e3b915ba9488dc374f752404c2c8945/compiler/rustc_target/src/abi/call/powerpc64.rs#L116-L119

While Clang makes it dependent on the ABI alignment: https://github.com/llvm/llvm-project/blob/fe2119a7b08b6e468b2a67768904ea85b1bf0a45/clang/lib/CodeGen/Targets/PPC.cpp#L878-L884

nikic commented 6 months ago

Wow, apparently passing i128 and [1 x i128] has different ABI: https://llvm.godbolt.org/z/beM6j8Yhs

The Rust cast ABI currently assumes that these are the same thing and will always pass a single-element Uniform as a scalar rather than array...