Created attachment 472633 [details] -fverbose-asm .s file, from a slightly newer kernel version, but same compiler The linux kernel's fs/namei.c contains an inline function may_create. While declared inline and called from four places, the compiler turns out to instantiate only one out-of-line copy of it. The problem is that the the "child" parameter has no location info, even though it is used. gcc-4.5.1-6.fc15.x86_64 kernel-2.6.37-1.fc15.x86_64
Please provide preprocessed source and gcc options used to compile it. Thanks.
Created attachment 475626 [details] preprocessed source gcc -Wp,-MD,fs/.namei.o.d -nostdinc -isystem /usr/lib/gcc/x86_64-redhat-linux/4.6.0/include -I/notnfs/linux-2.6/arch/x86/include -Iinclude -include include/generated/autoconf.h -D__KERNEL__ -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -fno-delete-null-pointer-checks -Os -m64 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -fstack-protector -DCONFIG_AS_CFI=1 -DCONFIG_AS_CFI_SIGNAL_FRAME=1 -DCONFIG_AS_CFI_SECTIONS=1 -DCONFIG_AS_FXSAVEQ=1 -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -Wframe-larger-than=2048 -fno-omit-frame-pointer -fno-optimize-sibling-calls -g -pg -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fconserve-stack -DCC_HAVE_ASM_GOTO -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(namei)" -D"KBUILD_MODNAME=KBUILD_STR(namei)" -c -o fs/namei.o fs/namei.c -save-temps gcc version 4.6.0 20110122 (Red Hat 4.6.0-0.3) (GCC) linux source v2.6.38-rc2-175-g6fb1b30
The problem is IPA-SRA. Self-contained testcase for -Os: struct inode { char i_pad[16]; unsigned int i_flags; }; struct dentry { unsigned int d_pad[16]; struct inode *d_inode; }; extern int inode_permission (struct inode *, int); extern int fsnotify_create (struct inode *, struct dentry *); static inline int may_create (struct inode *dir, struct dentry *child) { if (child->d_inode) return -17; if (((dir)->i_flags & 16)) return -2; return inode_permission (dir, 2 | 1); } int foo (struct inode *dir, struct dentry *child) { if (may_create (dir, child) < 0) return -1; return fsnotify_create (dir, child); } int bar (struct inode *dir, struct dentry *child) { if (may_create (dir, child) < 0) return -1; return fsnotify_create (dir, child); } int baz (struct inode *dir, struct dentry *child) { if (may_create (dir, child) < 0) return -1; return fsnotify_create (dir, child); } IPA-SRA decides (clearly it is a wrong decision here for code size) to not pass child parameter to may_create, but instead pass it child->d_inode argument. Thus in the may_create.isra.N function there really is no child parameter. In this exact testcase this might be solvable in the future with my DW_TAG_GNU_call_site stuff together with the (still just in drafting) DW_OP_GNU_parameter_ref op, as in the callers the child is still available (copied from %rsi to %rbp where %rsi is call clobbered and overwritten by child->d_inode). But e.g. if you just do return may_create (dir, child); above as the whole fn body, it would be only available if the caller of that function had that value around in DW_TAG_GNU_call_site. See http://gcc.gnu.org/wiki/summit2010?action=AttachFile&do=get&target=jelinek.pdf for more details. The DW_TAG_GNU_call_site and DW_OP_GNU_entry_value stuff is currently awaiting for 4.6 branching, so that it can be resubmitted for 4.7 stage 1.
Tracking this upstream, http://gcc.gnu.org/PR47858
Package gcc-4.6.0-0.11.fc15: * should fix your issue, * was pushed to the Fedora 15 updates-testing repository, * should be available at your local mirror within two days. Update it with: # su -c 'yum update --enablerepo=updates-testing gcc-4.6.0-0.11.fc15' as soon as you are able to, then reboot. Please go to the following url: https://admin.fedoraproject.org/updates/gcc-4.6.0-0.11.fc15 then log in and leave karma (feedback).
gcc-4.6.0-0.11.fc15 has been pushed to the Fedora 15 stable repository. If problems still persist, please make note of it in this bug report.