When using --enable-target-optspace on gcc 4.5 function __bswapsi2 in libgcc generates call to itself which causes infinite recursion. Here is disassembly. $ arm-none-linux-uclibcgnueabi-objdump -d _bswapsi2_s.o _bswapsi2_s.o: file format elf32-littlearm Disassembly of section .text: 00000000 <__bswapsi2>: 0: e92d4008 push {r3, lr} 4: ebfffffe bl 0 <__bswapsi2> 8: e8bd8008 pop {r3, pc} This does not happen on -O1, O2 or O3 where is computes the swapping and does not call the libgcc function. With gcc 4.4 it does not call libgcc function even at -Os. I have only tested it on arm architecture. Here is little program which demonstrates it typedef signed int SItype; SItype __bswapsi2 (SItype u) { return ((((u) & 0xff000000) >> 24) | (((u) & 0x00ff0000) >> 8) | (((u) & 0x0000ff00) << 8) | (((u) & 0x000000ff) << 24)); } here is how the gcc was built /scratch/oe/work/armv5te-oe-linux-gnueabi/gcc-cross-intermediate-4.5-r0+svnr160043/gcc-4.5/build.x86_64-linux.arm-oe-linux-gnueabi/gcc/xgcc -v Using built-in specs. COLLECT_GCC=/scratch/oe/work/armv5te-oe-linux-gnueabi/gcc-cross-intermediate-4.5-r0+svnr160043/gcc-4.5/build.x86_64-linux.arm-oe-linux-gnueabi/gcc/xgcc Target: arm-oe-linux-gnueabi Configured with: /scratch/oe/work/armv5te-oe-linux-gnueabi/gcc-cross-intermediate-4.5-r0+svnr160043/gcc-4.5/configure --build=x86_64-linux --host=x86_64-linux --target=arm-oe-linux-gnueabi --prefix=/scratch/oe/cross/armv5te --exec_prefix=/scratch/oe/cross/armv5te --bindir=/scratch/oe/cross/armv5te/bin --sbindir=/scratch/oe/cross/armv5te/bin --libexecdir=/scratch/oe/cross/armv5te/libexec --datadir=/scratch/oe/cross/armv5te/share --sysconfdir=/scratch/oe/cross/armv5te/etc --sharedstatedir=/scratch/oe/cross/armv5te/com --localstatedir=/scratch/oe/cross/armv5te/var --libdir=/scratch/oe/cross/armv5te/lib --includedir=/scratch/oe/cross/armv5te/include --oldincludedir=/scratch/oe/cross/armv5te/include --infodir=/scratch/oe/cross/armv5te/share/info --mandir=/scratch/oe/cross/armv5te/share/man --with-local-prefix=/scratch/oe/sysroots/armv5te-oe-linux-gnueabi/usr --enable-shared --disable-multilib --disable-threads --enable-languages=c --program-prefix=arm-oe-linux-gnueabi- --with-sysroot=/scratch/oe/sysroots/armv5te-oe-linux-gnueabi --with-build-sysroot=/scratch/oe/sysroots/armv5te-oe-linux-gnueabi --enable-target-optspace --disable-libmudflap --disable-libgomp --disable-libssp --with-float=soft --program-prefix=arm-oe-linux-gnueabi- --enable-__cxa_atexit Thread model: single gcc version 4.5.1 20100530 (prerelease) (GCC)
Heh. arm does have a bswapsi pattern though - why is that expanding to a call at -Os?
(In reply to comment #1) > Heh. arm does have a bswapsi pattern though - why is that expanding to a call > at -Os? > IIUC this pattern only triggers for armv6+ architectures. The problem I see is on a armv5te
I've looked at this, and as far as I can tell it's caused by two separate improvements in 4.5 that are Ok individually but cause libgcc's __bswapsi2 to call itself when combined (and certain build options are selected). 1. The middle-end now recognises C idioms for bswap and represents them as calls to the builtin bswap. 2. The ARM backend now generates much better code for the builtin bswap, but for archs prior to ARMv6 when -Os is enabled the .md expander arranges to have a libcall emitted instead. Consequently, then building for (say) ARMv5 with --enable-target-optspace: a) the middle-end represents the C bswap idiom in libgcc2.c:__bswapsi2 () as a call to the builtin b) the ARM backend (not knowing it's compiling libgcc) emits a libcall c) hence __bswapsi2 () calls itself The only way I see around this is to add a compiler option (-fin-libgcc say), set it when compiling libgcc routines (similar to -DIN_LIBGCC2), check for it in the ARM bswap expander, and if set ignore -Os in the arch < v6 case.
No, the arm backend should not claim to implement bswapsi when it in fact emits a libcall.
Khem, Can you check if this fixes your problem ? Feel free to submit this to gcc-patches@ if you get around to testing this before me. Ramana diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 628bd62..9dcceea 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -11296,7 +11296,7 @@ (define_expand "bswapsi2" [(set (match_operand:SI 0 "s_register_operand" "=r") (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))] -"TARGET_EITHER" +"TARGET_EITHER && (arm_arch6 || ( !arm_arch6 && !optimize_size))" " if (!arm_arch6) {
Why not just: TARGET_EITHER && (arm_arch6 || !optimize_size) ? That !arm_arch6 && is completely redundant there.
(In reply to comment #6) > Why not just: > TARGET_EITHER && (arm_arch6 || !optimize_size) > ? That !arm_arch6 && is completely redundant there. > Hi Ramana the patch along with Jakub's suggestions works for me. Thx -Khem
If nobody tests and submits this patch the issue will be not fixed for 4.5.1.
GCC 4.5.1 is being released, adjusting target milestone.
The patch has been approved, why hasn't been applied? http://gcc.gnu.org/ml/gcc-patches/2010-07/msg00381.html
Subject: Bug 44392 Author: ramana Date: Wed Sep 8 21:35:48 2010 New Revision: 164029 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=164029 Log: 2010-09-08 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> PR target/44392 * config/arm/arm.md (bswapsi2): Handle condition correctly for armv6 and optimize_size. Modified: trunk/gcc/ChangeLog trunk/gcc/config/arm/arm.md
Fixed on the trunk then.
GCC 4.5.2 is being released, adjusting target milestone.
Author: ramana Date: Tue Jan 25 07:18:05 2011 New Revision: 169221 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=169221 Log: 2011-01-21 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> Backport from mainline. 2010-09-08 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> PR target/44392 * config/arm/arm.md (bswapsi2): Handle condition correctly for armv6 and optimize_size. Modified: branches/gcc-4_5-branch/gcc/ChangeLog branches/gcc-4_5-branch/gcc/config/arm/arm.md
This is now fixed.