I am trying to build GMP 6.1.2 for ARMv8-A Thunderx2t99 (AARCH64) CPU on RHEL7.4-ARM64.
I can build BINUTILS 2.29.1, GMP 6.1.2, and CC 7.2.0 using the system GCC 4.8.5 (provided by RHEL7.4-ARM64). No errors, GMP passes its make check
tests. The gen-fac program works.
Now I use my GCC 7.2.0 to build everything again. GMP fails with an assertion error before it gets very far into its build process.
During the GMP build process it builds a few programs, “gen-fac” being one of them. This is the exact command the Makefile executes: “custom_toolchain/bin/gcc -v `test -f 'gen-fac.c' || echo './'`gen-fac.c -o gen-fac”
It then tries to execute: “./gen-fac 64 0” which hits an assertion error if built using my GCC 7.2.0: gen-fac: mini-gmp/mini-gmp.c:1207: mpn_limb_size_in_base_2: Assertion `u > 0' failed. /bin/sh: line 1: 9766 Aborted (core dumped) ./gen-fac 64 0 > fac_table.h
In this case u
is exactly 0.
I think I was able to narrow down the cause. In GCC 7.2.0 the GMP_LLIMB_MASK is coming out wrong. So I wrote a tiny test program to show case this (the DEFINE's are copy and pasted from GMP/mini-gmp.h):
#include <stdio.h>
#define GMP_LIMB_BITS 64
#define GMP_HLIMB_BIT ((unsigned long) 1 << (GMP_LIMB_BITS / 2))
#define GMP_LLIMB_MASK (GMP_HLIMB_BIT - 1)
int main()
{
printf("GMP_HLIMB_BIT=%lu=%lx\n", GMP_HLIMB_BIT, GMP_HLIMB_BIT);
printf("GMP_LLIMB_MASK=%lu=%lx\n", GMP_LLIMB_MASK, GMP_LLIMB_MASK);
}
Output
== GCC 4.8.5 ==
GMP_HLIMB_BIT=4294967296=100000000
GMP_LLIMB_MASK=4294967295=ffffffff
== GCC 7.2.0 ==
GMP_HLIMB_BIT=4294967296=100000000
GMP_LLIMB_MASK=4294967297=100000001
This leads me to believe I am building GCC 7.2.0 wrong or GMP 6.1.2 wrong. At least the handling of long's seem different between the GCC's.
Here is how I configure GCC:
"$GCC/configure" \
--prefix="$1" \
--with-local-prefix="$1" \
--enable-clocale=gnu \
--enable-languages=c,c++,fortran \
--with-gmp="$1" \
--with-mpfr="$1" \
--with-mpc="$1" \
--with-isl="$1" \
--enable-tls \
--enable-threads=posix \
--enable-lto \
--with-ld="$1/bin/ld" \
--with-as="$1/bin/as" \
--with-system-zlib \
--disable-nls \
--disable-libstdcxx-pch \
--disable-multilib \
--enable-compressed-debug-sections=all \
--build="$MACHINE_TARGET" \
--host="$MACHINE_TARGET" \
--target="$MACHINE_TARGET"
Here is how I configure GMP (MACHINE_ABI=64 in this case):
ABI="${MACHINE_ABI}" \
./configure \
--prefix="${1}" \
--disable-static \
--without-readline
Can anyone shed any light on what is happening here?
I am confident that I am building GCC 7.2.0 wrong (somehow, all my other libraries work but GMP is quite unique) or that I've hit a bug in GMP on ARM64 architectures.
Any thoughts on what I can try next?
Important note
GCC 4.8.5=GMP_LLIMB_MASK=4294967295=ffffffff
GCC 7.2.0=GMP_LLIMB_MASK=4294967297=100000001
Notice the mask has an extra bit in GCC 7.2.0. Clearly the handling of longs is different between the two GCC's. How can I test/verify this?
Update
Forcing the LLIMB_MASK to be 0xffffffff causes GMP to fail, but differently. The gen-fac program just goes into an infinite loop. I also tried 0xffffffff00000000 which fails.
Assembly View
Compiling the code in question with -S
to view the assembly. The only stand out difference I can see is:
GCC 4.8.5 claims .cpu generic+fp+simd
GCC 7.2.0 claims .arch armv8-a
Final Note
Using a prebuilt GCC 7.2.0 for AARCH64 does not cause this behavior. So I think that definitively points to a poorly built GCC. Any tips where to begin exploring the differences?