Bug 68467 - libgcc, compilation for target m68k-linux breaks in linux_atomic.c
Summary: libgcc, compilation for target m68k-linux breaks in linux_atomic.c
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 5.2.0
: P4 normal
Target Milestone: 7.4
Assignee: Jeffrey A. Law
URL:
Keywords: build
: 53833 (view as bug list)
Depends on:
Blocks:
 
Reported: 2015-11-21 08:09 UTC by angelo
Modified: 2018-01-29 21:02 UTC (History)
6 users (show)

See Also:
Host:
Target: m68k-linux
Build:
Known to work:
Known to fail:
Last reconfirmed: 2016-11-07 00:00:00


Attachments
config log (1.33 KB, text/plain)
2015-11-21 08:09 UTC, angelo
Details
build log (19.33 KB, text/plain)
2015-11-21 08:10 UTC, angelo
Details
preprocessed source (1.33 KB, text/plain)
2016-11-22 15:56 UTC, Joseph S. Myers
Details

Note You need to log in before you can comment on or make changes to this bug.
Description angelo 2015-11-21 08:09:51 UTC
Created attachment 36791 [details]
config log

Dear all,

after had filled 68466, and applied the workaround mentioned in it, i can fully compile gcc. Btw, inside libgcc i see only M68000 code, and not coldfire variants.

So i am trying with different configuration options, as:

EXTRA_GCC_CONF="--enable-multilib --with-arch=cf --with-newlib --with-system-zlib"

With config options above, i get following error compiling:

/home/angelo/archivio/aziende/sysam/buildall/m68k/gcc/./gcc/xgcc -B/home/angelo/archivio/aziende/sysam/buildall/m68k/gcc/./gcc/ -B/home/angelo/archivio/aziende/sysam/output/m68k-linux/bin/ -B/home/angelo/archivio/aziende/sysam/output/m68k-linux/lib/ -isystem /home/angelo/archivio/aziende/sysam/output/m68k-linux/include -isystem /home/angelo/archivio/aziende/sysam/output/m68k-linux/sys-include    -g -O2 -mcpu=54455 -Wa,-mno-mac -O2  -g -O2 -DIN_GCC  -DCROSS_DIRECTORY_STRUCTURE  -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition  -isystem ./include   -fPIC -g -DIN_LIBGCC2 -fbuilding-libgcc -fno-stack-protector -Dinhibit_libc  -fPIC -I. -I. -I../../.././gcc -I/home/angelo/archivio/aziende/sysam/buildall/gcc-5.2.0/libgcc -I/home/angelo/archivio/aziende/sysam/buildall/gcc-5.2.0/libgcc/. -I/home/angelo/archivio/aziende/sysam/buildall/gcc-5.2.0/libgcc/../gcc -I/home/angelo/archivio/aziende/sysam/buildall/gcc-5.2.0/libgcc/../include  -DHAVE_CC_TLS  -o linux-atomic.o -MT linux-atomic.o -MD -MP -MF linux-atomic.dep  -c /home/angelo/archivio/aziende/sysam/buildall/gcc-5.2.0/libgcc/config/m68k/linux-atomic.c -fvisibility=hidden -DHIDE_EXPORTS
/home/angelo/archivio/aziende/sysam/buildall/gcc-5.2.0/libgcc/config/m68k/linux-atomic.c: In function '__sync_lock_test_and_set_4':
/home/angelo/archivio/aziende/sysam/buildall/gcc-5.2.0/libgcc/config/m68k/linux-atomic.c:207:15: warning: left-hand operand of comma expression has no effect [-Wunused-value]
 #define COMMA ,
               ^
/home/angelo/archivio/aziende/sysam/buildall/gcc-5.2.0/libgcc/config/m68k/linux-atomic.c:80:31: note: in definition of macro 'WORD_SYNC_OP'
       newval = PFX_OP (oldval INF_OP val);    \


Compiling on x86_64 os
$ gcc --version
gcc (Debian 5.2.1-21) 5.2.1 20151003
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.



I attach configure and build logs.

Regards
Comment 1 angelo 2015-11-21 08:10:22 UTC
Created attachment 36792 [details]
build log
Comment 2 angelo 2016-04-17 19:43:45 UTC
Well the final error is :

