riscv-collab / riscv-gcc Goto Github PK
View Code? Open in Web Editor NEWLicense: GNU General Public License v2.0
License: GNU General Public License v2.0
This directory contains the GNU Compiler Collection (GCC). The GNU Compiler Collection is free software. See the files whose names start with COPYING for copying permission. The manuals, and some of the runtime libraries, are under different terms; see the individual source files for details. The directory INSTALL contains copies of the installation information as HTML and plain text. The source of this information is gcc/doc/install.texi. The installation information includes details of what is included in the GCC sources and what files GCC installs. See the file gcc/doc/gcc.texi (together with other files that it includes) for usage and porting information. An online readable version of the manual is in the files gcc/doc/gcc.info*. See http://gcc.gnu.org/bugs/ for how to report bugs usefully. Copyright years on GCC source files may be listed using range notation, e.g., 1987-2012, indicating that every year in the range, inclusive, is a copyrightable year that could otherwise be listed individually.
Matthew point out some issue in the mov[qi|hi|si|di] pattern for FPR <-> GPR in bug 79912[1], because riscv_hard_regno_mode_ok_p is say FPR is not ok for MODE_INT and here is alternative for FPR <-> GPR in our integer move pattern.
There is two solution for this problem:
See here: https://cx.rv8.io/g/JtEZL6
template <typename T, unsigned B>
inline T signextend(const T x)
{
struct {T x:B;} s;
return s.x = x;
}
int sx5(int x) {
return signextend<signed int,5>(x);
}
expands to
sx5(int):
slliw a0,a0,3
slliw a0,a0,24
sraiw a0,a0,24
sraiw a0,a0,3
but really should be:
sx5(int):
slliw a0,a0,27
sraiw a0,a0,27
should probably be raised as a bug on upstream gcc as it affects x86. It's shifting by 24 then by 3. There must be some target independent logic that splits shifts for bitfield accesses. We can link to this bug in an email, and the gcc developers can raise an upstream bug, if they believe it is a bug, so we can get a fix into a point release.
sx5(int):
lea eax, [0+rdi*8]
sar al, 3
movsx eax, al
ret
I was testing out a new clz function derived from the GNU MP Library's highly optimized clz. It has some nice properties compared to gcc's __builtin_clz. Both of them are table based however the gcc version uses a larger table. During the process I discovered a puzzling gcc 7.1.0 bug. It is puzzling because it only occurs on RISC-V and it only occurs when calling __builtin_clz in a loop.
Despite the odd gcc bug, take a look at the asm output of the GNU MP clz function, with RISC-V custom asm; and compare to __clzdi2
. GNU MP has lots of platform specific inline assembly for performance. I think gcc's __builtin_clz (__clzdi2) is broken in this case:
I tried to make a reproducer outside of a loop and the bug does not occur:
$ cat clz7.c
#include <assert.h>
int main()
{
assert (__builtin_clz(2) == 30);
}
$ riscv64-linux-musl-gcc -fwrapv -O3 -static clz7.c
$ qemu-riscv64 a.out
The program runs to completion on x86-64
$ x86_64-linux-musl-gcc -fwrapv -O3 -static clz6.c
$ ./a.out
However __builtin_clz returns incorrect values when called in a loop (29 is returned where x == 2).
$ riscv64-linux-musl-gcc -fwrapv -O3 -static clz6.c
$ qemu-riscv64 a.out
1 31 31
2 29 30
Assertion failed: __builtin_clz(x) == clz6(x) (clz6.c: main: 50)
Aborted
Here is the test program (note: the printf is only enabled on riscv, and the inline asm version of the new function is likely correct, rather it is __builtin_clz that is returning erroneous values):
$ cat clz6.c
/* clz implementation derived from GNU MP Library longlong.h */
#include <stdio.h>
#include <assert.h>
const
unsigned char __clz_tab[129] =
{
1,2,3,3,4,4,4,4,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
9
};
#if defined (__riscv)
int clz6(unsigned x)
{
unsigned shamt;
__asm__(
"li t0,0x1000000\n\t"
"sltu t0,%1,t0\n\t"
"neg %0,t0\n\t"
"li t0,0x10000\n\t"
"sltu t0,%1,t0\n\t"
"sub %0,%0,t0\n\t"
"li t0,0x100\n\t"
"sltu t0,%1,t0\n\t"
"sub %0,%0,t0"
: "=&r" (shamt) : "r" (x));
shamt = shamt*8 + 24 + 1;
return 33 - shamt - __clz_tab[x >> shamt];
}
#else
int clz6(unsigned x)
{
unsigned shamt;
shamt = -(x < 0x1000000);
shamt -= (x < 0x10000);
shamt -= (x < 0x100);
shamt = shamt*8 + 24 + 1;
return 33 - shamt - __clz_tab[x >> shamt];
}
#endif
int main()
{
for (int x = 1; x != 0; x++) {
#if defined (__riscv)
printf("%d %d %d\n", x, __builtin_clz(x), clz6(x));
#endif
assert (__builtin_clz(x) == clz6(x));
}
}
-fstack-protector
uses TP-relative access on other arches, which saves a couple instructions versus a variable accessed through the GOT.
-fstack-check
does not appear to have a fallback, and is not operational.
The fsrmi and fsflagsi pseudo-ops defined in the 2.2 RISC-V ISA manual are not recognized by the latest gcc. The register forms of the pseudo-ops compile.
Attempting to compile the following code:
#include <stdio.h>
int main(int argc, char **argv)
{
int rd, rs;
asm volatile("frrm %0" : "=r"(rd));
asm volatile("fsrm %0, %1" : "=r"(rd) : "r"(rs));
asm volatile("fsrm %0" : : "r"(rs));
asm volatile("fsrmi %0, %1" : "=r"(rd) : "i"(0));
asm volatile("fsrmi %0" : : "i"(0));
asm volatile("frflags %0" : "=r"(rd));
asm volatile("fsflags %0, %1" : "=r"(rd) : "r"(rs));
asm volatile("fsflags %0" : : "r"(rs));
asm volatile("fsflagsi %0, %1" : "=r"(rd) : "i"(0));
asm volatile("fsflagsi %0" : : "i"(0));
}
Results in the following errors:
$ riscv64-unknown-elf-gcc -o /tmp/test /tmp/test-pseudo-ops.c
/tmp/test-pseudo-ops.c: Assembler messages:
/tmp/test-pseudo-ops.c:11: Error: unrecognized opcode `fsrmi a5,0'
/tmp/test-pseudo-ops.c:12: Error: unrecognized opcode `fsrmi 0'
/tmp/test-pseudo-ops.c:17: Error: unrecognized opcode `fsflagsi a5,0'
/tmp/test-pseudo-ops.c:18: Error: unrecognized opcode `fsflagsi 0'
$
# cat ailf.c
#include <stdio.h>
int main() {
#define CHECK(size) \
printf("size %d always? %d is? %d\n", size, \
__atomic_always_lock_free(size,(char*)0), \
__atomic_is_lock_free(size,(char*)0));
CHECK(1) CHECK(2) CHECK(4) CHECK(8) CHECK(16) CHECK(32)
return 0;
}
# cc -latomic ailf.c; ./a.out
size 1 always? 0 is? 1
size 2 always? 0 is? 1
size 4 always? 1 is? 1
size 8 always? 1 is? 1
size 16 always? 0 is? 0
size 32 always? 0 is? 0
Since the fallback code is lock-free, we should be getting 1 in the first two cases. This is probably related to not having patterns for size 1/size 2 atomics. (??? is this actually true)
(while factually incorrect, I can't find anything in either the gcc documentation or the C11 final draft which specifically forbids this)
Code which uses __atomic_xxx
builtins or C11 atomics requires to be linked with -latomic
on RISC-V, but not on other common architectures (including but not limited to ARM, x86).
Example code:
unsigned char ach;
int main() {
__atomic_fetch_add(&ach,1,__ATOMIC_RELAXED);
return 0;
}
Testing with the tool at gcc.godbolt.org:
__atomic_fetch_add
Modify gcc to generate a call to __sync_fetch_and_add_1
instead of __atomic_fetch_add_1
, and similarly for other size-1 and size-2 atomics.
Advantages: code size, avoids polluting the libgcc ABI with weirdness
Make libgcc provide a subset of the libatomic names.
Advantages: Probably the easiest in the short term
Disadvantages: Creates an ABI mess that we'll probably regret later, especially for things like compiler-rt (LLVM's compatible reimplementation of libgcc)
As MIPS/MIPS64/PowerPC are already doing.
Advantages: sidesteps ABI issues entirely
--as-needed -latomic
to the spec fileArguably gcc should be doing this on all platforms, _Atomic(char[32])
is in C11 and requiring a non-POSIX -l
flag to use standard C features is quite dodgy.
Disadvantages: Depletes the RISC-V weirdness budget
So far this includes QEMU and the Boehm GC. I haven't analyzed all of the Fedora build failures so it might have caused others.
Disadvantages: Depletes the RISC-V weirdness budget much more since it affects non-compiler software
When I compile the code like this:
.c
extern u32 __text_size;
__attribute__((noinline))
void test(int n1, int n3)
{
asm("nop");
}
AT(.init_text)
int main(void)
{
test(0, (u32)&__text_size);
return 0;
}
.ld:
__text_size= SIZEOF(.comm);
the disassembly listing looks like:
10000012 <main>:
10000012: 6581 lui a1,0x0
10000014: 1171 addi sp,sp,-4
10000016: 4501 li a0,0
10000018: 60000593 li a1,1536
1000001c: c006 sw ra,0(sp)
1000001e: f0020317 auipc t1,0xf0020
10000022: 1a0300e7 jalr 416(t1) # 201be <test>
10000026: 4082 lw ra,0(sp)
10000028: 4501 li a0,0
1000002a: 0111 addi sp,sp,4
1000002c: 8082 ret
Notice the first instruction:
lui a1,0x0
in the RISCV-SPEC:
C.LUI is only valid when rd6={x0 , x2}, and when the immediate is not equal to zero.
So, it's an invalid instruction.
Option: -march=rv32i or -march=rv64i (No M extension)
How to reproduce:
$ gcc div.c
$ ./a.out
-2147483648(0x80000000) 16777216(0x01000000) -128(0xffffff80)
$ riscv32-unknown-linux-gnu-gcc div.c -static
$ qemu-riscv32 a.out
// Hang forever
Code for div.c:
#include <stdio.h>
int div(int a, int b) __attribute__((noinline, noclone));
int div(int a, int b)
{
return a / b;
}
int main()
{
int a = 0x80000000;
int b = 0x1000000;
printf("%d(0x%08x) %d(0x%08x) %d(0x%08x)\n", a, a, b, b, div(a, b), div(a, b));
return 0;
}
Key point I think is there:
/* Handle negative arguments to __divdi3. */
.L10:
neg a0, a0 // neg 0x80000000 = 0x80000000
I'd like to add a command line option to disable divide, but enable divide, along the lines of -mmuldiv.
Could someone point me in the right direction to go about doing this?
The input below (foo.c) causes an internal compiler error when compiled as follows using the v20170503 release of riscv-gnu-toolchain when configured with --with-arch=rv64imafd (note: no "c").
Command line:
$RISCV/bin/riscv64-unknown-elf-gcc -O2 -mcmodel=medany -o /dev/null foo.c
foo.c (minimized from bzip2.c in bzip2):
int x;
struct Z {
char *n;
struct Z *m;
};
void license();
int main() {
struct Z *a;
struct Z *b;
for (b = a; b; b = b->m) {
if (b->n[0] == '-') {
int j;
for (j = 1; b->n[j] != '\0'; j++) {
switch (b->n[j]) {
case '6':
x = 6;
break;
case 'L':
license();
break;
}
}
}
}
}
Hi, I compiled a version riscv-none-gcc and riscv-newlib in riscv-tools support to RV32E.
https://github.com/gnu-mcu-eclipse/riscv-none-gcc/
when i compiled the hello.c. I got errors such like following. what happened. it's something errors in assembler. Would you please give some suggestion to deal with it?
thanks
Dong Tong
riscv32-unknown-elf-gcc hello.c -march=rv32ema
/tmp/ccQtyvD5.s: Assembler messages:
/tmp/ccQtyvD5.s:12: Error: illegal operands addi sp,sp,-8' /tmp/ccQtyvD5.s:13: Error: illegal operandssw ra,4(sp)'
/tmp/ccQtyvD5.s:14: Error: illegal operands sw s0,0(sp)' /tmp/ccQtyvD5.s:15: Error: illegal operandsaddi s0,sp,8'
/tmp/ccQtyvD5.s:16: Error: illegal operands lui a5,%hi(.LC0)' /tmp/ccQtyvD5.s:17: Error: illegal operandsaddi a0,a5,%lo(.LC0)'
/tmp/ccQtyvD5.s:18: Error: unrecognized opcode call puts' /tmp/ccQtyvD5.s:19: Error: illegal operandsli a5,0'
/tmp/ccQtyvD5.s:20: Error: illegal operands mv a0,a5' /tmp/ccQtyvD5.s:21: Error: illegal operandslw ra,4(sp)'
/tmp/ccQtyvD5.s:22: Error: illegal operands lw s0,0(sp)' /tmp/ccQtyvD5.s:23: Error: illegal operandsaddi sp,sp,8'
/tmp/ccQtyvD5.s:24: Error: illegal operands `jr ra'
eyeballing objdump output from a gcc build from a fortnight ago, found that the generated register moves are using “add rd, zero, rs2” pattern instead of the mv pseudo from the spec: “addi rd, rs1, 0”
$ ls -l `which riscv64-unknown-elf-gcc`
-rwxr-xr-x 2 mclark mclark 5181232 Feb 15 19:44 /opt/riscv/toolchain/bin/riscv64-unknown-elf-gcc
$ rv-bin dump -a linux-4.6.2/vmlinux | grep "add " | grep zero | head
800000d0: 892a add s2, zero, a0
800000d2: 8b2e add s6, zero, a1
800000f4: 854a add a0, zero, s2
80000104: 854a add a0, zero, s2
8000010e: 855a add a0, zero, s6
80000114: 85ca add a1, zero, s2
800001b2: 892a add s2, zero, a0
800001b6: 85aa add a1, zero, a0
800001c2: 85ce add a1, zero, s3
800001c4: 8556 add a0, zero, s5
Compiling bar.c below with -O2 produces an unaligned store double instruction. Removing the -O2 fixes the problem.
Using this version of riscv-gcc:
commit a0d67b753fc2eeaf6aca047fe80e0c4a51b9417f
Author: Kito Cheng <[email protected]>
Date: Thu May 4 02:11:13 2017 +0800
Configuring like this (note the lack of a "c" in the --with-arch argument):
$ ./configure --prefix=$RISCV --with-arch=rv64imafd
Compiling bar.c like this:
$RISCV/bin/riscv64-unknown-elf-gcc -o bar.o bar.c -c -mcmodel=medany -O2
Where bar.c (minimized from bzip2) is as follows:
struct DState {
int nInUse;
int save_i;
int save_j;
int save_t;
int save_alphaSize;
};
struct DState dstate;
struct DState *make_DState() {
return &dstate;
}
void init_DState(struct DState * const s) {
s->save_i = 0;
s->save_j = 0;
s->save_t = 0;
s->save_alphaSize = 0;
}
We get a double-word aligned global dstate.
name: 'dstate'
type: STT_OBJECT
bind: STB_GLOBAL
visibility: STV_DEFAULT
value: 0x8 == 8
size: 0x14 == 20
And an init_DState() that does an unaligned store double to its DState * parameter (note that 12 % 8 != 0):
init_DState:
sw x0, 4(a0)
sw x0, 8(a0)
sd x0, 12(a0)
ret
Passing the address of the global dstate to init_DState() produces an unaligned store double.
Running riscv64 gcc on linux-riscv results in an internal compiler error, even for a minimal program:
#include <stdio.h>
int main() { printf("Hello World\n"); return 0; }
The error that is shown is:
In file included from /usr/include/bits/types.h:130:0,
from /usr/include/stdio.h:35,
from test.c:1:
/usr/include/bits/types.h:143:12: internal compiler error: in grokdeclarator, at c/c-decl.c:6769
__STD_TYPE __FSID_T_TYPE __fsid_t; /* Type of file system IDs. */
^
Please submit a full bug report,
with preprocessed source if appropriate.
See <https://gcc.gnu.org/bugs/> for instructions.
This was with the versions of the tools from abe63db64e56f42b53a38cb72f8b8eb0c8b3550f in riscv-poky. The GCC version is 7.2.0 from upstream.
Maybe it just same as @sorear report in #15?
Option: -std=c11 -latomic
Arch: RV64I and RV64G
How to reproduce:
$ riscv64-unknown-linux-gnu-gcc c11-atomic-exec-3.c -std=c11 -latomic
$ qemu-riscv64 -L `riscv64-unknown-linux-gnu-gcc --print-sysroot` a.out
Aborted (core dumped)
Code for c11-atomic-exec-3.c:
/* { dg-do run } */
/* { dg-options "-std=c11 -pedantic-errors" } */
extern void abort (void);
extern void exit (int);
#define TEST_INCDEC(TYPE, VALUE, PREOP, POSTOP, PRE_P, CHANGE) \
do \
{ \
static volatile _Atomic (TYPE) a = (TYPE) (VALUE); \
if (PREOP a POSTOP != (PRE_P \
? (TYPE) ((TYPE) (VALUE) + (CHANGE)) \
: (TYPE) (VALUE))) \
abort (); \
if (a != (TYPE) ((TYPE) (VALUE) + (CHANGE))) \
abort (); \
} \
while (0)
#define TEST_INCDEC_ARITH(VALUE, PREOP, POSTOP, PRE_P, CHANGE) \
do \
{ \
TEST_INCDEC (_Bool, (VALUE), PREOP, POSTOP, (PRE_P), (CHANGE)); \
TEST_INCDEC (char, (VALUE), PREOP, POSTOP, (PRE_P), (CHANGE)); \
TEST_INCDEC (signed char, (VALUE), PREOP, POSTOP, (PRE_P), \
(CHANGE)); \
TEST_INCDEC (unsigned char, (VALUE), PREOP, POSTOP, (PRE_P), \
(CHANGE)); \
TEST_INCDEC (signed short, (VALUE), PREOP, POSTOP, (PRE_P), \
(CHANGE)); \
TEST_INCDEC (unsigned short, (VALUE), PREOP, POSTOP, (PRE_P), \
(CHANGE)); \
TEST_INCDEC (signed int, (VALUE), PREOP, POSTOP, (PRE_P), \
(CHANGE)); \
TEST_INCDEC (unsigned int, (VALUE), PREOP, POSTOP, (PRE_P), \
(CHANGE)); \
TEST_INCDEC (signed long, (VALUE), PREOP, POSTOP, (PRE_P), \
(CHANGE)); \
TEST_INCDEC (unsigned long, (VALUE), PREOP, POSTOP, (PRE_P), \
(CHANGE)); \
TEST_INCDEC (signed long long, (VALUE), PREOP, POSTOP, (PRE_P), \
(CHANGE)); \
TEST_INCDEC (unsigned long long, (VALUE), PREOP, POSTOP, (PRE_P), \
(CHANGE)); \
TEST_INCDEC (float, (VALUE), PREOP, POSTOP, (PRE_P), (CHANGE)); \
TEST_INCDEC (double, (VALUE), PREOP, POSTOP, (PRE_P), (CHANGE)); \
TEST_INCDEC (long double, (VALUE), PREOP, POSTOP, (PRE_P), \
(CHANGE)); \
} \
while (0)
#define TEST_ALL_INCDEC_ARITH(VALUE) \
do \
{ \
TEST_INCDEC_ARITH ((VALUE), ++, , 1, 1); \
TEST_INCDEC_ARITH ((VALUE), --, , 1, -1); \
TEST_INCDEC_ARITH ((VALUE), , ++, 0, 1); \
TEST_INCDEC_ARITH ((VALUE), , --, 0, -1); \
} \
while (0)
static void
test_incdec (void)
{
TEST_ALL_INCDEC_ARITH (0);
TEST_ALL_INCDEC_ARITH (1);
TEST_ALL_INCDEC_ARITH (2);
TEST_ALL_INCDEC_ARITH (-1);
TEST_ALL_INCDEC_ARITH (1ULL << 60);
TEST_ALL_INCDEC_ARITH (1.5);
static int ia[2];
TEST_INCDEC (int *, &ia[1], ++, , 1, 1);
TEST_INCDEC (int *, &ia[1], --, , 1, -1);
TEST_INCDEC (int *, &ia[1], , ++, 0, 1);
TEST_INCDEC (int *, &ia[1], , --, 0, -1);
}
int
main (void)
{
test_incdec ();
exit (0);
}
All fail case for atomic test:
gcc.dg/atomic/c11-atomic-exec-2.c
gcc.dg/atomic/c11-atomic-exec-3.c
gcc.dg/atomic/c11-atomic-exec-4.c
gcc.dg/atomic/stdatomic-compare-exchange-3.c
GCC is generating redundant loads for accesses to bitfields. Andrew Pinski mentioned that it would likely be due to SLOW_BYTE_ACCESS being set to 0. I've tested a patch and that seems to be true. Here is example codegen with gcc 7.2 patched to set SLOW_BYTE_ACCESS to 1 vs unpatched gcc 7.1
Here is the comment from SPARC:
/* Nonzero if access to memory by bytes is slow and undesirable.
For RISC chips, it means that access to memory by bytes is no
better than access by words when possible, so grab a whole word
and maybe make use of that. */
#define SLOW_BYTE_ACCESS 1
Here is the patch to fix it:
The current code-gen seems non-optimal assuming most architectures would have cache lines were one word access is going to be faster than several byte and half accesses (including a word access in the pathological case).
This is the pathological test case:
struct foo {
unsigned int a : 3;
unsigned int b : 3;
unsigned int c : 3;
unsigned int d : 3;
unsigned int e : 3;
unsigned int f : 3;
unsigned int g : 3;
unsigned int h : 3;
unsigned int i : 3;
unsigned int j : 3;
};
unsigned int proc_foo(struct foo *p)
{
return p->a + p->b + p->c + p->d + p->d + p->e + p->f + p->g + p->h + p->i + p->j;
}
gcc is still generating sbreak instructions under certain circumstances; I'll submit this along with the multilib stuff if no-one gets there first.
Arch: RV32I, RV32G
Option: -pthread -O1
How to reproduce:
$ riscv32-unknown-linux-gnu-gcc tls-test.c -pthread -O1
$ qemu-riscv32 -L `riscv32-unknown-linux-gnu-gcc --print-sysroot` a.out
Segmentation fault (core dumped)
Code for tls-test.c:
#include <pthread.h>
extern int printf (char *,...);
__thread int a = 5;
int *volatile a_in_other_thread = (int *) 12345;
static void *
thread_func (void *arg)
{
a_in_other_thread = &a;
a+=5;
*((int *) arg) = a;
return (void *)0;
}
int
main ()
{
pthread_t thread;
void *thread_retval;
int *volatile a_in_main_thread;
int *volatile again ;
int thr_a;
a_in_main_thread = &a;
if (pthread_create (&thread, (pthread_attr_t *)0, thread_func, &thr_a))
return 0;
if (pthread_join (thread, &thread_retval))
return 0;
again = &a;
if (again != a_in_main_thread)
{
printf ("FAIL: main thread addy changed from 0x%0x to 0x%0x\n",
a_in_other_thread, again);
return 1;
}
if (a != 5 || thr_a != 10 || (a_in_other_thread == a_in_main_thread))
{
printf ("FAIL: a= %d, thr_a = %d Addr = 0x%0x\n",
a, thr_a, a_in_other_thread);
return 1;
}
return 0;
}
Code:
#define TEST (*(volatile int*)0x10000003)
void test()
{
TEST = 0x55aaaa55;
}
Generated Assemble code:
0000008e :
8e: 10000737 lui a4,0x10000
92: 00374683 lbu a3,3(a4) # 10000003 <end+0xffffddf>
96: 00370793 addi a5,a4,3
9a: 05500693 li a3,85
9e: 00d701a3 sb a3,3(a4)
a2: 00474703 lbu a4,4(a4)
a6: faa00713 li a4,-86
aa: 00e780a3 sb a4,1(a5)
ae: 0027c603 lbu a2,2(a5)
b2: 00e78123 sb a4,2(a5)
b6: 0037c703 lbu a4,3(a5)
ba: 00d781a3 sb a3,3(a5)
be: 8082 ret
Not only it doesn't generates a unaligned memory access, but also it converts it to a series of aligned memory operation, and it has some unnecessary code. If you delete this unnecessary code from it. The assemble code will look like this:
lui a4, 0x10000
li a1, 0x55
li a2, 0xaa
sb a1, 3(a4)
sb a2, 4(a4)
sb a2, 5(a4)
sb a1, 6(a4)
Command line:
riscv32-unknown-elf-gcc -Os -march=rv32ic -ffreestanding -nostdlib -o firmware.elf firmware.S firmware.c
--std=gnu99 -Wl,-Bstatic,-T,firmware.lds,-Map,firmware.map,--strip-debug -lgcc
GCC version:
gcc version 7.0.1 20170208 (experimental) (GCC)
During the boot process of 32-Bit Linux kernel several messages are shown in the console such as the found devices with their hardware addresses.
However the debug output of 64-Bit (long long int) numbers showed sometimes random 64-Bit numbers.
After a long quest through the Linux kernel and hours of disassembling and live debugging I figured out that the variadic arguments used by the printk command are responsible for the problem. The variadic argument implementation can't manage stack pointers which are divisible by 4.
The code to reproduce the problem is
#include<stdio.h>
#include<stdarg.h>
#include<string.h>
void PrintLongLong (int n, ...)
{
int i;
unsigned long long val;
va_list vl;
va_start(vl, n);
for (i=0;i<n;i++)
{
val = va_arg(vl, long long);
printf ("0x%llx\n", val);
}
va_end(vl);
}
unsigned long long x = 0x0123456789abcdef;
unsigned long long y = 0xfedcba9876543210;
void Trampoline()
{
// Move stack pointer to a offset only divisible by 4.
// A move of 8 bytes works again.
asm("addi sp, sp, -4");
PrintLongLong(2, y, x);
asm("addi sp, sp, 4");
}
int main()
{
Trampoline();
return 0;
}
Run with
riscv32-unknown-linux-gnu-gcc -O2 --static var_arg_problem.c
spike --isa=rv32 pk ./a.out
I am unsure whether the problem is in the kernel or in the compiler.
So either the Linux kernel sets the stack pointer to a wrongly aligned address or the variadic argument implementation of gcc is wrong.
This method:
static inline void l2ctl_barrier_0() { asm volatile("fence rw, io" : : : "memory" ); }
static inline void l2ctl_barrier_1() { asm volatile("fence io, rw" : : : "memory" ); }
static inline uint64_t l2ctl_flip_ways(uint64_t base_addr, int client, uint64_t ways) {
volatile uint64_t *ways_v = (uint64_t *)(base_addr + L2CTL_WAYS);
l2ctl_barrier_0();
uint64_t old = atomic_exchange_explicit(&ways_v[client], ways, memory_order_relaxed);
l2ctl_barrier_1();
return old;
}
When included above and below some critical section, this gets inlined into:
8000028e: 03c0000f fence rw,io
80000292: e03e sd a5,0(sp)
80000294: 6782 ld a5,0(sp)
80000296: 08f8b7af amoswap.d a5,a5,(a7)
8000029a: e43e sd a5,8(sp)
8000029c: 6e22 ld t3,8(sp)
8000029e: 0c30000f fence io,rw
800002a2: 4701 li a4,0
800002a4: 4781 li a5,0
800002a6: 00d05f63 blez a3,800002c4 <llc_reserve+0x104>
800002aa: 97b2 add a5,a5,a2
800002ac: 03c0000f fence rw,io
800002b0: 20f5b023 sd a5,512(a1) # 2010200 <_prog_start-0x7dfefe00>
800002b4: 0c30000f fence io,rw
800002b8: 0007c783 lbu a5,0(a5) # a000000 <_prog_start-0x76000000>
800002bc: 9f29 addw a4,a4,a0
800002be: 87ba mv a5,a4
800002c0: fed7c5e3 blt a5,a3,800002aa <llc_reserve+0xea>
800002c4: 03c0000f fence rw,io
800002c8: e872 sd t3,16(sp)
800002ca: 67c2 ld a5,16(sp)
800002cc: 08f8b7af amoswap.d a5,a5,(a7)
800002d0: ec3e sd a5,24(sp)
800002d2: 67e2 ld a5,24(sp)
800002d4: 0c30000f fence io,rw
Changing the relevant line to:
uint64_t old = atomic_exchange_explicit((_Atomic(uint64_t*))&ways_v[client], ways, memory_order_relaxed);
Makes the assembler output:
8000020a: 03c0000f fence rw,io
8000020e: 60a7362f amoand.d a2,a0,(a4)
80000212: 0c30000f fence io,rw
80000216: 0721 addi a4,a4,8
80000218: fa6d bnez a2,8000020a <llc_reserve+0x60>
8000021a: 8f46 mv t5,a7
8000021c: 07c8d663 ble t3,a7,80000288 <llc_reserve+0xde>
80000220: 02d88633 mul a2,a7,a3
80000224: 02011737 lui a4,0x2011
80000228: 00359313 slli t1,a1,0x3
8000022c: 80070713 addi a4,a4,-2048 # 2010800 <_prog_start-0x7dfef800>
80000230: 0007859b sext.w a1,a5
80000234: 0a0007b7 lui a5,0xa000
80000238: 933a add t1,t1,a4
8000023a: 4e85 li t4,1
8000023c: 02010537 lui a0,0x2010
80000240: 963e add a2,a2,a5
80000242: 03c0000f fence rw,io
80000246: 011e9833 sll a6,t4,a7
8000024a: 0903382f amoswap.d a6,a6,(t1)
8000024e: 0c30000f fence io,rw
Either it should be an error to not use an _Atomic type or the conversion should not round-trip through memory.
Arch: RV32I, RV32G, RV64I, RV64G
Option: -O0 -gdwarf
$ riscv32-unknown-linux-gnu-gcc asm-line1.c -O0 -gdwarf -S
$ grep "is_stmt 1" asm-line1.s # gcc testsute want to see that
$ riscv32-unknown-linux-gnu-gcc discriminator.c -O0 -gdwarf -S
$ grep "is_stmt" discriminator.s # gcc testsute want to see that
Code for asm-line1.c:
/* { dg-do compile { target *-*-gnu* } } */
/* { dg-options "-O0 -gdwarf" } */
/* { dg-final { scan-assembler "is_stmt 1" } } */
int i;
void f() __attribute ((section ("foo")));
void f() { if (i) ++i; else --i; }
void fun()
{
return;
}
int main()
{
f();
fun();
return 0;
}
Code for discriminator.c:
/* { dg-do compile { target *-*-gnu* } } */
/* { dg-options "-O0 -gdwarf" } */
/* { dg-final { scan-assembler "loc \[0-9] 11 \[0-9]( is_stmt \[0-9])?\n" } } */
/* { dg-final { scan-assembler "loc \[0-9] 11 \[0-9]( is_stmt \[0-9])? discriminator 2\n" } } */
/* { dg-final { scan-assembler "loc \[0-9] 11 \[0-9]( is_stmt \[0-9])? discriminator 1\n" } } */
int foo(int n) {
int i, ret = 0;
for (i = 0; i < n; i++) {
if (i % 10 == 1)
ret++;
else
ret--;
}
return ret;
}
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: g++.dg/template/nontype10.C -std=c++11 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: g++.dg/template/nontype10.C -std=c++11 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: g++.dg/template/nontype10.C -std=c++14 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: g++.dg/template/nontype10.C -std=c++14 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: g++.dg/template/nontype10.C -std=c++98 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: g++.dg/template/nontype10.C -std=c++98 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: gcc.dg/pr21643.c scan-tree-dump-times reassoc1 "Optimizing range tests c_[0-9]*.D. -.0, 31. and -.32, 32.[\n\r]* into" 6
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: gcc.dg/pr21643.c scan-tree-dump-times reassoc1 "Optimizing range tests c_[0-9]*.D. -.0, 31. and -.32, 32.[\n\r]* into" 6
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: gcc.dg/pr21643.c scan-tree-dump-times reassoc1 "Optimizing range tests c_[0-9]*.D. -.0, 31. and -.32, 32.[\n\r]* into" 6
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: gcc.dg/pr21643.c scan-tree-dump-times reassoc1 "Optimizing range tests c_[0-9]*.D. -.0, 31. and -.32, 32.[\n\r]* into" 6
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: gcc.dg/pr28796-2.c execution test
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: gcc.dg/tree-ssa/phi-opt-11.c scan-tree-dump-times optimized "if" 0
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: gcc.dg/tree-ssa/phi-opt-11.c scan-tree-dump-times optimized "if" 0
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: gcc.dg/tree-ssa/phi-opt-11.c scan-tree-dump-times optimized "if" 0
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: gcc.dg/tree-ssa/phi-opt-11.c scan-tree-dump-times optimized "if" 0
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_2.f90 -O0 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_2.f90 -O0 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_2.f90 -O1 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_2.f90 -O1 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_2.f90 -O2 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_2.f90 -O2 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_2.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_2.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_2.f90 -O3 -g execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_2.f90 -O3 -g execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_2.f90 -Os execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_2.f90 -Os execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_denormal_2.f90 -O0 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_denormal_2.f90 -O0 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_denormal_2.f90 -O1 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_denormal_2.f90 -O1 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_denormal_2.f90 -O2 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_denormal_2.f90 -O2 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_denormal_2.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_denormal_2.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_denormal_2.f90 -O3 -g execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_denormal_2.f90 -O3 -g execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_denormal_2.f90 -Os execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_denormal_2.f90 -Os execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O1 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O1 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O1 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O1 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O2 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O2 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O2 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O2 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O3 -g (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O3 -g (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O3 -g (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O3 -g (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -Os (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -Os (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -Os (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -Os (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_pf.f90 -O0 output pattern test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_pf.f90 -O1 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_pf.f90 -O1 output pattern test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_pf.f90 -O2 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_pf.f90 -O2 output pattern test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_pf.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_pf.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions output pattern test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_pf.f90 -O3 -g execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_pf.f90 -O3 -g output pattern test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_pf.f90 -Os output pattern test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_1.f90 -O0 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_1.f90 -O1 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_1.f90 -O2 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_1.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_1.f90 -O3 -g execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_1.f90 -Os execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_2.f90 -O0 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_2.f90 -O1 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_2.f90 -O1 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_2.f90 -O2 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_2.f90 -O2 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_2.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_2.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_2.f90 -O3 -g execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_2.f90 -O3 -g execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_2.f90 -Os execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/matmul_15.f90 -O execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/matmul_15.f90 -O execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/round_2.f03 -O0 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/round_2.f03 -O1 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/round_2.f03 -O2 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/round_2.f03 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/round_2.f03 -O3 -g execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/round_2.f03 -Os execution test
Is there any particular reason you remove existing branches such as "riscv-gcc-6.1.0" and move everything from the branch into another branch archive?
This causes all kinds of fetch errors from bitbake recipes.
Noticed while working on libffi.
[root@sorear6 tmp]# cat zdemo.c
struct a { double b; double c; };
struct a d(struct a e) { return e; }
[root@sorear6 tmp]# cc -o- -S -O3 zdemo.c
.file "zdemo.c"
.option nopic
.text
.align 2
.globl d
.type d, @function
d:
add sp,sp,-48
fsd fa0,16(sp)
ld a5,16(sp)
fsd fa1,24(sp)
sd a5,32(sp)
ld a5,24(sp)
fld fa0,32(sp)
sd a5,40(sp)
fld fa1,40(sp)
add sp,sp,48
jr ra
.size d, .-d
.ident "GCC: (GNU) 6.1.0 20160427 (Red Hat 6.1.0-1)"
d
could be reduced to just the return
When compiling the Fedora package xorg-x11-server-utils-7.7-20.fc25, we hit the following compiler error:
CC iceauth.o
iceauth.c: In function 'main':
iceauth.c:166:1: error: unrecognizable insn:
}
^
(insn 434 179 460 21 (set (mem/c:SI (symbol_ref:DI ("*.LANCHOR2") [flags 0x182]) [3 verbose+0 S4 A32])
(reg:SI 224 [ i ])) iceauth.c:116 -1
(nil))
iceauth.c:166:1: internal compiler error: in extract_insn, at recog.c:2287
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://bugzilla.redhat.com/bugzilla> for instructions.
Preprocessed source stored into /tmp/ccejULR8.out file, please attach this to your bugreport.
Makefile:498: recipe for target 'iceauth.o' failed
make[2]: *** [iceauth.o] Error 1
I am collecting additional information now and will update this bug.
Arch: RV32I, RV32G, RV64I, RV64G
Option: -fPIC
How to reproduce:
$ riscv32-unknown-linux-gnu-gcc run-le.c -O1 -fpic
run-le.c: In function 'get_le':
run-le.c:12:1: error: unrecognizable insn:
}
^
(insn 6 5 7 2 (set (reg:SI 75)
(unspec:SI [
(reg:SI 74)
(reg:SI 4 tp)
(symbol_ref:SI ("tls_le") [flags 0xa8] <var_decl 0x7feb299d43f0 tls_le>)
] UNSPEC_TLS_LE)) run-le.c:11 -1
(nil))
run-le.c:12:1: internal compiler error: in extract_insn, at recog.c:2287
0x8ecde3 _fatal_insn(char const*, rtx_def const*, char const*, int, char const*)
/home/kito/riscv-workspace/riscv-gnu-toolchain/riscv-gcc/gcc/rtl-error.c:108
0x8ece19 _fatal_insn_not_found(rtx_def const*, char const*, int, char const*)
/home/kito/riscv-workspace/riscv-gnu-toolchain/riscv-gcc/gcc/rtl-error.c:116
0x8c23f1 extract_insn(rtx_insn*)
/home/kito/riscv-workspace/riscv-gnu-toolchain/riscv-gcc/gcc/recog.c:2287
0x7252f3 instantiate_virtual_regs_in_insn
/home/kito/riscv-workspace/riscv-gnu-toolchain/riscv-gcc/gcc/function.c:1582
0x7252f3 instantiate_virtual_regs
/home/kito/riscv-workspace/riscv-gnu-toolchain/riscv-gcc/gcc/function.c:1950
0x7252f3 execute
/home/kito/riscv-workspace/riscv-gnu-toolchain/riscv-gcc/gcc/function.c:1999
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
Code for run-le.c:
extern void abort (void);
__thread int tls_le __attribute__((tls_model("local-exec"))) = 3;
int get_le (void)
{
return tls_le;
}
int *get_lep (void)
{
return &tls_le;
}
int main (void)
{
int val;
val = get_le ();
if (val != 3)
abort ();
val = *get_lep ();
if (val != 3)
abort ();
return 0;
}
When barriers get dropped by atomics and other C primitive, they only ever fence between memory. However, in userspace the compiler does not know you were operating on actually memory or a memory-mapped device paged in for you by some kernel driver. Therefore maybe a fence rw,rw should be fence rwio, rwio?
https://github.com/riscv/riscv-gcc/blob/b731149757b93ddc80e6e4b5483a6931d5f9ad60/gcc/config/riscv/riscv.c#L3363
https://github.com/riscv/riscv-gcc/blob/b731149757b93ddc80e6e4b5483a6931d5f9ad60/gcc/config/riscv/riscv.c#L3451
https://github.com/riscv/riscv-gcc/blob/b731149757b93ddc80e6e4b5483a6931d5f9ad60/gcc/config/riscv/riscv.c#L3579
Arch: RV64IMAF
Option: -fno-dwarf2-cfi-asm x.c -g -march=rv64imaf
How to reproduce:
$ riscv64-unknown-linux-gnu-gcc -fno-dwarf2-cfi-asm x.c -g -march=rv64imaf
x.c:6:1: internal compiler error: in div_data_align, at dwarf2cfi.c:387
}
^
0x52d709 div_data_align
/home/kito/riscv-workspace/riscv-gnu-toolchain/riscv-gcc/gcc/dwarf2cfi.c:387
0x71df8c div_data_align
/home/kito/riscv-workspace/riscv-gnu-toolchain/riscv-gcc/gcc/dwarf2cfi.c:3021
0x71df8c output_cfi(dw_cfi_node*, dw_fde_node*, int)
/home/kito/riscv-workspace/riscv-gnu-toolchain/riscv-gcc/gcc/dwarf2cfi.c:3080
0x7284eb output_fde
/home/kito/riscv-workspace/riscv-gnu-toolchain/riscv-gcc/gcc/dwarf2out.c:687
0x7284eb output_call_frame_info
/home/kito/riscv-workspace/riscv-gnu-toolchain/riscv-gcc/gcc/dwarf2out.c:946
0x72ec56 dwarf2out_frame_finish()
/home/kito/riscv-workspace/riscv-gnu-toolchain/riscv-gcc/gcc/dwarf2out.c:1179
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
Code for x.c:
void foo()
{
__builtin_unwind_init ();
}
The 3.18.37 RISC-V Options section of the GCC manual lists the RISC-V specific options, but generally the explanations are very terse, and someone not very familiar with the RISC-V specifications can hardly make use of them.
For example -mcmodel=code-model Specify the code model.
What is a code model? What are the allowed values? What does these mean? When should a user select one over the other?
I suggest you try to put a user hat on you'll see how difficult is to get answers to these questions, not only for -mcmodel
, but for the other options too.
This bug is come from wrong gcc code gen, not wrong back-end porting.
Here is the fix kito-cheng@ea72a12, we will send patch to gcc upstream in next days.
Option: -O0
Arch: RV64I and RV64G
How to reproduce:
$ riscv64-unknown-linux-gnu-gcc test.c
$ qemu-riscv64 --L `riscv64-unknown-linux-gnu-gcc --print-sysroot` a.out
Code for test.c
int v;
__attribute__((noinline, noclone)) void
bar (void)
{
v++;
}
__attribute__((noinline, noclone)) signed int t115_1mul (unsigned int x, signed int y) {
signed int r;
if (__builtin_mul_overflow (x, y, &r))
bar ();
return r;
}
__attribute__((noinline, noclone)) signed int t115_2mul (signed int y) {
unsigned int x = ((unsigned int) 0x7fffffff + 1); signed int r;
if (__builtin_mul_overflow (x, y, &r))
bar ();
return r;
}
__attribute__((noinline, noclone)) signed int t115_3mul (signed int y) {
signed int r;
if (__builtin_mul_overflow ((unsigned int) ((unsigned int) 0x7fffffff + 1), y, &r))
bar ();
return r;
}
__attribute__((noinline, noclone)) signed int t115_4mul (unsigned int x) {
signed int y = (-1);
signed int r;
if (__builtin_mul_overflow (x, y, &r))
bar ();
return r;
}
__attribute__((noinline, noclone)) signed int t115_5mul (unsigned int x) {
signed int r;
if (__builtin_mul_overflow (x, (signed int) (-1), &r))
bar ();
return r;
}
void t115mul (void) {
unsigned int x = ((unsigned int) 0x7fffffff + 1);
signed int y = (-1);
signed int r1, r2; v = 0;
if (t115_1mul (x, y) != (signed int) ((-0x7fffffff - 1))
|| t115_2mul (y) != (signed int) ((-0x7fffffff - 1))
|| t115_3mul (y) != (signed int) ((-0x7fffffff - 1))
|| t115_4mul (x) != (signed int) ((-0x7fffffff - 1))
|| t115_5mul (x) != (signed int) ((-0x7fffffff - 1)))
__builtin_abort ();
if (__builtin_mul_overflow (x, y, &r1))
bar ();
if (r1 != (signed int) ((-0x7fffffff - 1)))
__builtin_abort ();
if (__builtin_mul_overflow ((unsigned int) ((unsigned int) 0x7fffffff + 1),
(signed int) (-1),
&r2))
bar ();
if (r2 != (signed int) ((-0x7fffffff - 1)) || v != 7 * 0)
__builtin_abort ();
}
int main()
{
t115mul();
}
Original test case:
c-c++-common/torture/builtin-arith-overflow-12.c
@michaeljclark to produce minimal test cases.
GCC: de6438d
Arch: All RV32 family
Option: O2
How to reproduce:
$ riscv32-unknown-linux-gnu-gcc vector-compare-3.c -O2
vector-compare-3.c: In function 'g':
vector-compare-3.c:20:1: internal compiler error: in max_value, at wide-int.cc:317
g (v4i *x, v4i const *y, v4i *z, v4i *t)
^
0xd7b7c6 wi::max_value(unsigned int, signop)
/home/kito/riscv-workspace/riscv-gnu-toolchain/riscv-gcc/gcc/wide-int.cc:317
0xd19640 integer_all_onesp(tree_node const*)
/home/kito/riscv-workspace/riscv-gnu-toolchain/riscv-gcc/gcc/tree.c:2410
0xd195f9 integer_all_onesp(tree_node const*)
/home/kito/riscv-workspace/riscv-gnu-toolchain/riscv-gcc/gcc/tree.c:2402
0xe3c2e7 generic_simplify_VEC_COND_EXPR
/home/kito/riscv-workspace/rv32ima/build/build-gcc-linux-stage2/gcc/generic-match.c:26211
0xe3c2e7 generic_simplify(unsigned int, tree_code, tree_node*, tree_node*, tree_node*, tree_node*)
/home/kito/riscv-workspace/rv32ima/build/build-gcc-linux-stage2/gcc/generic-match.c:26399
0x7c773c fold_ternary_loc(unsigned int, tree_code, tree_node*, tree_node*, tree_node*, tree_node*)
/home/kito/riscv-workspace/riscv-gnu-toolchain/riscv-gcc/gcc/fold-const.c:11482
0xd8d42a gimple_resimplify3(gimple**, code_helper*, tree_node*, tree_node**, tree_node* (*)(tree_node*))
/home/kito/riscv-workspace/riscv-gnu-toolchain/riscv-gcc/gcc/gimple-match-head.c:189
0xdff2a7 gimple_simplify(gimple*, code_helper*, tree_node**, gimple**, tree_node* (*)(tree_node*), tree_node* (*)(tree_node*))
/home/kito/riscv-workspace/riscv-gnu-toolchain/riscv-gcc/gcc/gimple-match-head.c:686
0x8294b1 fold_stmt_1
/home/kito/riscv-workspace/riscv-gnu-toolchain/riscv-gcc/gcc/gimple-fold.c:3649
0xbbf562 execute
/home/kito/riscv-workspace/riscv-gnu-toolchain/riscv-gcc/gcc/tree-ssa-forwprop.c:2309
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
Code for vector-compare-3.c
/* { dg-do compile } */
/* { dg-options "-O2" } */
typedef int v4i __attribute__((vector_size(4*sizeof(int))));
// fold should not turn (vec_other)(x<y) into (x<y)?vec_other(-1):vec_other(0).
void use (v4i const *z);
void
f (v4i *x, v4i *y)
{
v4i const zz = *x < *y;
use (&zz);
}
// Optimizations shouldn't introduce a boolean type in there
void
g (v4i *x, v4i const *y, v4i *z, v4i *t)
{
*z = *x < *y | *x == *y;
*t = *x < *y & *x > *y;
}
hello,
I want to generate a executable file without RVC codes. But even compiling program with -march=rv64g
, there still are RVC codes in standard library functions, for example, the printf
and memset
. I get this through riscv64-unknown-elf-objdump -d
. while if I use -march=rv64gc
, both my own functions and the standard ones will include RVC codes.
Automatically genetating RVC codes as many as possible is the correct behavior of the cross compiler? If yes, what should I do to stop it? Or there are something I misunderstanding?
So many thanks for any advice!
I seem to have stumbled into a peculiar riscv-gcc compiler bug that's manifesting as a segfault. I'm working on porting Contiki to the SiFive FE310, and compiling the network stack triggers the bug.
Steps to reproduce:
git clone https://github.com/osdomotics/osd-contiki.git
cd osd-contiki/
git checkout ico
touch icosoc.h
riscv32-unknown-elf-gcc -Icore -Iplatform/pico-rv32-icoboard -Icpu/pico-rv32 -I. -c core/net/ipv4/uip.c -Os -g
Error message:
core/net/ipv4/uip.c: In function 'uip_connect':
core/net/ipv4/uip.c:457:1: internal compiler error: Segmentation fault
}
^
0xa8b24f crash_signal
/ssd/freedom-e-sdk/work/riscv32-gnu-toolchain/src/newlib-gcc/gcc/toplev.c:333
0xe984e0 try_combine
/ssd/freedom-e-sdk/work/riscv32-gnu-toolchain/src/newlib-gcc/gcc/combine.c:4045
0xe9d751 combine_instructions
/ssd/freedom-e-sdk/work/riscv32-gnu-toolchain/src/newlib-gcc/gcc/combine.c:1288
0xe9d751 rest_of_handle_combine
/ssd/freedom-e-sdk/work/riscv32-gnu-toolchain/src/newlib-gcc/gcc/combine.c:14350
0xe9d751 execute
/ssd/freedom-e-sdk/work/riscv32-gnu-toolchain/src/newlib-gcc/gcc/combine.c:14393
Here's where it gets fun. -Os
without -g
doesn't segfault. Neither does -O2 -g
. Even more fun, adding the specific optimization flags to transform -O2 into -Os (finline-functions -fno-optimize-strlen -freorder-blocks-algorithm=simple -fno-schedule-insns -g
) results in a successful compile.
I am way out of my depth debugging this. Is there any other information I can provide to help?
GCC was compiled from riscv-gcc@3e7b179f8b6.
$ riscv32-unknown-elf-gcc -v
Using built-in specs.
COLLECT_GCC=/ssd/freedom-e-sdk/toolchain/bin/riscv32-unknown-elf-gcc
COLLECT_LTO_WRAPPER=/ssd/freedom-e-sdk/toolchain/libexec/gcc/riscv32-unknown-elf/6.1.0/lto-wrapper
Target: riscv32-unknown-elf
Configured with: /ssd/freedom-e-sdk/work/riscv32-gnu-toolchain/src/newlib-gcc/configure --target=riscv32-unknown-elf --prefix=/ssd/freedom-e-sdk/toolchain --disable-shared --disable-threads --disable-tls --enable-languages=c,c++ --with-system-zlib --with-newlib --disable-libmudflap --disable-libssp --disable-libquadmath --disable-libgomp --disable-nls --enable-checking=yes --disable-multilib --with-abi=ilp32 --with-arch=rv32ima
Thread model: single
gcc version 6.1.0 (GCC)
Seem cause by 2fe94d5
FAIL: gcc.dg/memmove-4.c scan-tree-dump-not optimized "memmove"
FAIL: gcc.dg/strlenopt-8.c scan-tree-dump-times strlen "memcpy \\(" 2
Hi all!
Sorry if this already was discussed but I haven't managed to find any related discussions.
We've noticed that currently the latest compiler doesn't have momvem patterns which means eg any memcpy is expanded in library call.
Is this intented for some reasons or it will be added at some moment?
Thanks in advance,
Igor
C Code:
void test_stack(void)
{
volatile char temp;
temp = 0;
}
ASM Code
addi sp,sp,-16
sb zero,15(sp)
addi sp,sp,16
ret
The compiler tries to keep items on the stack aligned to 16 byte. Can I control the stack to align to 2^n?
Reference:
http://stackoverflow.com/questions/1061818/stack-allocation-padding-and-alignment
The error messages are:
riscv64-unknown-elf-g++: error: unrecognized command line option '-mmemcpy'
riscv64-unknown-elf-g++: error: unrecognized command line option '-mno-memcpy'; did you mean '-Wno-cpp'?
This happens with:
$ opt/riscv64-unknown-elf-gcc-20170503-x86_64-apple-darwin/bin/riscv64-unknown-elf-gcc --version
riscv64-unknown-elf-gcc (GCC) 7.1.0
I'm currently investigating binary sizes (-Os vs -O2), but in the process noticed that the default binaries were quite large. I then discovered that all binaries had debug info whether or not I had requested it with -g, and even trying to turn debug into off with -gtoggle or -g0 has no effect.
Reference: https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/Debugging-Options.html
I've tried with gcc 7.0.1 20170321 (experimental) and the gcc 7.1 release, with various configurations (newlib, glibc, musl) and they all appear to add debug info by default.
It seems riscv64-unknown-elf-strip --strip-debug
works okay in the mean time, however shouldn't the RISC-V GCC port honour the -g flags?
$ riscv64-unknown-elf-gcc -static -Os -g0 src/aes.c -o bin/riscv64/aes
$ riscv64-unknown-elf-objdump -h bin/riscv64/aes
bin/riscv64/aes: file format elf64-littleriscv
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000d5fa 00000000000100b0 00000000000100b0 000000b0 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .rodata 00003438 000000000001d6b0 000000000001d6b0 0000d6b0 2**4
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .eh_frame 00000004 0000000000020ae8 0000000000020ae8 00010ae8 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .init_array 00000008 0000000000021af0 0000000000021af0 00010af0 2**3
CONTENTS, ALLOC, LOAD, DATA
4 .fini_array 00000008 0000000000021af8 0000000000021af8 00010af8 2**3
CONTENTS, ALLOC, LOAD, DATA
5 .data 00000ff8 0000000000021b00 0000000000021b00 00010b00 2**3
CONTENTS, ALLOC, LOAD, DATA
6 .sdata 00000070 0000000000022af8 0000000000022af8 00011af8 2**3
CONTENTS, ALLOC, LOAD, DATA
7 .sbss 00000030 0000000000022b68 0000000000022b68 00011b68 2**3
ALLOC
8 .bss 00000078 0000000000022b98 0000000000022b98 00011b68 2**3
ALLOC
9 .comment 00000029 0000000000000000 0000000000000000 00011b68 2**0
CONTENTS, READONLY
10 .debug_aranges 00000c40 0000000000000000 0000000000000000 00011ba0 2**4
CONTENTS, READONLY, DEBUGGING
11 .debug_info 0002ed21 0000000000000000 0000000000000000 000127e0 2**0
CONTENTS, READONLY, DEBUGGING
12 .debug_abbrev 00008bac 0000000000000000 0000000000000000 00041501 2**0
CONTENTS, READONLY, DEBUGGING
13 .debug_line 00013a71 0000000000000000 0000000000000000 0004a0ad 2**0
CONTENTS, READONLY, DEBUGGING
14 .debug_frame 00003520 0000000000000000 0000000000000000 0005db20 2**3
CONTENTS, READONLY, DEBUGGING
15 .debug_str 00003476 0000000000000000 0000000000000000 00061040 2**0
CONTENTS, READONLY, DEBUGGING
16 .debug_loc 0002cbd1 0000000000000000 0000000000000000 000644b6 2**0
CONTENTS, READONLY, DEBUGGING
17 .debug_ranges 00003260 0000000000000000 0000000000000000 00091087 2**0
CONTENTS, READONLY, DEBUGGING
I am trying to decompose the elf file data into different 8-bit RAM chips, which together form a 64-bit data bus. For this, I use "riscv64-unknown-elf-objcopy -I elf64-littleriscv -O verilog --interleave = 8 --interleave-width = 1 --byte = 0". But when the elf file starts with addresses that are not 8 bytes long, an error occurs.
In the attachment, an example of a test.
dump:
0000000000000000 <.a0>:
0: 00000013 nop
4: 00000033 add zero, zero, zero
Disassembly of section .a1:
000000000000000c <_start + 0xc>:
c: 00000013 nop
10: 00000033 add zero, zero, zero
I expect that the file test0.hex will:
@ 00000000
13
@ 00000002
33
... in the file test4.hex will be:
@ 00000000
33
@ 00000001
13
... in fact in the file test0.hex:
@ 00000000
13
@ 00000001
13
... in the file test4.hex:
@ 00000000
33
@ 00000001
33
I guess this is relate to sfp-machine.h since we add the FP_INIT_ROUNDMODE and FP_HANDLE_EXCEPTIONS stub and make this case testable.
Arch: RV64IMAF and RV64G
Option: -latomic -lpthread -lm -o c11-atomic-exec-5.rv64i -std=c11 -pedantic-errors -pthread -U_POSIX_C_SOURCE -D_POSIX_C_SOURCE=200809L -O
How to reproduce:
$ riscv64-unknown-linux-gnu-gcc c11-atomic-exec-5.c -latomic -lpthread -lm -o c11-atomic-exec-5.rv64g -std=c11 -pedantic-errors -pthread -U_POSIX_C_SOURCE -D_POSIX_C_SOURCE=200809L -O
$ qemu-riscv64 -L `./rv64imafd/bin/riscv64-unknown-linux-gnu-gcc --print-sysroot` c11-atomic-exec-5.rv64g
float_add_invalid (a) 4323 pass, 694 fail; (b) 4983 pass, 0 fail
float_add_invalid_prev (a) 4208 pass, 765 fail; (b) 5027 pass, 0 fail
float_add_overflow (a) 0 pass, 5128 fail; (b) 4872 pass, 0 fail
float_add_overflow_prev (a) 0 pass, 4994 fail; (b) 5006 pass, 0 fail
float_add_overflow_double (a) 0 pass, 5039 fail; (b) 4961 pass, 0 fail
float_add_overflow_long_double (a) 4973 pass, 0 fail; (b) 4449 pass, 578 fail
float_add_inexact (a) 5009 pass, 0 fail; (b) 3967 pass, 1024 fail
float_add_inexact_int (a) 5068 pass, 0 fail; (b) 4242 pass, 690 fail
float_preinc_inexact (a) 5064 pass, 0 fail; (b) 4269 pass, 667 fail
float_postinc_inexact (a) 5156 pass, 0 fail; (b) 4275 pass, 569 fail
long_add_float_inexact (a) 4914 pass, 0 fail; (b) 3745 pass, 1341 fail
complex_float_add_overflow (a) 0 pass, 4983 fail; (b) 5017 pass, 0 fail
float_sub_invalid (a) 3968 pass, 1006 fail; (b) 5026 pass, 0 fail
float_sub_overflow (a) 0 pass, 5157 fail; (b) 4843 pass, 0 fail
float_sub_inexact (a) 5019 pass, 0 fail; (b) 4301 pass, 680 fail
float_sub_inexact_int (a) 4999 pass, 0 fail; (b) 3936 pass, 1065 fail
float_predec_inexact (a) 5006 pass, 0 fail; (b) 4252 pass, 742 fail
float_postdec_inexact (a) 4990 pass, 0 fail; (b) 3994 pass, 1016 fail
long_sub_float_inexact (a) 5022 pass, 0 fail; (b) 3971 pass, 1007 fail
complex_float_sub_overflow (a) 0 pass, 5035 fail; (b) 4965 pass, 0 fail
float_mul_invalid (a) 4352 pass, 654 fail; (b) 4994 pass, 0 fail
float_mul_overflow (a) 0 pass, 5029 fail; (b) 4971 pass, 0 fail
float_mul_underflow (a) 0 pass, 4999 fail; (b) 5001 pass, 0 fail
float_mul_inexact (a) 4967 pass, 0 fail; (b) 4195 pass, 838 fail
float_mul_inexact_int (a) 4961 pass, 0 fail; (b) 4213 pass, 826 fail
long_mul_float_inexact (a) 4835 pass, 0 fail; (b) 4088 pass, 1077 fail
complex_float_mul_overflow (a) 0 pass, 4927 fail; (b) 5073 pass, 0 fail
float_div_invalid_divbyzero (a) 4248 pass, 771 fail; (b) 4265 pass, 716 fail
float_div_overflow (a) 0 pass, 5060 fail; (b) 4940 pass, 0 fail
float_div_underflow (a) 0 pass, 5008 fail; (b) 4992 pass, 0 fail
float_div_inexact (a) 4904 pass, 0 fail; (b) 4217 pass, 879 fail
float_div_inexact_int (a) 5036 pass, 0 fail; (b) 4225 pass, 739 fail
int_div_float_inexact (a) 5002 pass, 0 fail; (b) 4248 pass, 750 fail
complex_float_div_overflow (a) 0 pass, 4966 fail; (b) 5034 pass, 0 fail
double_add_invalid (a) 4295 pass, 817 fail; (b) 4888 pass, 0 fail
double_add_overflow (a) 0 pass, 5063 fail; (b) 4937 pass, 0 fail
double_add_overflow_long_double (a) 4946 pass, 0 fail; (b) 3949 pass, 1105 fail
double_add_inexact (a) 5024 pass, 0 fail; (b) 4188 pass, 788 fail
double_add_inexact_int (a) 5025 pass, 0 fail; (b) 4213 pass, 762 fail
double_preinc_inexact (a) 4973 pass, 0 fail; (b) 4409 pass, 618 fail
double_postinc_inexact (a) 4989 pass, 0 fail; (b) 4259 pass, 752 fail
long_long_add_double_inexact (a) 5013 pass, 0 fail; (b) 3942 pass, 1045 fail
complex_double_add_overflow (a) 0 pass, 4874 fail; (b) 5126 pass, 0 fail
double_sub_invalid (a) 4082 pass, 960 fail; (b) 4958 pass, 0 fail
double_sub_overflow (a) 0 pass, 5000 fail; (b) 5000 pass, 0 fail
double_sub_inexact (a) 5090 pass, 0 fail; (b) 3943 pass, 967 fail
double_sub_inexact_int (a) 4969 pass, 0 fail; (b) 4054 pass, 977 fail
double_predec_inexact (a) 4955 pass, 0 fail; (b) 3790 pass, 1255 fail
double_postdec_inexact (a) 5009 pass, 0 fail; (b) 3955 pass, 1036 fail
long_long_sub_double_inexact (a) 5045 pass, 0 fail; (b) 3904 pass, 1051 fail
complex_double_sub_overflow (a) 0 pass, 5026 fail; (b) 4974 pass, 0 fail
double_mul_invalid (a) 4329 pass, 713 fail; (b) 4958 pass, 0 fail
double_mul_overflow (a) 0 pass, 5064 fail; (b) 4936 pass, 0 fail
double_mul_overflow_float (a) 0 pass, 4965 fail; (b) 5035 pass, 0 fail
double_mul_underflow (a) 0 pass, 4968 fail; (b) 5032 pass, 0 fail
double_mul_inexact (a) 5075 pass, 0 fail; (b) 4219 pass, 706 fail
double_mul_inexact_int (a) 4962 pass, 0 fail; (b) 4297 pass, 741 fail
long_long_mul_double_inexact (a) 4975 pass, 0 fail; (b) 4339 pass, 686 fail
complex_double_mul_overflow (a) 0 pass, 4954 fail; (b) 5046 pass, 0 fail
double_div_invalid_divbyzero (a) 4405 pass, 759 fail; (b) 4260 pass, 576 fail
double_div_overflow (a) 0 pass, 5013 fail; (b) 4987 pass, 0 fail
double_div_underflow (a) 0 pass, 4992 fail; (b) 5008 pass, 0 fail
double_div_inexact (a) 4965 pass, 0 fail; (b) 4025 pass, 1010 fail
double_div_inexact_int (a) 4913 pass, 0 fail; (b) 4168 pass, 919 fail
int_div_double_inexact (a) 4957 pass, 0 fail; (b) 4302 pass, 741 fail
complex_double_div_overflow (a) 0 pass, 4920 fail; (b) 5080 pass, 0 fail
long_double_add_invalid (a) 4348 pass, 728 fail; (b) 4924 pass, 0 fail
long_double_add_overflow (a) 5009 pass, 0 fail; (b) 4202 pass, 789 fail
long_double_add_inexact (a) 4892 pass, 0 fail; (b) 4258 pass, 850 fail
long_double_add_inexact_int (a) 4888 pass, 0 fail; (b) 3900 pass, 1212 fail
long_double_preinc_inexact (a) 4850 pass, 0 fail; (b) 3982 pass, 1168 fail
long_double_postinc_inexact (a) 4912 pass, 0 fail; (b) 4042 pass, 1046 fail
complex_long_double_add_overflow (a) 4936 pass, 0 fail; (b) 4014 pass, 1050 fail
long_double_sub_invalid (a) 4236 pass, 716 fail; (b) 5048 pass, 0 fail
long_double_sub_overflow (a) 4939 pass, 0 fail; (b) 4338 pass, 723 fail
long_double_sub_inexact (a) 4841 pass, 0 fail; (b) 4152 pass, 1007 fail
long_double_sub_inexact_int (a) 4821 pass, 0 fail; (b) 4109 pass, 1070 fail
long_double_predec_inexact (a) 4805 pass, 0 fail; (b) 3994 pass, 1201 fail
long_double_postdec_inexact (a) 4783 pass, 0 fail; (b) 4167 pass, 1050 fail
complex_long_double_sub_overflow (a) 4927 pass, 0 fail; (b) 4084 pass, 989 fail
long_double_mul_invalid (a) 4305 pass, 640 fail; (b) 5055 pass, 0 fail
long_double_mul_overflow (a) 4868 pass, 0 fail; (b) 4229 pass, 903 fail
long_double_mul_overflow_float (a) 4782 pass, 0 fail; (b) 3941 pass, 1277 fail
long_double_mul_overflow_double (a) 5022 pass, 0 fail; (b) 4041 pass, 937 fail
long_double_mul_underflow (a) 4873 pass, 0 fail; (b) 3949 pass, 1178 fail
long_double_mul_inexact (a) 4888 pass, 0 fail; (b) 4223 pass, 889 fail
long_double_mul_inexact_int (a) 4851 pass, 0 fail; (b) 4090 pass, 1059 fail
complex_long_double_mul_overflow (a) 4718 pass, 0 fail; (b) 3910 pass, 1372 fail
long_double_div_invalid_divbyzero (a) 4206 pass, 895 fail; (b) 4037 pass, 862 fail
long_double_div_overflow (a) 4781 pass, 0 fail; (b) 4313 pass, 906 fail
long_double_div_underflow (a) 4882 pass, 0 fail; (b) 4162 pass, 956 fail
long_double_div_inexact (a) 4794 pass, 0 fail; (b) 4215 pass, 991 fail
long_double_div_inexact_int (a) 4723 pass, 0 fail; (b) 3980 pass, 1297 fail
int_div_long_double_inexact (a) 4591 pass, 0 fail; (b) 3805 pass, 1604 fail
complex_long_double_div_overflow (a) 4825 pass, 0 fail; (b) 3880 pass, 1295 fail
Aborted (core dumped)
Code for c11-atomic-exec-5.c:
/* Test for _Atomic in C11. Test floating-point exceptions for
compound assignment are consistent with result (so that if multiple
iterations of the compare-and-exchange loop are needed, exceptions
get properly cleared). */
/* { dg-do run } */
/* { dg-options "-std=c11 -pedantic-errors -pthread -U_POSIX_C_SOURCE -D_POSIX_C_SOURCE=200809L" } */
/* { dg-add-options ieee } */
/* { dg-additional-options "-mfp-trap-mode=sui" { target alpha*-*-* } } */
/* { dg-additional-options "-D_XOPEN_SOURCE=600" { target *-*-solaris2.1[0-9]* } } */
/* { dg-require-effective-target fenv_exceptions } */
/* { dg-require-effective-target pthread } */
/* { dg-timeout-factor 2 } */
#include <fenv.h>
#include <float.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#define TEST_ALL_EXCEPT (FE_DIVBYZERO \
| FE_INEXACT \
| FE_INVALID \
| FE_OVERFLOW \
| FE_UNDERFLOW)
#if defined __alpha__
#define ITER_COUNT 100
#else
#define ITER_COUNT 10000
#endif
static volatile _Atomic bool thread_ready, thread_stop;
/* Generate test code (with NAME used to name functions and variables)
for atomic compound assignments to a variable of type LHSTYPE. One
thread repeatedly stores the values INIT1 and INIT2 in a variable,
while the other repeatedly executes PRE var POST having set
floating-point exceptions to BEXC. If the value of the assignment
operation satisfies VALTEST1 (var), the floating-point exceptions
should be BEXC | EXC1; otherwise, they should be BEXC | EXC2. A
function test_main_##NAME is generated that returns nonzero on
failure, zero on success. */
#define TEST_FUNCS(NAME, LHSTYPE, PRE, POST, BEXC, \
INIT1, VALTEST1, EXC1, INIT2, EXC2) \
\
static volatile _Atomic LHSTYPE var_##NAME; \
\
static void * \
test_thread_##NAME (void *arg) \
{ \
thread_ready = true; \
while (!thread_stop) \
{ \
var_##NAME = (INIT1); \
var_##NAME = (INIT2); \
} \
return NULL; \
} \
\
static int \
test_main_##NAME (void) \
{ \
thread_stop = false; \
thread_ready = false; \
var_##NAME = (INIT1); \
pthread_t thread_id; \
int pret = pthread_create (&thread_id, NULL, test_thread_##NAME, \
NULL); \
if (pret != 0) \
{ \
printf ("pthread_create failed: %d\n", pret); \
return 1; \
} \
int num_1_pass = 0, num_1_fail = 0, num_2_pass = 0, num_2_fail = 0; \
while (!thread_ready) \
; \
for (int i = 0; i < ITER_COUNT; i++) \
{ \
feclearexcept (FE_ALL_EXCEPT); \
feraiseexcept (BEXC); \
LHSTYPE r = (PRE var_##NAME POST); \
int rexc = fetestexcept (TEST_ALL_EXCEPT); \
if (VALTEST1 (r)) \
{ \
if (rexc == ((BEXC) | (EXC1))) \
num_1_pass++; \
else \
num_1_fail++; \
var_##NAME = (INIT2); \
} \
else \
{ \
if (rexc == ((BEXC) | (EXC2))) \
num_2_pass++; \
else \
num_2_fail++; \
var_##NAME = (INIT1); \
} \
} \
thread_stop = true; \
pthread_join (thread_id, NULL); \
printf (#NAME " (a) %d pass, %d fail; (b) %d pass, %d fail\n", \
num_1_pass, num_1_fail, num_2_pass, num_2_fail); \
return num_1_fail || num_2_fail; \
}
TEST_FUNCS (float_add_invalid, float, , += __builtin_inff (), 0,
0, __builtin_isinf, 0,
-__builtin_inff (), FE_INVALID)
TEST_FUNCS (float_add_invalid_prev, float, , += __builtin_inff (),
FE_DIVBYZERO | FE_INEXACT | FE_OVERFLOW | FE_UNDERFLOW,
0, __builtin_isinf, 0,
-__builtin_inff (), FE_INVALID)
TEST_FUNCS (float_add_overflow, float, , += FLT_MAX, 0,
FLT_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
0, 0)
TEST_FUNCS (float_add_overflow_prev, float, , += FLT_MAX, FE_INVALID,
FLT_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
0, 0)
TEST_FUNCS (float_add_overflow_double, float, , += (double) FLT_MAX, 0,
FLT_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
0, 0)
TEST_FUNCS (float_add_overflow_long_double, float, , += (long double) FLT_MAX, 0,
FLT_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
0, 0)
#define NOT_FLT_EPSILON_2(X) ((X) != FLT_EPSILON / 2)
TEST_FUNCS (float_add_inexact, float, , += FLT_EPSILON / 2, 0,
1.0f, NOT_FLT_EPSILON_2, FE_INEXACT,
0, 0)
#define NOT_0(X) ((X) != 0)
TEST_FUNCS (float_add_inexact_int, float, , += 1, 0,
FLT_EPSILON / 2, NOT_0, FE_INEXACT,
-1, 0)
TEST_FUNCS (float_preinc_inexact, float, ++, , 0,
FLT_EPSILON / 2, NOT_0, FE_INEXACT,
-1, 0)
#define NOT_MINUS_1(X) ((X) != -1)
TEST_FUNCS (float_postinc_inexact, float, , ++, 0,
FLT_EPSILON / 2, NOT_MINUS_1, FE_INEXACT,
-1, 0)
#if FLT_EVAL_METHOD == 0
TEST_FUNCS (long_add_float_inexact, long, , += 2 / FLT_EPSILON, 0,
1, NOT_0, FE_INEXACT,
-2 / FLT_EPSILON, 0)
#endif
#define REAL_ISINF(X) (__builtin_isinf (__real__ (X)))
TEST_FUNCS (complex_float_add_overflow, _Complex float, , += FLT_MAX, 0,
FLT_MAX, REAL_ISINF, FE_OVERFLOW | FE_INEXACT,
0, 0)
TEST_FUNCS (float_sub_invalid, float, , -= __builtin_inff (), 0,
0, __builtin_isinf, 0,
__builtin_inff (), FE_INVALID)
TEST_FUNCS (float_sub_overflow, float, , -= FLT_MAX, 0,
-FLT_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
0, 0)
#define NOT_MINUS_FLT_EPSILON_2(X) ((X) != -FLT_EPSILON / 2)
TEST_FUNCS (float_sub_inexact, float, , -= FLT_EPSILON / 2, 0,
-1.0f, NOT_MINUS_FLT_EPSILON_2, FE_INEXACT,
0, 0)
#define NOT_0(X) ((X) != 0)
TEST_FUNCS (float_sub_inexact_int, float, , -= 1, 0,
-FLT_EPSILON / 2, NOT_0, FE_INEXACT,
1, 0)
TEST_FUNCS (float_predec_inexact, float, --, , 0,
-FLT_EPSILON / 2, NOT_0, FE_INEXACT,
1, 0)
#define NOT_1(X) ((X) != 1)
TEST_FUNCS (float_postdec_inexact, float, , --, 0,
-FLT_EPSILON / 2, NOT_1, FE_INEXACT,
1, 0)
#if FLT_EVAL_METHOD == 0
TEST_FUNCS (long_sub_float_inexact, long, , -= 2 / FLT_EPSILON, 0,
-1, NOT_0, FE_INEXACT,
2 / FLT_EPSILON, 0)
#endif
TEST_FUNCS (complex_float_sub_overflow, _Complex float, , -= FLT_MAX, 0,
-FLT_MAX, REAL_ISINF, FE_OVERFLOW | FE_INEXACT,
0, 0)
TEST_FUNCS (float_mul_invalid, float, , *= __builtin_inff (), 0,
__builtin_inff (), __builtin_isinf, 0,
0, FE_INVALID)
TEST_FUNCS (float_mul_overflow, float, , *= FLT_MAX, 0,
FLT_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
0, 0)
#define IS_0(X) ((X) == 0)
TEST_FUNCS (float_mul_underflow, float, , *= FLT_MIN, 0,
FLT_MIN, IS_0, FE_UNDERFLOW | FE_INEXACT,
1, 0)
TEST_FUNCS (float_mul_inexact, float, , *= 1 + FLT_EPSILON, 0,
1 + FLT_EPSILON, NOT_0, FE_INEXACT,
0, 0)
TEST_FUNCS (float_mul_inexact_int, float, , *= 3, 0,
1 + FLT_EPSILON, NOT_0, FE_INEXACT,
0, 0)
#if FLT_EVAL_METHOD == 0
TEST_FUNCS(long_mul_float_inexact, long, , *= 3.0f, 0,
1 + 1 / FLT_EPSILON, NOT_0, FE_INEXACT,
0, 0)
#endif
TEST_FUNCS (complex_float_mul_overflow, _Complex float, , *= FLT_MAX, 0,
FLT_MAX, REAL_ISINF, FE_OVERFLOW | FE_INEXACT,
0, 0)
TEST_FUNCS (float_div_invalid_divbyzero, float, , /= 0.0f, 0,
1, __builtin_isinf, FE_DIVBYZERO,
0, FE_INVALID)
TEST_FUNCS (float_div_overflow, float, , /= FLT_MIN, 0,
FLT_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
0, 0)
TEST_FUNCS (float_div_underflow, float, , /= FLT_MAX, 0,
FLT_MIN, IS_0, FE_UNDERFLOW | FE_INEXACT,
FLT_MAX, 0)
TEST_FUNCS (float_div_inexact, float, , /= 3.0f, 0,
1, NOT_0, FE_INEXACT,
0, 0)
TEST_FUNCS (float_div_inexact_int, float, , /= 3, 0,
1, NOT_0, FE_INEXACT,
0, 0)
TEST_FUNCS (int_div_float_inexact, int, , /= 3.0f, 0,
4, NOT_0, FE_INEXACT,
0, 0)
TEST_FUNCS (complex_float_div_overflow, _Complex float, , /= FLT_MIN, 0,
FLT_MAX, REAL_ISINF, FE_OVERFLOW | FE_INEXACT,
0, 0)
TEST_FUNCS (double_add_invalid, double, , += __builtin_inf (), 0,
0, __builtin_isinf, 0,
-__builtin_inf (), FE_INVALID)
TEST_FUNCS (double_add_overflow, double, , += DBL_MAX, 0,
DBL_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
0, 0)
TEST_FUNCS (double_add_overflow_long_double, double, , += (long double) DBL_MAX, 0,
DBL_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
0, 0)
#define NOT_DBL_EPSILON_2(X) ((X) != DBL_EPSILON / 2)
TEST_FUNCS (double_add_inexact, double, , += DBL_EPSILON / 2, 0,
1.0, NOT_DBL_EPSILON_2, FE_INEXACT,
0, 0)
TEST_FUNCS (double_add_inexact_int, double, , += 1, 0,
DBL_EPSILON / 2, NOT_0, FE_INEXACT,
-1, 0)
TEST_FUNCS (double_preinc_inexact, double, ++, , 0,
DBL_EPSILON / 2, NOT_0, FE_INEXACT,
-1, 0)
TEST_FUNCS (double_postinc_inexact, double, , ++, 0,
DBL_EPSILON / 2, NOT_MINUS_1, FE_INEXACT,
-1, 0)
#if FLT_EVAL_METHOD == 0
TEST_FUNCS (long_long_add_double_inexact, long long, , += 2 / DBL_EPSILON, 0,
1, NOT_0, FE_INEXACT,
-2 / DBL_EPSILON, 0)
#endif
TEST_FUNCS (complex_double_add_overflow, _Complex double, , += DBL_MAX, 0,
DBL_MAX, REAL_ISINF, FE_OVERFLOW | FE_INEXACT,
0, 0)
TEST_FUNCS (double_sub_invalid, double, , -= __builtin_inf (), 0,
0, __builtin_isinf, 0,
__builtin_inf (), FE_INVALID)
TEST_FUNCS (double_sub_overflow, double, , -= DBL_MAX, 0,
-DBL_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
0, 0)
#define NOT_MINUS_DBL_EPSILON_2(X) ((X) != -DBL_EPSILON / 2)
TEST_FUNCS (double_sub_inexact, double, , -= DBL_EPSILON / 2, 0,
-1.0, NOT_MINUS_DBL_EPSILON_2, FE_INEXACT,
0, 0)
TEST_FUNCS (double_sub_inexact_int, double, , -= 1, 0,
-DBL_EPSILON / 2, NOT_0, FE_INEXACT,
1, 0)
TEST_FUNCS (double_predec_inexact, double, --, , 0,
-DBL_EPSILON / 2, NOT_0, FE_INEXACT,
1, 0)
TEST_FUNCS (double_postdec_inexact, double, , --, 0,
-DBL_EPSILON / 2, NOT_1, FE_INEXACT,
1, 0)
#if FLT_EVAL_METHOD == 0
TEST_FUNCS (long_long_sub_double_inexact, long long, , -= 2 / DBL_EPSILON, 0,
-1, NOT_0, FE_INEXACT,
2 / DBL_EPSILON, 0)
#endif
TEST_FUNCS (complex_double_sub_overflow, _Complex double, , -= DBL_MAX, 0,
-DBL_MAX, REAL_ISINF, FE_OVERFLOW | FE_INEXACT,
0, 0)
TEST_FUNCS (double_mul_invalid, double, , *= __builtin_inf (), 0,
__builtin_inf (), __builtin_isinf, 0,
0, FE_INVALID)
TEST_FUNCS (double_mul_overflow, double, , *= DBL_MAX, 0,
DBL_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
0, 0)
TEST_FUNCS (double_mul_overflow_float, double, , *= FLT_MAX, 0,
DBL_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
0, 0)
TEST_FUNCS (double_mul_underflow, double, , *= DBL_MIN, 0,
DBL_MIN, IS_0, FE_UNDERFLOW | FE_INEXACT,
1, 0)
TEST_FUNCS (double_mul_inexact, double, , *= 1 + DBL_EPSILON, 0,
1 + DBL_EPSILON, NOT_0, FE_INEXACT,
0, 0)
TEST_FUNCS (double_mul_inexact_int, double, , *= 3, 0,
1 + DBL_EPSILON, NOT_0, FE_INEXACT,
0, 0)
#if FLT_EVAL_METHOD == 0
TEST_FUNCS(long_long_mul_double_inexact, long long, , *= 3.0, 0,
1 + 1 / DBL_EPSILON, NOT_0, FE_INEXACT,
0, 0)
#endif
TEST_FUNCS (complex_double_mul_overflow, _Complex double, , *= DBL_MAX, 0,
DBL_MAX, REAL_ISINF, FE_OVERFLOW | FE_INEXACT,
0, 0)
TEST_FUNCS (double_div_invalid_divbyzero, double, , /= 0.0, 0,
1, __builtin_isinf, FE_DIVBYZERO,
0, FE_INVALID)
TEST_FUNCS (double_div_overflow, double, , /= DBL_MIN, 0,
DBL_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
0, 0)
TEST_FUNCS (double_div_underflow, double, , /= DBL_MAX, 0,
DBL_MIN, IS_0, FE_UNDERFLOW | FE_INEXACT,
DBL_MAX, 0)
TEST_FUNCS (double_div_inexact, double, , /= 3.0, 0,
1, NOT_0, FE_INEXACT,
0, 0)
TEST_FUNCS (double_div_inexact_int, double, , /= 3, 0,
1, NOT_0, FE_INEXACT,
0, 0)
TEST_FUNCS (int_div_double_inexact, int, , /= 3.0, 0,
4, NOT_0, FE_INEXACT,
0, 0)
TEST_FUNCS (complex_double_div_overflow, _Complex double, , /= DBL_MIN, 0,
DBL_MAX, REAL_ISINF, FE_OVERFLOW | FE_INEXACT,
0, 0)
TEST_FUNCS (long_double_add_invalid, long double, , += __builtin_infl (), 0,
0, __builtin_isinf, 0,
-__builtin_infl (), FE_INVALID)
#if LDBL_MANT_DIG != 106
TEST_FUNCS (long_double_add_overflow, long double, , += LDBL_MAX, 0,
LDBL_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
0, 0)
#define NOT_LDBL_EPSILON_2(X) ((X) != LDBL_EPSILON / 2)
TEST_FUNCS (long_double_add_inexact, long double, , += LDBL_EPSILON / 2, 0,
1.0L, NOT_LDBL_EPSILON_2, FE_INEXACT,
0, 0)
TEST_FUNCS (long_double_add_inexact_int, long double, , += 1, 0,
LDBL_EPSILON / 2, NOT_0, FE_INEXACT,
-1, 0)
TEST_FUNCS (long_double_preinc_inexact, long double, ++, , 0,
LDBL_EPSILON / 2, NOT_0, FE_INEXACT,
-1, 0)
TEST_FUNCS (long_double_postinc_inexact, long double, , ++, 0,
LDBL_EPSILON / 2, NOT_MINUS_1, FE_INEXACT,
-1, 0)
TEST_FUNCS (complex_long_double_add_overflow, _Complex long double, , += LDBL_MAX, 0,
LDBL_MAX, REAL_ISINF, FE_OVERFLOW | FE_INEXACT,
0, 0)
#endif
TEST_FUNCS (long_double_sub_invalid, long double, , -= __builtin_infl (), 0,
0, __builtin_isinf, 0,
__builtin_infl (), FE_INVALID)
#if LDBL_MANT_DIG != 106
TEST_FUNCS (long_double_sub_overflow, long double, , -= LDBL_MAX, 0,
-LDBL_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
0, 0)
#define NOT_MINUS_LDBL_EPSILON_2(X) ((X) != -LDBL_EPSILON / 2)
TEST_FUNCS (long_double_sub_inexact, long double, , -= LDBL_EPSILON / 2, 0,
-1.0L, NOT_MINUS_LDBL_EPSILON_2, FE_INEXACT,
0, 0)
TEST_FUNCS (long_double_sub_inexact_int, long double, , -= 1, 0,
-LDBL_EPSILON / 2, NOT_0, FE_INEXACT,
1, 0)
TEST_FUNCS (long_double_predec_inexact, long double, --, , 0,
-LDBL_EPSILON / 2, NOT_0, FE_INEXACT,
1, 0)
TEST_FUNCS (long_double_postdec_inexact, long double, , --, 0,
-LDBL_EPSILON / 2, NOT_1, FE_INEXACT,
1, 0)
TEST_FUNCS (complex_long_double_sub_overflow, _Complex long double, , -= LDBL_MAX, 0,
-LDBL_MAX, REAL_ISINF, FE_OVERFLOW | FE_INEXACT,
0, 0)
#endif
TEST_FUNCS (long_double_mul_invalid, long double, , *= __builtin_infl (), 0,
__builtin_infl (), __builtin_isinf, 0,
0, FE_INVALID)
TEST_FUNCS (long_double_mul_overflow, long double, , *= LDBL_MAX, 0,
LDBL_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
0, 0)
TEST_FUNCS (long_double_mul_overflow_float, long double, , *= FLT_MAX, 0,
LDBL_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
0, 0)
TEST_FUNCS (long_double_mul_overflow_double, long double, , *= DBL_MAX, 0,
LDBL_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
0, 0)
TEST_FUNCS (long_double_mul_underflow, long double, , *= LDBL_MIN, 0,
LDBL_MIN, IS_0, FE_UNDERFLOW | FE_INEXACT,
1, 0)
#if LDBL_MANT_DIG != 106
TEST_FUNCS (long_double_mul_inexact, long double, , *= 1 + LDBL_EPSILON, 0,
1 + LDBL_EPSILON, NOT_0, FE_INEXACT,
0, 0)
TEST_FUNCS (long_double_mul_inexact_int, long double, , *= 3, 0,
1 + LDBL_EPSILON, NOT_0, FE_INEXACT,
0, 0)
#endif
TEST_FUNCS (complex_long_double_mul_overflow, _Complex long double, , *= LDBL_MAX, 0,
LDBL_MAX, REAL_ISINF, FE_OVERFLOW | FE_INEXACT,
0, 0)
TEST_FUNCS (long_double_div_invalid_divbyzero, long double, , /= 0.0L, 0,
1, __builtin_isinf, FE_DIVBYZERO,
0, FE_INVALID)
TEST_FUNCS (long_double_div_overflow, long double, , /= LDBL_MIN, 0,
LDBL_MAX, __builtin_isinf, FE_OVERFLOW | FE_INEXACT,
0, 0)
TEST_FUNCS (long_double_div_underflow, long double, , /= LDBL_MAX, 0,
LDBL_MIN, IS_0, FE_UNDERFLOW | FE_INEXACT,
LDBL_MAX, 0)
TEST_FUNCS (long_double_div_inexact, long double, , /= 3.0L, 0,
1, NOT_0, FE_INEXACT,
0, 0)
TEST_FUNCS (long_double_div_inexact_int, long double, , /= 3, 0,
1, NOT_0, FE_INEXACT,
0, 0)
TEST_FUNCS (int_div_long_double_inexact, int, , /= 3.0L, 0,
4, NOT_0, FE_INEXACT,
0, 0)
TEST_FUNCS (complex_long_double_div_overflow, _Complex long double, , /= LDBL_MIN, 0,
LDBL_MAX, REAL_ISINF, FE_OVERFLOW | FE_INEXACT,
0, 0)
int
main (void)
{
int ret = 0;
ret |= test_main_float_add_invalid ();
ret |= test_main_float_add_invalid_prev ();
ret |= test_main_float_add_overflow ();
ret |= test_main_float_add_overflow_prev ();
ret |= test_main_float_add_overflow_double ();
ret |= test_main_float_add_overflow_long_double ();
ret |= test_main_float_add_inexact ();
ret |= test_main_float_add_inexact_int ();
ret |= test_main_float_preinc_inexact ();
ret |= test_main_float_postinc_inexact ();
#if FLT_EVAL_METHOD == 0
ret |= test_main_long_add_float_inexact ();
#endif
ret |= test_main_complex_float_add_overflow ();
ret |= test_main_float_sub_invalid ();
ret |= test_main_float_sub_overflow ();
ret |= test_main_float_sub_inexact ();
ret |= test_main_float_sub_inexact_int ();
ret |= test_main_float_predec_inexact ();
ret |= test_main_float_postdec_inexact ();
#if FLT_EVAL_METHOD == 0
ret |= test_main_long_sub_float_inexact ();
#endif
ret |= test_main_complex_float_sub_overflow ();
ret |= test_main_float_mul_invalid ();
ret |= test_main_float_mul_overflow ();
ret |= test_main_float_mul_underflow ();
ret |= test_main_float_mul_inexact ();
ret |= test_main_float_mul_inexact_int ();
#if FLT_EVAL_METHOD == 0
ret |= test_main_long_mul_float_inexact ();
#endif
ret |= test_main_complex_float_mul_overflow ();
ret |= test_main_float_div_invalid_divbyzero ();
ret |= test_main_float_div_overflow ();
ret |= test_main_float_div_underflow ();
ret |= test_main_float_div_inexact ();
ret |= test_main_float_div_inexact_int ();
ret |= test_main_int_div_float_inexact ();
ret |= test_main_complex_float_div_overflow ();
ret |= test_main_double_add_invalid ();
ret |= test_main_double_add_overflow ();
ret |= test_main_double_add_overflow_long_double ();
ret |= test_main_double_add_inexact ();
ret |= test_main_double_add_inexact_int ();
ret |= test_main_double_preinc_inexact ();
ret |= test_main_double_postinc_inexact ();
#if FLT_EVAL_METHOD == 0
ret |= test_main_long_long_add_double_inexact ();
#endif
ret |= test_main_complex_double_add_overflow ();
ret |= test_main_double_sub_invalid ();
ret |= test_main_double_sub_overflow ();
ret |= test_main_double_sub_inexact ();
ret |= test_main_double_sub_inexact_int ();
ret |= test_main_double_predec_inexact ();
ret |= test_main_double_postdec_inexact ();
#if FLT_EVAL_METHOD == 0
ret |= test_main_long_long_sub_double_inexact ();
#endif
ret |= test_main_complex_double_sub_overflow ();
ret |= test_main_double_mul_invalid ();
ret |= test_main_double_mul_overflow ();
ret |= test_main_double_mul_overflow_float ();
ret |= test_main_double_mul_underflow ();
ret |= test_main_double_mul_inexact ();
ret |= test_main_double_mul_inexact_int ();
#if FLT_EVAL_METHOD == 0
ret |= test_main_long_long_mul_double_inexact ();
#endif
ret |= test_main_complex_double_mul_overflow ();
ret |= test_main_double_div_invalid_divbyzero ();
ret |= test_main_double_div_overflow ();
ret |= test_main_double_div_underflow ();
ret |= test_main_double_div_inexact ();
ret |= test_main_double_div_inexact_int ();
ret |= test_main_int_div_double_inexact ();
ret |= test_main_complex_double_div_overflow ();
ret |= test_main_long_double_add_invalid ();
#if LDBL_MANT_DIG != 106
ret |= test_main_long_double_add_overflow ();
ret |= test_main_long_double_add_inexact ();
ret |= test_main_long_double_add_inexact_int ();
ret |= test_main_long_double_preinc_inexact ();
ret |= test_main_long_double_postinc_inexact ();
ret |= test_main_complex_long_double_add_overflow ();
#endif
ret |= test_main_long_double_sub_invalid ();
#if LDBL_MANT_DIG != 106
ret |= test_main_long_double_sub_overflow ();
ret |= test_main_long_double_sub_inexact ();
ret |= test_main_long_double_sub_inexact_int ();
ret |= test_main_long_double_predec_inexact ();
ret |= test_main_long_double_postdec_inexact ();
ret |= test_main_complex_long_double_sub_overflow ();
#endif
ret |= test_main_long_double_mul_invalid ();
ret |= test_main_long_double_mul_overflow ();
ret |= test_main_long_double_mul_overflow_float ();
ret |= test_main_long_double_mul_overflow_double ();
ret |= test_main_long_double_mul_underflow ();
#if LDBL_MANT_DIG != 106
ret |= test_main_long_double_mul_inexact ();
ret |= test_main_long_double_mul_inexact_int ();
#endif
ret |= test_main_complex_long_double_mul_overflow ();
ret |= test_main_long_double_div_invalid_divbyzero ();
ret |= test_main_long_double_div_overflow ();
ret |= test_main_long_double_div_underflow ();
ret |= test_main_long_double_div_inexact ();
ret |= test_main_long_double_div_inexact_int ();
ret |= test_main_int_div_long_double_inexact ();
ret |= test_main_complex_long_double_div_overflow ();
if (ret != 0)
abort ();
else
exit (0);
}
I won't have time to look at these for a while
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-decl.c -std=gnu++11 scan-assembler-times nop 2
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-decl.c -std=gnu++11 scan-assembler-times nop 2
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-decl.c -std=gnu++11 scan-assembler-times nop 2
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-decl.c -std=gnu++11 scan-assembler-times nop 2
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-decl.c -std=gnu++14 scan-assembler-times nop 2
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-decl.c -std=gnu++14 scan-assembler-times nop 2
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-decl.c -std=gnu++14 scan-assembler-times nop 2
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-decl.c -std=gnu++14 scan-assembler-times nop 2
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-decl.c -std=gnu++98 scan-assembler-times nop 2
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-decl.c -std=gnu++98 scan-assembler-times nop 2
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-decl.c -std=gnu++98 scan-assembler-times nop 2
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-decl.c -std=gnu++98 scan-assembler-times nop 2
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-default.c -std=gnu++11 scan-assembler-times nop 3
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-default.c -std=gnu++11 scan-assembler-times nop 3
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-default.c -std=gnu++11 scan-assembler-times nop 3
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-default.c -std=gnu++11 scan-assembler-times nop 3
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-default.c -std=gnu++14 scan-assembler-times nop 3
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-default.c -std=gnu++14 scan-assembler-times nop 3
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-default.c -std=gnu++14 scan-assembler-times nop 3
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-default.c -std=gnu++14 scan-assembler-times nop 3
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-default.c -std=gnu++98 scan-assembler-times nop 3
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-default.c -std=gnu++98 scan-assembler-times nop 3
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-default.c -std=gnu++98 scan-assembler-times nop 3
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-default.c -std=gnu++98 scan-assembler-times nop 3
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-definition.c -std=gnu++11 scan-assembler-times nop 1
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-definition.c -std=gnu++11 scan-assembler-times nop 1
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-definition.c -std=gnu++11 scan-assembler-times nop 1
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-definition.c -std=gnu++11 scan-assembler-times nop 1
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-definition.c -std=gnu++14 scan-assembler-times nop 1
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-definition.c -std=gnu++14 scan-assembler-times nop 1
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-definition.c -std=gnu++14 scan-assembler-times nop 1
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-definition.c -std=gnu++14 scan-assembler-times nop 1
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-definition.c -std=gnu++98 scan-assembler-times nop 1
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-definition.c -std=gnu++98 scan-assembler-times nop 1
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-definition.c -std=gnu++98 scan-assembler-times nop 1
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: c-c++-common/patchable_function_entry-definition.c -std=gnu++98 scan-assembler-times nop 1
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: g++.dg/eh/registers1.C -std=gnu++11 execution test
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: g++.dg/eh/registers1.C -std=gnu++11 execution test
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: g++.dg/eh/registers1.C -std=gnu++14 execution test
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: g++.dg/eh/registers1.C -std=gnu++14 execution test
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: g++.dg/eh/registers1.C -std=gnu++98 execution test
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: g++.dg/eh/registers1.C -std=gnu++98 execution test
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: g++.dg/template/nontype10.C -std=c++11 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: g++.dg/template/nontype10.C -std=c++11 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: g++.dg/template/nontype10.C -std=c++14 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: g++.dg/template/nontype10.C -std=c++14 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: g++.dg/template/nontype10.C -std=c++98 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/g++/g++.sum:FAIL: g++.dg/template/nontype10.C -std=c++98 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: c-c++-common/patchable_function_entry-decl.c -Wc++-compat scan-assembler-times nop 2
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: c-c++-common/patchable_function_entry-decl.c -Wc++-compat scan-assembler-times nop 2
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: c-c++-common/patchable_function_entry-decl.c -Wc++-compat scan-assembler-times nop 2
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: c-c++-common/patchable_function_entry-decl.c -Wc++-compat scan-assembler-times nop 2
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: c-c++-common/patchable_function_entry-default.c -Wc++-compat scan-assembler-times nop 3
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: c-c++-common/patchable_function_entry-default.c -Wc++-compat scan-assembler-times nop 3
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: c-c++-common/patchable_function_entry-default.c -Wc++-compat scan-assembler-times nop 3
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: c-c++-common/patchable_function_entry-default.c -Wc++-compat scan-assembler-times nop 3
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: c-c++-common/patchable_function_entry-definition.c -Wc++-compat scan-assembler-times nop 1
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: c-c++-common/patchable_function_entry-definition.c -Wc++-compat scan-assembler-times nop 1
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: c-c++-common/patchable_function_entry-definition.c -Wc++-compat scan-assembler-times nop 1
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: c-c++-common/patchable_function_entry-definition.c -Wc++-compat scan-assembler-times nop 1
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: gcc.dg/pr21643.c scan-tree-dump-times reassoc1 "Optimizing range tests c_[0-9]*.D. -.0, 31. and -.32, 32.[\n\r]* into" 6
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: gcc.dg/pr21643.c scan-tree-dump-times reassoc1 "Optimizing range tests c_[0-9]*.D. -.0, 31. and -.32, 32.[\n\r]* into" 6
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: gcc.dg/pr21643.c scan-tree-dump-times reassoc1 "Optimizing range tests c_[0-9]*.D. -.0, 31. and -.32, 32.[\n\r]* into" 6
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: gcc.dg/pr21643.c scan-tree-dump-times reassoc1 "Optimizing range tests c_[0-9]*.D. -.0, 31. and -.32, 32.[\n\r]* into" 6
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: gcc.dg/pr28796-2.c execution test
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: gcc.dg/tree-ssa/phi-opt-11.c scan-tree-dump-times optimized "if" 0
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: gcc.dg/tree-ssa/phi-opt-11.c scan-tree-dump-times optimized "if" 0
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: gcc.dg/tree-ssa/phi-opt-11.c scan-tree-dump-times optimized "if" 0
build-gcc-linux-stage2/gcc/testsuite/gcc/gcc.sum:FAIL: gcc.dg/tree-ssa/phi-opt-11.c scan-tree-dump-times optimized "if" 0
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_2.f90 -O0 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_2.f90 -O0 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_2.f90 -O1 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_2.f90 -O1 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_2.f90 -O2 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_2.f90 -O2 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_2.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_2.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_2.f90 -O3 -g execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_2.f90 -O3 -g execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_2.f90 -Os execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_2.f90 -Os execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_denormal_2.f90 -O0 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_denormal_2.f90 -O0 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_denormal_2.f90 -O1 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_denormal_2.f90 -O1 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_denormal_2.f90 -O2 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_denormal_2.f90 -O2 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_denormal_2.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_denormal_2.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_denormal_2.f90 -O3 -g execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_denormal_2.f90 -O3 -g execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_denormal_2.f90 -Os execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/default_format_denormal_2.f90 -Os execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O1 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O1 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O1 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O1 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O2 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O2 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O2 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O2 (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O3 -g (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O3 -g (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O3 -g (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -O3 -g (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -Os (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -Os (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -Os (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/elemental_subroutine_3.f90 -Os (test for excess errors)
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_en.f90 -O0 scan-file All kinds rounded to nearest
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_en.f90 -O1 scan-file All kinds rounded to nearest
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_en.f90 -O2 scan-file All kinds rounded to nearest
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_en.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions scan-file All kinds rounded to nearest
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_en.f90 -O3 -g scan-file All kinds rounded to nearest
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_en.f90 -Os scan-file All kinds rounded to nearest
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_pf.f90 -O0 output pattern test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_pf.f90 -O1 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_pf.f90 -O1 output pattern test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_pf.f90 -O2 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_pf.f90 -O2 output pattern test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_pf.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_pf.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions output pattern test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_pf.f90 -O3 -g execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_pf.f90 -O3 -g output pattern test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/fmt_pf.f90 -Os output pattern test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_1.f90 -O0 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_1.f90 -O1 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_1.f90 -O2 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_1.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_1.f90 -O3 -g execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_1.f90 -Os execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_2.f90 -O0 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_2.f90 -O1 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_2.f90 -O1 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_2.f90 -O2 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_2.f90 -O2 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_2.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_2.f90 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_2.f90 -O3 -g execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_2.f90 -O3 -g execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/large_real_kind_form_io_2.f90 -Os execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/matmul_15.f90 -O execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/matmul_15.f90 -O execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/round_2.f03 -O0 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/round_2.f03 -O1 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/round_2.f03 -O2 execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/round_2.f03 -O3 -fomit-frame-pointer -funroll-loops -fpeel-loops -ftracer -finline-functions execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/round_2.f03 -O3 -g execution test
build-gcc-linux-stage2/gcc/testsuite/gfortran/gfortran.sum:FAIL: gfortran.dg/round_2.f03 -Os execution test
A full example of this brokenness can be seen in the "smp" example from https://github.com/sifive/freedom-e-sdk. The problem appears to be that when emitting "ra" into the FDE we end up with the wrong offset. I've reduced the test case a bit. When compiling this file
$ cat smp.c
#define ATOMIC_INIT(x) \
{ \
.counter = (x), \
}
typedef struct {
int counter;
} atomic_t;
static inline int atomic_xchg(atomic_t *v, int n)
{
register int c;
__asm__ __volatile__ (
"amoswap.w.aqrl %0, %2, %1"
: "=r" (c), "+A" (v->counter)
: "r" (n));
return c;
}
static inline void mb(void)
{
__asm__ __volatile__ ("fence");
}
atomic_t tty_lock = ATOMIC_INIT(0);
void get_lock(atomic_t *lock)
{
while (atomic_xchg(lock, 1) == 1);
mb();
}
void put_lock(atomic_t *lock)
{
mb();
atomic_xchg(lock, 0);
}
int secondary_main(int hartid)
{
volatile int counter;
while (1) {
get_lock(&tty_lock);
write(1, "hello world from hart ", 22);
char s[] = {'0', '\n', '\0'};
s[0] += hartid;
write(1, s, 2);
put_lock(&tty_lock);
for (counter = 0; counter < 10000 + 100*hartid; ++counter)
mb();
}
}
int main()
{
return secondary_main(0);
}
I appear to get an incorrect FDE entry spit out into the assembly file. The "-O2" code looks like this
secondary_main:
.LFB4:
.loc 1 41 0
.LVL6:
add sp,sp,-96
.LCFI0:
sd s2,64(sp)
.LCFI1:
.LBB35:
.loc 1 52 0
li s2,100
mulw s2,s2,a0
li a5,8192
addw a0,a0,48
.LVL7:
addw a5,a5,1807
.LBE35:
.loc 1 41 0
sd s0,80(sp)
sd s1,72(sp)
sd s3,56(sp)
sd s4,48(sp)
sd s5,40(sp)
sd s6,32(sp)
sd s7,24(sp)
sd ra,88(sp)
.LCFI2:
and s4,a0,0xff
lui s0,%hi(tty_lock)
lui s5,%hi(.LC0)
but the FDE entry looks like this
.LASFDE4:
.4byte .Lframe0
.8byte .LFB4
.8byte .LFE4-.LFB4
.byte 0x4
.4byte .LCFI0-.LFB4
.byte 0xe
.byte 0x60
.byte 0x4
.4byte .LCFI1-.LCFI0
.byte 0x92
.byte 0x8
.byte 0x4
.4byte .LCFI2-.LCFI1
.byte 0x88
.byte 0x4
.byte 0x89
.byte 0x6
.byte 0x93
.byte 0xa
.byte 0x94
.byte 0xc
.byte 0x95
.byte 0xe
.byte 0x96
.byte 0x10
.byte 0x97
.byte 0x12
.byte 0x81
.byte 0x2
.align 3
This decodes to something like this (I've jumped to a slightly different toolchain here, so it might be a touch off)
00000040 000000000000003c 00000000 FDE cie=00000000 pc=0000000040400206..00000000404002a4
DW_CFA_advance_loc4: 2 to 0000000040400208
DW_CFA_def_cfa_offset: 96
DW_CFA_advance_loc4: 2 to 000000004040020a
DW_CFA_offset: r18 at cfa-32
DW_CFA_advance_loc4: 34 to 000000004040022c
DW_CFA_offset: r8 at cfa-16
DW_CFA_offset: r9 at cfa-24
DW_CFA_offset: r19 at cfa-40
DW_CFA_offset: r20 at cfa-48
DW_CFA_offset: r21 at cfa-56
DW_CFA_offset: r22 at cfa-64
DW_CFA_offset: r23 at cfa-72
DW_CFA_offset: r1 at cfa-8
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
DW_CFA_nop
The problem is that last CFA entry:
.byte 0x81
.byte 0x2
which decodes to
DW_CFA_offset: r1 at cfa-8
because our CFA offset is "-4". This doesn't match the generated assembly
44: ec86 sd ra,88(sp)
I'm not sure what's going on, so I'm dumping a bug in here for now...
This fail is come from C front-end due to RV64's TRULY_NOOP_TRUNCATION, and mips64el-elf toolchain will also fail for this case, so I think we should report to upstream.
Arch: RV64I and RV64G
How to reproduce:
$ riscv64-unknown-linux-gnu-gcc pr66178.c
pr66178.c: In function 'test':
pr66178.c:3:21: error: initializer element is not computable at load time
static int a = ((char *)&&l1-(char *)&&l2)-1;
Code for pr66178.c:
int test(void)
{
static int a = ((char *)&&l1-(char *)&&l2)-1;
l1:
l2:
return a;
}
int test2(void)
{
static int a = ((char *)&&l2-(char *)&&l3)+((char *)&&l1-(char *)&&l2);
l1:
l2:
l3:
return a;
}
Note:
How to build a simple mips64el-elf gcc:
$ <path-to>/gcc/configure --prefix=<PREFIX> --with-abi=64 --target=mips64el-elf
$ make all-gcc
$ make install-gcc
$ mips64el-elf-gcc pr66178.c
pr66178.c: In function ‘test’:
pr66178.c:3:21: error: initializer element is not computable at load time
static int a = ((char *)&&l1-(char *)&&l2)-1;
^
I think it's graphite's bug, so don't waste time to investigate until other bug is clean.
Arch: RV32I, RV32G, RV64I, RV64G
Option: -O2 -fgraphite-identity
How to reproduce:
$ riscv64-unknown-linux-gnu-gcc id-pr46845.c -O2 -fgraphite-identity
id-pr46845.c: In function 'foo':
id-pr46845.c:17:1: internal compiler error: in commit_one_edge_insertion, at cfgrtl.c:2070
}
^
0x633c58 commit_one_edge_insertion(edge_def*)
/home/kito/riscv-workspace/riscv-gnu-toolchain/riscv-gcc/gcc/cfgrtl.c:2070
0x621953 execute
/home/kito/riscv-workspace/riscv-gnu-toolchain/riscv-gcc/gcc/cfgexpand.c:6408
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
Code for id-pr46845.c:
typedef float V2SF __attribute__ ((vector_size (128)));
V2SF
foo (int x, V2SF a)
{
V2SF b;
if (x & 42)
b = a;
else
b = a + (V2SF) {1.0f/0.0f - 1.0f/0.0f, 1.0f/0.0f - 1.0f/0.0f};
while (x--)
a += b;
return a;
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.