On Sun, May 19, 2019 at 5:22 AM Andreas Schwab <sch...@linux-m68k.org> wrote:
> ../../../libgo/go/runtime/mbitmap.go: In function 
> ‘runtime.setMarked.runtime.markBits’:
> ../../../libgo/go/runtime/mbitmap.go:291:9: internal compiler error: 
> Segmentation fault
>   291 |  atomic.Or8(m.bytep, m.mask)
>       |         ^

This is failing for RISC-V because __atomic_or_fetch_1 isn't a
built-in function that can be expanded inline.  You have to call the
library function in libatomic.  The C front-end is registering all of
the built-in functions, but it looks like the go front-end is only
registering functions it thinks it needs and this list is incomplete.
In expand_builtin, case BUILT_IN_ATOMIC_OR_FETCH_1, the external
library call for this gets set to BUILT_IN_ATOMIC_FETCH_OR_1.  Then in
expand_builtin_atomic_fetch_op when we call builtin_decl_explicit
(ext_call) it returns NULL.  This is because the go front end
registered BUILT_IN_ATOMIC_OR_FETCH_1 as a built-in, but did not
register BUILT_IN_ATOMIC_FETCH_OR_1 as a built-in.  The NULL return
from builtin_decl_explicit gives us an ADDR_EXPR with a NULL operand
which eventually causes the internal compiler error.  It looks like
the same thing is done with all of the op_fetch built-ins, so use of
any of them means that the fetch_op built-in also has to be
registered.  I verified with a quick hack that I need both
BUILT_IN_ATOMIC_FETCH_OR_1 and BUILT_IN_ATOMIC_FETCH_AND_1 defined as
built-ins to make a RISC-V go build work.  I haven't done any testing
yet.

Jim
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index 1b26f2bac93..91043b51463 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -871,6 +871,8 @@ Gcc_backend::Gcc_backend()
                                NULL_TREE);
   this->define_builtin(BUILT_IN_ATOMIC_AND_FETCH_1, "__atomic_and_fetch_1", 
NULL,
                        t, false, false);
+  this->define_builtin(BUILT_IN_ATOMIC_FETCH_AND_1, "__atomic_fetch_and_1", 
NULL,
+                       t, false, false);
 
   t = build_function_type_list(unsigned_char_type_node,
                                ptr_type_node,
@@ -879,6 +881,8 @@ Gcc_backend::Gcc_backend()
                                NULL_TREE);
   this->define_builtin(BUILT_IN_ATOMIC_OR_FETCH_1, "__atomic_or_fetch_1", NULL,
                        t, false, false);
+  this->define_builtin(BUILT_IN_ATOMIC_FETCH_OR_1, "__atomic_fetch_or_1", NULL,
+                       t, false, false);
 }
 
 // Get an unnamed integer type.

Reply via email to