/home/angelo/archivio/aziende/sysam/buildall/gcc-5.2.0/libgcc/config/m68k/linux-atomic.c:198:13: internal compiler error: in emit_library_call_value_1, at calls.c:4401
     return (__sync_val_compare_and_swap_##WIDTH (ptr, oldval, newval) \
             ^
/home/angelo/archivio/aziende/sysam/buildall/gcc-5.2.0/libgcc/config/m68k/linux-atomic.c:203:1: note: in expansion of macro 'SUBWORD_BOOL_CAS'
 SUBWORD_BOOL_CAS (unsigned char,  1)

I tried also gcc 5.3.0, same error using --with-arch=cf.

Seems like m68k branch is not considered at all.
Comment 3 Joseph S. Myers 2016-11-07 16:33:23 UTC
Confirmed.  Building libgcc for m68k-linux-gnu --with-arch=cf fails for every GCC version from 4.7 onwards (4.6 didn't have linux-atomic.c, so I'm not sure if this counts as a regression).

Errors with current mainline:

/scratch/jmyers/glibc/many7/src/gcc/libgcc/config/m68k/linux-atomic.c: In function '__sync_bool_compare_and_swap_1':
/scratch/jmyers/glibc/many7/src/gcc/libgcc/config/m68k/linux-atomic.c:197:13: internal compiler error: in emit_library_call_value_1, at calls.c:4624
     return (__sync_val_compare_and_swap_##WIDTH (ptr, oldval, newval) \
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/scratch/jmyers/glibc/many7/src/gcc/libgcc/config/m68k/linux-atomic.c:202:1: note: in expansion of macro 'SUBWORD_BOOL_CAS'
 SUBWORD_BOOL_CAS (unsigned char,  1)
 ^~~~~~~~~~~~~~~~
0x6a7dc7 emit_library_call_value_1
        /scratch/jmyers/glibc/many7/src/gcc/gcc/calls.c:4623
0x6acb5f emit_library_call_value(rtx_def*, rtx_def*, libcall_type, machine_mode, int, ...)
        /scratch/jmyers/glibc/many7/src/gcc/gcc/calls.c:4817
0x9e576e expand_atomic_compare_and_swap(rtx_def**, rtx_def**, rtx_def*, rtx_def*, rtx_def*, bool, memmodel, memmodel)
        /scratch/jmyers/glibc/many7/src/gcc/gcc/optabs.c:6210
0x690b1b expand_builtin_compare_and_swap
        /scratch/jmyers/glibc/many7/src/gcc/gcc/builtins.c:5059
0x69db77 expand_builtin(tree_node*, rtx_def*, rtx_def*, machine_mode, int)
        /scratch/jmyers/glibc/many7/src/gcc/gcc/builtins.c:6606
0x7bdd4d expand_expr_real_1(tree_node*, rtx_def*, machine_mode, expand_modifier, rtx_def**, bool)
        /scratch/jmyers/glibc/many7/src/gcc/gcc/expr.c:10773
0x7c8e4f store_expr_with_bounds(tree_node*, rtx_def*, int, bool, bool, tree_node*)
        /scratch/jmyers/glibc/many7/src/gcc/gcc/expr.c:5548
0x7ca790 expand_assignment(tree_node*, tree_node*, bool)
        /scratch/jmyers/glibc/many7/src/gcc/gcc/expr.c:5317
0x6bb4ba expand_call_stmt
        /scratch/jmyers/glibc/many7/src/gcc/gcc/cfgexpand.c:2666
0x6bb4ba expand_gimple_stmt_1
        /scratch/jmyers/glibc/many7/src/gcc/gcc/cfgexpand.c:3581
0x6bb4ba expand_gimple_stmt
        /scratch/jmyers/glibc/many7/src/gcc/gcc/cfgexpand.c:3747
0x6bd28e expand_gimple_basic_block
        /scratch/jmyers/glibc/many7/src/gcc/gcc/cfgexpand.c:5754
0x6c3176 execute
        /scratch/jmyers/glibc/many7/src/gcc/gcc/cfgexpand.c:6368
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.
Comment 4 Jeffrey A. Law 2016-11-17 18:53:43 UTC
*** Bug 53833 has been marked as a duplicate of this bug. ***
Comment 5 Joseph S. Myers 2016-11-22 15:56:56 UTC
Created attachment 40117 [details]
preprocessed source

Preprocessed source of file causing ICE attached.  Compile with: -S -g -O2 -fPIC -fbuilding-libgcc -fno-stack-protector linux-atomic.i

Compiler configured with: /scratch/jmyers/glibc/many7/src/gcc/configure '--prefix=/scratch/jmyers/glibc/many7/install/compilers/m68k-linux-gnu-coldfire' '--build=x86_64-pc-linux-gnu' '--host=x86_64-pc-linux-gnu' '--target=m68k-glibc-linux-gnu' '--with-sysroot=/scratch/jmyers/glibc/many7/install/compilers/m68k-linux-gnu-coldfire/sysroot' '--with-arch=cf' --disable-multilib --disable-libsanitizer --disable-libssp '--with-gmp=/scratch/jmyers/glibc/many7/install/host-libraries' '--with-mpfr=/scratch/jmyers/glibc/many7/install/host-libraries' '--with-mpc=/scratch/jmyers/glibc/many7/install/host-libraries' '--enable-languages=c' --disable-shared --disable-threads --disable-libatomic --disable-decimal-float --disable-libffi --disable-libgomp --disable-libitm --disable-libmpx --disable-libquadmath --without-headers --with-newlib '--with-glibc-version=2.24'
Comment 6 Jeffrey A. Law 2016-12-02 17:38:16 UTC

This is a bad interaction between PREFERRED_STACK_BOUNDARY and PUSH_ROUNDING, but there's a deeper code generation issue that needs to be looked at as well.

So background.  A push insn on the m68k is actually a store using a pre-decrement addressing mode and register a7. ie -(%a7) aka -(%sp)

The original m68k family special cased byte pushes so that if you did something like

mov.b <input>,-(%sp)

You would actually push 2 bytes on the stack instead of 1 to ensure the stack was always 2 byte aligned.  This quirk was only done when using sp/a7 in predec/postinc addressing modes as push/pop insns.

The coldfire family did away with that quirk and no longer special cases sp/a7 in those addressing modes.


GCC uses PUSH_ROUNDING to describe the behavior of the original m68k family.  As expected it's behavior is now conditional on TARGET_COLDFIRE:

/* On the 680x0, sp@- in a byte insn really pushes a word.
   On the ColdFire, sp@- in a byte insn pushes just a byte.  */
#define PUSH_ROUNDING(BYTES) (TARGET_COLDFIRE ? BYTES : ((BYTES) + 1) & ~1)


Another quirk of the Coldfire family is that it really prefers its stack stack 32 bit aligned.  It impacts all kinds of things.  So not surprisingly m68k has (m68k.h and linux.h respectively):

/* ColdFire and fido strongly prefer a 32-bit aligned stack.  */
#define PREFERRED_STACK_BOUNDARY \
  ((TARGET_COLDFIRE || TARGET_FIDOA) ? 32 : 16)


#undef PREFERRED_STACK_BOUNDARY
#define PREFERRED_STACK_BOUNDARY 32


So far, so good on the target bits.    We define various sync builtins, including:

DEF_SYNC_BUILTIN (BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_1,
                  "__sync_val_compare_and_swap_1",
                  BT_FN_I1_VPTR_I1_I1, ATTR_NOTHROWCALL_LEAF_LIST)

ie,

char __sync_val_compare_and_swap_1 (void *, char, char)

These are called as libcalls, not normal functions.  This distinction is important.  

So when we make a call to __sync_val_compare_and_swap, on coldfire we push 6 bytes of data.  This then runs afoul of this assert in emit_library_call_value_1:


 /* Stack must be properly aligned now.  */
  gcc_assert (!(stack_pointer_delta
                & (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT - 1)));

(STACK_POINTER_DELTA will be 6).


But wait, it's actually worse.  While the caller seems to want to push bytes, the callee seems to be using a more standard ABI where the usual promotions occur.  ie, expects the caller to have pushed 32bit words.

So not only do we have the assertion to deal with, we really need to address the ABI mismatch.  What a mess.  There's a reasonable chance I will not get this addressed prior to gcc-7.  m68k just isn't that high a priority.
Comment 7 Waldemar Brodkorb 2016-12-02 21:05:48 UTC
Can't we disable compilation of linux-atomic.c for gcc7 then?
So that at least it is possible to build a toolchain for coldfire?
Comment 8 Jeffrey A. Law 2016-12-02 21:10:38 UTC
Unsure.  I thought libstdc++ used some of the libatomic facilities under the hood so we'd just replace one build failure with another.

It might also mess up the older 68k systems (assuming I'm wrong about the ABI implications and they are in fact working properly) to just remove libatomic from the builds.

In short, I don't have enough information to recommend a reasonable course of action on this BZ.
Comment 9 Larry Baker 2016-12-02 21:25:20 UTC
To answer Waldemar's question, that is exactly how I worked around the problem for gcc 4.7 and 4.8 in 2012 (see Bug 53833).  That enabled me to have a functioning gcc for ColdFire.  I used it to fix broken stack limit checking for ColdFire processors.  I never tried to use it for building any system components, such as Jeff describes.
Comment 10 Andreas Schwab 2016-12-04 09:52:13 UTC
The fact that libcalls aren't using the C ABI is likely hurting everyone.
Comment 11 Waldemar Brodkorb 2016-12-04 11:35:09 UTC
I talking about following change:
diff -Nur gcc.orig/libgcc/config.host gcc/libgcc/config.host
--- gcc.orig/libgcc/config.host   2016-02-26 21:02:28.000000000 +0100
+++ gcc/libgcc/config.host        2016-04-29 09:18:40.377989160 +0200
@@ -812,7 +812,7 @@
 m68k*-*-openbsd*)
        ;;
 m68k-*-uclinux*)       # Motorola m68k/ColdFire running uClinux with uClibc
-       tmake_file="$tmake_file m68k/t-floatlib m68k/t-linux"
+       tmake_file="$tmake_file m68k/t-floatlib"
        md_unwind_header=m68k/linux-unwind.h
        ;;
 m68k-*-linux*)                 # Motorola m68k's running GNU/Linux


