Hi, #include <string.h> void fill(char *s, int i) { memset(s, i, strlen(s)); } 4.1 produces two strlen calls fill: mflr 0 stwu 1,-32(1) stw 0,36(1) stw 28,16(1) mr 28,4 stw 29,20(1) mr 29,3 bl strlen mr 3,29 bl strlen mr 4,28 mr 5,3 mr 3,29 bl memset lwz 0,36(1) lwz 28,16(1) lwz 29,20(1) addi 1,1,32 mtlr 0 blr where 4.0 outputs fill: mflr 0 stwu 1,-32(1) stw 0,36(1) stw 28,16(1) mr 28,3 stw 29,20(1) mr 29,4 bl strlen mr 4,29 mr 5,3 mr 3,28 bl memset lwz 0,36(1) lwz 28,16(1) lwz 29,20(1) addi 1,1,32 mtlr 0 blr
Confirmed, also happens on powerpc-darwin and on the mainline still.
We go via expand_builtin_memset which expands strlen at len_rtx = expand_normal (len); but then, expand via setmem fails, so we bail out else if (!set_storage_via_setmem(dest_mem, len_rtx, val_rtx, dest_align)) return 0; and end up doing regular return expand_call (exp, target, ignore); which then expands strlen again.
Testing a fix
Subject: Bug number PR27095 A patch for this bug has been added to the patch tracker. The mailing list url for the patch is http://gcc.gnu.org/ml/gcc-patches/2006-04/msg00494.html
Subject: Bug 27095 Author: amodra Date: Fri Apr 14 03:20:21 2006 New Revision: 112948 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=112948 Log: PR middle-end/27095 * builtins.c: (expand_builtin_memset): Stabilize args before expansion and emit libcall here in case the builtin fails. (expand_builtin_strcmp): Always emit the libcall here on failure. Modified: trunk/gcc/ChangeLog trunk/gcc/builtins.c
Fixed on the mainline. Btw, this is really wrong-code. Can you apply to the 4.1 branch, too, please?
Subject: Bug 27095 Author: amodra Date: Tue Apr 18 12:34:07 2006 New Revision: 113030 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=113030 Log: PR middle-end/27095 * builtins.c: (expand_builtin_memset): Stabilize args before expansion and emit libcall here in case the builtin fails. (expand_builtin_strcmp): Always emit the libcall here on failure. Modified: branches/gcc-4_1-branch/gcc/ChangeLog branches/gcc-4_1-branch/gcc/builtins.c
As Roger requested, I was waiting a few days to apply the patch on the 4.1 branch.
Subject: Bug 27095 Author: amodra Date: Fri Apr 28 03:36:15 2006 New Revision: 113340 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=113340 Log: PR middle-end/27095 * gcc.dg/pr27095.c: New. Added: trunk/gcc/testsuite/gcc.dg/pr27095.c Modified: trunk/gcc/testsuite/ChangeLog
I should note that this testcase fails on darwin because strlen is mentioned twice in the testcase as there is a stub for strlen.
Testcase fixed by simply xfailing *-*-darwin*. It might be possible to tweak the pattern we match to accommodate darwin, but I'll leave that to a darwin maintainer.
The testcase also fails on hppa64-hp-hpux11.11: b,l strlen,%r2 ... .type strlen, @function At the moment, it's a puzzle to me why this also isn't failing on the 32-bit ports.