| Summary: | aarch64-alt-linux-gcc-10 produces incorrect code (caught by strace test suite) | ||
|---|---|---|---|
| Product: | Sisyphus | Reporter: | Dmitry V. Levin <ldv> |
| Component: | gcc10 | Assignee: | Gleb F-Malinovskiy <glebfm> |
| Status: | CLOSED FIXED | QA Contact: | qa-sisyphus |
| Severity: | major | ||
| Priority: | P5 | CC: | glebfm, ldv |
| Version: | unstable | ||
| Hardware: | aarch64 | ||
| OS: | Linux | ||
| URL: | https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98853 | ||
Further simplified example:
$ cat a.c
#include <stdio.h>
int main(void)
{
const unsigned long in = (unsigned long) main;
unsigned int val = (in & 0xffU) | ((in >> 8) & 0xffffff00U);
printf("%#lx %#lx\n", in, (unsigned long) val);
return 0;
}
$ gcc -Wall -Werror a.c && ./a.out
0xaaaab463d794 0xaab46394
$ gcc -Wall -Werror -O1 a.c && ./a.out
0xaaaabd4cb794 0xaaaabd4c94
$ gcc -Wall -Werror -O2 a.c && ./a.out
0xaaaace920680 0xaaaace9280
The last example:
$ cat a.c
__attribute__((noipa)) unsigned long f(unsigned long x)
{
return (unsigned int) ((x & 0xffU) | ((x >> 8) & 0xffffff00U));
}
int main(void)
{
unsigned long v = f(-1UL);
if (v != (unsigned int) v) __builtin_abort();
return 0;
}
$ for i in 0 1 s 2; do printf '%s ' "-O$i" && gcc -Wall -Werror -O$i a.c && ./a.out && echo OK; done
-O0 OK
-O1 Aborted
-Os Aborted
-O2 Aborted
gcc10-10.2.1-alt3 -> sisyphus: Mon Mar 15 2021 Gleb F-Malinovskiy <glebfm@altlinux> 10.2.1-alt3 - Updated to merged branches from git://gcc.gnu.org/git/gcc.git (ALT#39798): + vendors/redhat/heads/gcc-10-branch commit 966e4575ccd8b618811b4871e44c31bb2d11a82a; + origin/releases/gcc-10 commit a07015ad4dc18a1167720aece205deca702a1ab1. - gcc10-plugin-devel: added R: libgmp-devel. |
aarch64-alt-linux-gcc-10 from gcc10-10.2.1-alt2.aarch64 miscompiles the following innocent example (a simplification of strace/src/print_dev_t.c): $ cat arm64.c #define _GNU_SOURCE #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <sys/sysmacros.h> int main(int ac, const char **av) { assert(ac == 2); const unsigned long long dev = strtoull(av[1], 0, 0); const unsigned long dev_major = major(dev); printf("%#lx\n", dev_major); const unsigned long dev_minor = minor(dev); printf("%#lx\n", dev_minor); return 0; } $ aarch64-alt-linux-gcc-10 -Wall -Werror -O2 arm64.c $ ./a.out 0x123456789abcdef0 0x12345cde 0x123456789abf0 Also reproducible with "gcc (GCC) 10.2.1 20201125 (Red Hat 10.2.1-9)" from f33, apparently fixed in "gcc (GCC) 11.0.0 20210210 (Red Hat 11.0.0-0)" from f34.