From patchwork Sat Dec 10 21:31:23 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 130583 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 42130B6FF5 for ; Sun, 11 Dec 2011 08:33:36 +1100 (EST) Received: (qmail 10017 invoked by alias); 10 Dec 2011 21:33:34 -0000 Received: (qmail 10000 invoked by uid 22791); 10 Dec 2011 21:33:32 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, TW_CP, TW_TM X-Spam-Check-By: sourceware.org Received: from mel.act-europe.fr (HELO mel.act-europe.fr) (194.98.77.210) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 10 Dec 2011 21:33:18 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 9C500CB1405 for ; Sat, 10 Dec 2011 22:33:18 +0100 (CET) Received: from mel.act-europe.fr ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 77tJO1G2NJ0n for ; Sat, 10 Dec 2011 22:33:18 +0100 (CET) Received: from [192.168.1.2] (bon31-6-88-161-99-133.fbx.proxad.net [88.161.99.133]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mel.act-europe.fr (Postfix) with ESMTP id 44F43CB13D1 for ; Sat, 10 Dec 2011 22:33:18 +0100 (CET) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [patch] Fix PR tree-optimization/50569 Date: Sat, 10 Dec 2011 22:31:23 +0100 User-Agent: KMail/1.9.9 MIME-Version: 1.0 Message-Id: <201112102231.23872.ebotcazou@adacore.com> Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi, this is a regression present on mainline and 4.6 branch at -O for the SPARC. The compiler again generates an unaligned access for the memcpy calls in: struct event { struct { unsigned int sec; } sent __attribute__((packed)); }; void __attribute__((noinline,noclone)) frob_entry(char *buf) { struct event event; __builtin_memcpy(&event, buf, sizeof(event)); if (event.sent.sec < 64) { event.sent.sec = -1U; __builtin_memcpy(buf, &event, sizeof(event)); } } Unsurprisingly enough, the trick used in build_ref_for_model (in case this is a reference to a component, the function will replicate the last COMPONENT_REF of model's expr to access it) isn't sufficient anymore with MEM_REFs around, since MEM_REFs can encapsulate an arbitrary number of inner references. Fixed by extending the trick to chain of COMPONENT_REFs. Tested on x86/Linux and SPARC/Solaris, OK for mainline and 4.6 branch? 2011-12-10 Eric Botcazou PR tree-optimization/50569 * tree-sra.c (build_ref_for_model): Replicate a chain of COMPONENT_REFs in the expression of MODEL instead of just the last one. 2011-12-10 Eric Botcazou * gcc.c-torture/execute/20111210-1.c! New test. Index: tree-sra.c =================================================================== --- tree-sra.c (revision 182102) +++ tree-sra.c (working copy) @@ -1493,32 +1493,61 @@ build_ref_for_offset (location_t loc, tr } /* Construct a memory reference to a part of an aggregate BASE at the given - OFFSET and of the same type as MODEL. In case this is a reference to a - component, the function will replicate the last COMPONENT_REF of model's - expr to access it. GSI and INSERT_AFTER have the same meaning as in - build_ref_for_offset. */ + OFFSET and of the type of MODEL. In case this is a chain of references + to component, the function will replicate the chain of COMPONENT_REFs of + the expression of MODEL to access it. GSI and INSERT_AFTER have the same + meaning as in build_ref_for_offset. */ static tree build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset, struct access *model, gimple_stmt_iterator *gsi, bool insert_after) { + tree type = model->type, t; + VEC(tree,heap) *stack = NULL; + if (TREE_CODE (model->expr) == COMPONENT_REF) { - tree t, exp_type, fld = TREE_OPERAND (model->expr, 1); - tree cr_offset = component_ref_field_offset (model->expr); + tree expr = model->expr; + + /* Create a stack of the COMPONENT_REFs so later we can walk them in + order from inner to outer. */ + stack = VEC_alloc (tree, heap, 6); + + do { + tree field = TREE_OPERAND (expr, 1); + tree cr_offset = component_ref_field_offset (expr); + gcc_assert (cr_offset && host_integerp (cr_offset, 1)); + + offset -= TREE_INT_CST_LOW (cr_offset) * BITS_PER_UNIT; + offset -= TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field)); - gcc_assert (cr_offset && host_integerp (cr_offset, 1)); - offset -= TREE_INT_CST_LOW (cr_offset) * BITS_PER_UNIT; - offset -= TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (fld)); - exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0)); - t = build_ref_for_offset (loc, base, offset, exp_type, gsi, insert_after); - return fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (fld), t, fld, - TREE_OPERAND (model->expr, 2)); + VEC_safe_push (tree, heap, stack, expr); + + expr = TREE_OPERAND (expr, 0); + type = TREE_TYPE (expr); + } while (TREE_CODE (expr) == COMPONENT_REF); } - else - return build_ref_for_offset (loc, base, offset, model->type, - gsi, insert_after); + + t = build_ref_for_offset (loc, base, offset, type, gsi, insert_after); + + if (TREE_CODE (model->expr) == COMPONENT_REF) + { + unsigned i; + tree expr; + + /* Now replicate the chain of COMPONENT_REFs from inner to outer. */ + FOR_EACH_VEC_ELT_REVERSE (tree, stack, i, expr) + { + tree field = TREE_OPERAND (expr, 1); + t = fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (field), t, field, + TREE_OPERAND (expr, 2)); + } + + VEC_free (tree, heap, stack); + } + + return t; } /* Construct a memory reference consisting of component_refs and array_refs to