From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10245 invoked by alias); 13 Nov 2008 15:29:57 -0000 Received: (qmail 810 invoked by uid 48); 13 Nov 2008 15:28:33 -0000 Date: Thu, 13 Nov 2008 15:29:00 -0000 Message-ID: <20081113152833.809.qmail@sourceware.org> X-Bugzilla-Reason: CC References: Subject: [Bug middle-end/29215] [4.2/4.3/4.4 Regression] extra store for memcpy In-Reply-To: Reply-To: gcc-bugzilla@gcc.gnu.org To: gcc-bugs@gcc.gnu.org From: "jakub at gcc dot gnu dot org" Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2008-11/txt/msg00972.txt.bz2 ------- Comment #15 from jakub at gcc dot gnu dot org 2008-11-13 15:28 ------- This is a regression from 3.4 still present in 4.3/4.4. At the tree level, we only fold memcpy if the size of the source and destination elements is the same and length is tgat size (say int i = 6; float f; memcpy (&f, &i, sizeof (int)); ) into an assignment. As this isn't the case here, before expansion we have: main () { int arg1; int arg2; int arg3; int arg4; int arg5; int D.1602; : D.1602 = *(int *) "abcd"; arg1 = D.1602; arg2 = D.1602; arg3 = D.1602; arg4 = D.1602; arg5 = D.1602; __builtin_memcpy (&buf, &arg1, 4); __builtin_memcpy (&buf[4], &arg2, 4); __builtin_memcpy (&buf[8], &arg3, 4); __builtin_memcpy (&buf[12], &arg4, 4); __builtin_memcpy (&buf[16], &arg5, 4); buf[20] = 0; __builtin_puts (&buf); return 0; } and all of arg{1,2,3,4,5} are TREE_ADDRESSABLE. In 3.4 ADDRESSOF took care of optimizing out these dead stores. But ADDRESSOF is gone, and RTL DSE is apparently unable to kill these. No idea why dse1 doesn't kill it, dse2 doesn't at least on x86_64 because pro_epilogue_adjust_stack_rex64 has (clobber (mem:BLK (scratch))) in it. On the tree level, we could perhaps optimize this by adding special builtins and transforming __builtin_memcpy into it if possible. Say have void *__builtin_memstore2 (char *, HImode);, void *__builtin_memstore4 (char *, SImode); etc., and transform say __builtin_memcpy (buffer + 8, &arg2, sizeof (arg2)) into __builtin_memstore4 (buffer + 8, arg2); (or for non-integral types, say arg2 being float, __builtin_memstore4 (buffer + 8, VCE). At expansion time these builtins would check if the second argument must live in memory. If yes, it would just expand it as __builtin_memcpy. Otherwise it would just do a store (with alias set 0). Or we could try to play with TYPE_REF_CAN_ALIAS_ALL pointers. That said, it would be good to know why DSE doesn't eliminate these dead stores. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29215