This would allow to create a working toolchain. 
m68k-nommu (coldfire) is only supported by uClibc-ng and not GNU libc.
There is only support for Linuxthreads, so TLS/libatomic is disabled at configure time.
C++ support still seems to work fine.
The m68k (full MMU) support isn't changed with this patch.

From the embedded build system maintainer view, I think the patch is fine to at least
get some working toolchain until the ICE is solved.

The patch is used for some time in Buildroot/OpenADK.
Comment 12 Andreas Schwab 2016-12-04 12:01:45 UTC
linux-atomic is independent of libc and libpthread, it implements compiler intrinsics and only depends on the kernel support for CAS on Coldfire.
Comment 13 Waldemar Brodkorb 2016-12-04 12:05:19 UTC
Okay.
So what is your opinion, how we proceed here?
Comment 14 Larry Baker 2016-12-04 17:59:00 UTC
(In reply to Waldemar Brodkorb from comment #11)

> diff -Nur gcc.orig/libgcc/config.host gcc/libgcc/config.host
> --- gcc.orig/libgcc/config.host   2016-02-26 21:02:28.000000000 +0100
> +++ gcc/libgcc/config.host        2016-04-29 09:18:40.377989160 +0200
> @@ -812,7 +812,7 @@
>  m68k*-*-openbsd*)
>         ;;
>  m68k-*-uclinux*)       # Motorola m68k/ColdFire running uClinux with uClibc
> -       tmake_file="$tmake_file m68k/t-floatlib m68k/t-linux"
> +       tmake_file="$tmake_file m68k/t-floatlib"
>         md_unwind_header=m68k/linux-unwind.h
>         ;;
>  m68k-*-linux*)                 # Motorola m68k's running GNU/Linux

