https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117327
Bug ID: 117327
Summary: SPARC miscompile - branch past end of function
Product: gcc
Version: 13.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: brad.moody at oracle dot com
Target Milestone: ---
Created attachment 59468
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=59468&action=edit
Minimized reproducer
Reproducer program test.c:
int printf(const char *restrict, ...);
__attribute__((noinline))
void foo(int *self, int *x) {
printf("foo\n");
if (x) {
while (1) {
++*self;
if (*self == 6) break;
if (*self == 7) __builtin_unreachable();
}
}
}
int main() {
int y = 0;
foo(&y, 0);
}
======================
Steps to reproduce, on a SPARC machine, using gcc 13:
gcc -O1 test.c -o test
./test
The program prints foo repeatedly before segfaulting (I believe due to
overflowing the stack). I've only been able to reproduce the issue on SPARC.
Reproduces with -m32 and -m64. Does not reproduce with -O3, but other less
minimized inputs did show the problem at -O3.
>From examining the resulting assembly, I believe this is a miscompile. The
assembly output:
.file "a.c"
.section ".text"
.section .rodata.str1.8,"aMS",@progbits,1
.align 8
.LLC0:
.asciz "foo"
.section ".text"
.align 4
.global foo
.type foo, #function
.proc 020
foo:
save %sp, -176, %sp
sethi %h44(.LLC0), %o0
or %o0, %m44(.LLC0), %o0
sllx %o0, 12, %o0
call puts, 0
or %o0, %l44(.LLC0), %o0
brz,pn %i1, .LL6
nop
ba,pt %xcc, .LL4
lduw [%i0], %g1
.LL7:
be,a,pn %icc, .LL8
st %g1, [%i0]
.LL4:
add %g1, 1, %g1
cmp %g1, 6
bne,pt %icc, .LL7
cmp %g1, 7
mov 6, %g1
st %g1, [%i0]
.LL8:
return %i7+8
nop
.LL6:
.size foo, .-foo
.align 4
.global main
.type main, #function
.proc 04
main:
save %sp, -192, %sp
st %g0, [%fp+2043]
mov 0, %o1
call foo, 0
add %fp, 2043, %o0
return %i7+8
mov 0, %o0
.size main, .-main
.ident "GCC: (GNU) 13.2.0"
The branch for `if (x)` to .LL6 is off the end of the function - it should be
to .LL8. Removing the call to __builtin_unreachable causes the problem to
disappear.
I don't have any other SPARC gcc installs on hand to test, but I did experiment
with other versions using Compiler Explorer. gcc 12.4, appears to reproduce the
problem at -O1, -O2 and -O3. gcc 14.1 doesn't appear to reproduce the problem
at all, but I think the bug could very well still be present in gcc 14 and just
not manifesting for this specific reproducer program.
======================
Other info:
The OS is Solaris 11.4.74.176.3
gcc -v output:
Using built-in specs.
COLLECT_GCC=gcc
Target: sparcv9-sun-solaris2.11
Configured with:
/builds/11.4-SRU/11.4.72.0.1.176.0/components/gcc13/gcc-13.2.0/configure
--prefix=/usr/gcc/13 --mandir=/usr/gcc/13/share/man --bindir=/usr/gcc/13/bin
--sbindir=/usr/gcc/13/sbin --libdir=/usr/gcc/13/lib
--infodir=/usr/gcc/13/share/info --libexecdir=/usr/gcc/13/lib
--enable-languages=ada,c,c++,fortran,go,objc --enable-shared
--enable-initfini-array --disable-rpath --with-system-zlib
--with-build-config=no --without-gnu-ld --with-ld=/usr/bin/ld --with-gnu-as
--with-as=/usr/gnu/bin/as --disable-bootstrap 'BOOT_CFLAGS=-g -O2'
sparcv9-sun-solaris2.11
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.2.0 (GCC)
COLLECT_GCC_OPTIONS='-v' '-O1' '-c' '-mcpu=v9'
/usr/gcc/13/lib/gcc/sparcv9-sun-solaris2.11/13.2.0/cc1 -quiet -v -D__arch64__
-D__sparcv9 a.c -quiet -dumpbase a.c -dumpbase-ext .c -mcpu=v9 -O1 -version -o
/var/tmp//ccj8.0wb.s
GNU C17 (GCC) version 13.2.0 (sparcv9-sun-solaris2.11)
compiled by GNU C version 13.2.0, GMP version 6.3.0, MPFR version
4.2.1, MPC version 1.3.1, isl version isl-0.26-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/usr/local/include"
ignoring nonexistent directory
"/usr/gcc/13/lib/gcc/sparcv9-sun-solaris2.11/13.2.0/../../../../sparcv9-sun-solaris2.11/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/gcc/13/lib/gcc/sparcv9-sun-solaris2.11/13.2.0/include
/usr/gcc/13/include
/usr/gcc/13/lib/gcc/sparcv9-sun-solaris2.11/13.2.0/include-fixed
/usr/include
End of search list.
Compiler executable checksum: 92a7a4e1db50327821c291fc4325641f
COLLECT_GCC_OPTIONS='-v' '-O1' '-c' '-mcpu=v9'
/usr/gnu/bin/as -v -V -Qy -s -xarch=v9 -64 -no-undeclared-regs -o a.o
/var/tmp//ccj8.0wb.s
GNU assembler version 2.40 (sparcv9-sun-solaris2.11) using BFD version (GNU
Binutils) 2.40
COMPILER_PATH=/usr/gcc/13/lib/gcc/sparcv9-sun-solaris2.11/13.2.0/:/usr/gcc/13/lib/gcc/sparcv9-sun-solaris2.11/13.2.0/:/usr/gcc/13/lib/gcc/sparcv9-sun-solaris2.11/:/usr/gcc/13/lib/gcc/sparcv9-sun-solaris2.11/13.2.0/:/usr/gcc/13/lib/gcc/sparcv9-sun-solaris2.11/:/usr/ccs/bin/
LIBRARY_PATH=/usr/gcc/13/lib/gcc/sparcv9-sun-solaris2.11/13.2.0/:/usr/gcc/13/lib/gcc/sparcv9-sun-solaris2.11/13.2.0/../../../sparcv9/:/lib/sparcv9/:/usr/lib/sparcv9/:/usr/gcc/13/lib/gcc/sparcv9-sun-solaris2.11/13.2.0/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-O1' '-c' '-mcpu=v9'