https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61958
Bug ID: 61958 Summary: function arbitrarily placed in .text.unlikely section Product: gcc Version: 4.9.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: jpoimboe at redhat dot com Created attachment 33206 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=33206&action=edit gzipped .i file for the bad case When making changes to a certain source file in the Linux kernel, gcc is unexpectedly moving two functions from the .text section to the .text.unlikely section. When compiling the original version of the source file, the two functions are placed in the .text section: $ cd linux $ git describe v3.16-rc7-7-g31dab71 $ make net/ipv4/fib_trie.o CHK include/config/kernel.release CHK include/generated/uapi/linux/version.h CHK include/generated/utsrelease.h CALL scripts/checksyscalls.sh CC net/ipv4/fib_trie.o $ eu-readelf -s net/ipv4/fib_trie.o |grep 'insert_leaf_info\|leaf_info_new' 6: 0000000000000000 136 FUNC LOCAL DEFAULT 1 insert_leaf_info 37: 0000000000000dc0 88 FUNC LOCAL DEFAULT 1 leaf_info_new $ eu-readelf -S net/ipv4/fib_trie.o |grep '\[ 1\]' [ 1] .text PROGBITS 0000000000000000 00000040 000038c0 0 AX 0 0 16 However, when I apply the following patch, the two functions get unexpectedly moved to .text.unlikely: $ cat /tmp/fib_trie.patch diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 5afeb5a..cc5e3d3 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1187,6 +1187,7 @@ int fib_table_insert(struct fib_table *tb, struct fib_config *cfg) key = key & mask; + printk("foo\n"); fi = fib_create_info(cfg); if (IS_ERR(fi)) { err = PTR_ERR(fi); $ patch -p1 < /tmp/fib_trie.patch patching file net/ipv4/fib_trie.c $ make net/ipv4/fib_trie.o CHK include/config/kernel.release CHK include/generated/uapi/linux/version.h CHK include/generated/utsrelease.h CALL scripts/checksyscalls.sh CC net/ipv4/fib_trie.o $ eu-readelf -s net/ipv4/fib_trie.o |grep 'insert_leaf_info\|leaf_info_new' 6: 0000000000000000 111 FUNC LOCAL DEFAULT 5 insert_leaf_info 28: 000000000000006f 82 FUNC LOCAL DEFAULT 5 leaf_info_new $ eu-readelf -S net/ipv4/fib_trie.o |grep '\[ 5\]' [ 5] .text.unlikely PROGBITS 0000000000000000 00003770 000000c1 0 AX 0 0 1 Both of the moved functions are called by fib_insert_node(), which is inlined by fib_table_insert(), which was modified by the patch. As far as I can tell, it seems likely that the moved functions would be called, especially insert_leaf_info() which is called in the main control path of the function. Also it seems odd that adding a call to printk would change the likelihood of a function being called, since it doesn't change control flow. Using gcc from Fedora rawhide: $ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.9.1/lto-wrapper Target: x86_64-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.9.1-20140717/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.9.1-20140717/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux Thread model: posix gcc version 4.9.1 20140717 (Red Hat 4.9.1-2) (GCC) Full gcc cmdline: gcc -Wp,-MD,net/ipv4/.fib_trie.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-redhat-linux/4.9.1/include -I./arch/x86/include -Iarch/x86/include/generated -Iinclude -I./arch/x86/include/uapi -Iarch/x86/include/generated/uapi -I./include/uapi -Iinclude/generated/uapi -include ./include/linux/kconfig.h -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -m64 -mno-mmx -mno-sse -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -DCONFIG_AS_CRC32=1 -DCONFIG_AS_AVX=1 -DCONFIG_AS_AVX2=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -fno-delete-null-pointer-checks -O2 -Wframe-larger-than=2048 -fstack-protector-strong -Wno-unused-but-set-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -g -pg -mfentry -DCC_USING_FENTRY -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -DCC_HAVE_ASM_GOTO -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(fib_trie)" -D"KBUILD_MODNAME=KBUILD_STR(fib_trie)" -c -o net/ipv4/fib_trie.o net/ipv4/fib_trie.c I have also seen this issue with "gcc version 4.8.3 20140624 (Red Hat 4.8.3-1) (GCC)" from Fedora 20. The .i files are attached (and gzipped to be under the bugzilla file size limit).