This is exactly the same patch I was referring to in Comment #9 that I used to work around the problem for gcc 4.7 and 4.8 in 2012 (see Bug 53833).
Comment 15 Waldemar Brodkorb 2017-04-28 00:16:37 UTC
Jeffrey, seems gcc 7 is coming soon, any chance getting this resolved?
Comment 16 Carlos Soto 2017-06-25 18:40:54 UTC
Any news on this bug?

Currently I'm trying to get a 5485 board working with linux and I'm facing the fact that there's no working toolchain available anymore.

It would be great to have this old boards up and running again
Comment 17 angelo 2017-06-25 22:27:56 UTC
Hi Carlos,

maybe you can try one of these 2 toolchains i prepared years ago:

http://sysam.it/toolchains.html

Regads,
Angelo

On 25/06/2017 20:40, csotoalonso at gmail dot com wrote:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68467
>
> Carlos Soto <csotoalonso at gmail dot com> changed:
>
>             What    |Removed                     |Added
> ----------------------------------------------------------------------------
>                   CC|                            |csotoalonso at gmail dot com
>
> --- Comment #16 from Carlos Soto <csotoalonso at gmail dot com> ---
> Any news on this bug?
>
> Currently I'm trying to get a 5485 board working with linux and I'm facing the
> fact that there's no working toolchain available anymore.
>
> It would be great to have this old boards up and running again
>
Comment 18 Carlos Soto 2017-06-30 19:23:05 UTC
(In reply to angelo from comment #17)
> Hi Carlos,
> 
> maybe you can try one of these 2 toolchains i prepared years ago:
> 
> http://sysam.it/toolchains.html
> 
> Regads,
> Angelo
> 

Hi angelo,
thanks for pointing that. But unfortunately those toolchain lack a sysroot so they are not suitable for Buildroot, the tool I use to create the root fs.

So, I'm stuck for the time being...
Comment 19 Joseph S. Myers 2018-01-24 23:37:00 UTC
Author: jsm28
Date: Wed Jan 24 23:36:29 2018
New Revision: 257032

URL: https://gcc.gnu.org/viewcvs?rev=257032&root=gcc&view=rev
Log:
Fix m68k-linux-gnu libgcc build for ColdFire (PR target/68467).

PR target/68467 is libgcc failing to build for m68k-linux-gnu
configured for ColdFire.

Jeff has an analysis in the PR identifying the problem as resulting
from the callers of libcalls with 1-byte or 2-byte arguments wanting
to push just 1 or 2 bytes on the stack, while the libcall
implementations have the normal C ABI and expect 4-byte arguments.
For normal C functions, I believe the TARGET_PROMOTE_PROTOTYPES
definition would ensure such arguments get passed as 4-byte, but that
does not apply for libcalls.

This patch fixes the issue by defining TARGET_PROMOTE_FUNCTION_MODE
for m68k.  The definition is conservative, only applying promotions in
the case of arguments to libcalls; otherwise it returns the unpromoted
type, which I believe matches what the default implementation of the
hook would have done on m68k.

I have tested that this fixes the libgcc build for ColdFire, and, in
conjunction with one glibc patch, this enables glibc to build cleanly
for ColdFire and to pass the compilation parts of the glibc testsuite
except for one test unrelated to this patch (while glibc and the
compilation parts of the testsuite continue to build OK for
non-ColdFire m68k, as expected).  I have *not* run any GCC tests for
this patch, or any execution tests for m68k.

	PR target/68467
	* config/m68k/m68k.c (m68k_promote_function_mode): New function.
	(TARGET_PROMOTE_FUNCTION_MODE): New macro.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/m68k/m68k.c
Comment 20 Joseph S. Myers 2018-01-24 23:37:24 UTC
Fixed for GCC 8.
Comment 21 Waldemar Brodkorb 2018-01-27 13:46:29 UTC
I can confirm that this fixes the problem even for gcc 7.x.
Any chance to get it included into gcc 7 branch?

No regression found while running the uClibc-ng testsuite inside
qemu-system-m68k.

Thanks a lot!
Comment 22 joseph@codesourcery.com 2018-01-29 18:21:40 UTC
What do the m68k maintainers think about the suggestion of backporting to 
GCC 7 (and for that matter GCC 6)?  This is a regression in the sense of 
"libgcc used to build for ColdFire, then that broke", though not (as far 
as I know) a regression in the sense of "this fixed .i file used to build, 
then that broke".
Comment 23 Jeffrey A. Law 2018-01-29 18:29:36 UTC
I've got no objection Joseph.  But I think you need to make your case to Richi and Jakub -- I doubt they're on CC for this BZ :-)
Comment 24 Joseph S. Myers 2018-01-29 21:01:25 UTC
Author: jsm28
Date: Mon Jan 29 21:00:52 2018
New Revision: 257165

URL: https://gcc.gnu.org/viewcvs?rev=257165&root=gcc&view=rev
Log:
Fix m68k-linux-gnu libgcc build for ColdFire (PR target/68467).

PR target/68467 is libgcc failing to build for m68k-linux-gnu
configured for ColdFire.

Jeff has an analysis in the PR identifying the problem as resulting
from the callers of libcalls with 1-byte or 2-byte arguments wanting
to push just 1 or 2 bytes on the stack, while the libcall
implementations have the normal C ABI and expect 4-byte arguments.
For normal C functions, I believe the TARGET_PROMOTE_PROTOTYPES
definition would ensure such arguments get passed as 4-byte, but that
does not apply for libcalls.

This patch fixes the issue by defining TARGET_PROMOTE_FUNCTION_MODE
for m68k.  The definition is conservative, only applying promotions in
the case of arguments to libcalls; otherwise it returns the unpromoted
type, which I believe matches what the default implementation of the
hook would have done on m68k.

I have tested that this fixes the libgcc build for ColdFire, and, in
conjunction with one glibc patch, this enables glibc to build cleanly
for ColdFire and to pass the compilation parts of the glibc testsuite
except for one test unrelated to this patch (while glibc and the
compilation parts of the testsuite continue to build OK for
non-ColdFire m68k, as expected).  I have *not* run any GCC tests for
this patch, or any execution tests for m68k.

	Backport from mainline
	2018-01-24  Joseph Myers  <joseph@codesourcery.com>

	PR target/68467
	* config/m68k/m68k.c (m68k_promote_function_mode): New function.
	(TARGET_PROMOTE_FUNCTION_MODE): New macro.

Modified:
    branches/gcc-7-branch/gcc/ChangeLog
    branches/gcc-7-branch/gcc/config/m68k/m68k.c
Comment 25 Joseph S. Myers 2018-01-29 21:02:58 UTC
Also now fixed for GCC 7.4.