From patchwork Thu Aug 7 19:50:15 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernd Schmidt X-Patchwork-Id: 377936 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 958231400D2 for ; Fri, 8 Aug 2014 05:51:02 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:content-type; q= dns; s=default; b=wT0WT/Vk8sPqsfhgIYVB0g6YRfDgVn+gBoQz8elIEjs3sW Ll4q4VJdSFHzLLp6Ey2BSg3taegyiAyWKcSExVaecnns9a2gtoyrU9BDMTxSzo3S Clue7ggdtDu1u2iZdSY30MNHXMKlxBSeGepovuOwk2eDKgKIoWmHq2o4IDfZA= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:content-type; s= default; bh=zKromE47M4Y8j6m3kijf8O5G3CU=; b=ptr9u3SF1ACby4aH5h80 gNHH4Fnmb/9AmkiFh1CHv+egsFcjLJ5g1WV8IDk6WjNvrFIOE2dNbbMSINO/UO+K uKJVKFSbKp1bosuEQallhQ2fl70ofP7gs6exnVRzOttMbrJ4b1X2ots91hTehOMY +5xwuYvP+BjpI6QVf1JcxtQ= Received: (qmail 5173 invoked by alias); 7 Aug 2014 19:50:55 -0000 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 Received: (qmail 5156 invoked by uid 89); 7 Aug 2014 19:50:55 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL, BAYES_00 autolearn=ham version=3.3.2 X-HELO: relay1.mentorg.com Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 07 Aug 2014 19:50:54 +0000 Received: from svr-orw-exc-10.mgc.mentorg.com ([147.34.98.58]) by relay1.mentorg.com with esmtp id 1XFTi6-00018h-06 from Bernd_Schmidt@mentor.com ; Thu, 07 Aug 2014 12:50:50 -0700 Received: from SVR-IES-FEM-01.mgc.mentorg.com ([137.202.0.104]) by SVR-ORW-EXC-10.mgc.mentorg.com with Microsoft SMTPSVC(6.0.3790.4675); Thu, 7 Aug 2014 12:50:49 -0700 Received: from [127.0.0.1] (137.202.0.76) by SVR-IES-FEM-01.mgc.mentorg.com (137.202.0.104) with Microsoft SMTP Server id 14.2.247.3; Thu, 7 Aug 2014 20:50:48 +0100 Message-ID: <53E3D877.4050607@codesourcery.com> Date: Thu, 7 Aug 2014 21:50:15 +0200 From: Bernd Schmidt User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.7.0 MIME-Version: 1.0 To: GCC Patches , Ulrich Weigand Subject: Fix ivopts address space confusion This is a followup fix for the patches from PR41857, which contained a bug that is exposed by the ptx backend. The problem is finding the right pointer type for a mem_ref during ivopts. The original problem was that on spu-elf, __ea pointers are 64 bit while sizetype is 32 bit. During ivopts, pointer types are typically replaced by unsigned integers in computations, and in the original testcase we have an aff_tree containing only one long long element, but no pointer base, and addr_to_parts casts everything to sizetype, losing parts of the address. To fix that, code was introduced to promote one of the elements of the aff_tree to become the base, cast it to a pointer of an appropriate type, and thus avoid the conversion to sizetype for that element. This element is the base_hint, which is chosen based on the candidate's base_object. The problem lies in the following code in move_hint_to_base: /* Cast value to appropriate pointer type. We cannot use a pointer to TYPE directly, as the back-end will assume registers of pointer type are aligned, and just the base itself may not actually be. We use void pointer to the type's address space instead. */ qual = ENCODE_QUAL_ADDR_SPACE (TYPE_ADDR_SPACE (type)); type = build_qualified_type (void_type_node, qual); parts->base = fold_convert (build_pointer_type (type), val); This is confused about address spaces. We can get here with either an integer (for the the original testcase in 4.5, it's a long long that holds the pointer value), but I think we can also arrive here with a pointer. Assuming a normal machine, if it's a long long created by ivopts, TYPE_ADDR_SPACE should be just generic, and if it's some other pointer, we should be looking at TYPE_ADDR_SPACE (TREE_TYPE (type)). Thus, the code seems essentially unnecessary, but - up to this point - harmless. On ptx however, local variables have an address space, and the above code picks that up and incorrectly places it on the pointer destination type. The following patch reworks this area - instead of trying to find a proper pointer type, it just recognizes the case where an integer is promoted to be the base, and performs all calculations in that type rather than sizetype. That also seems to be an additional bugfix over the original change, which could still lose address bits in the index. I've verified that this produces the same assembly for the original testcase on spu-elf with the gcc-4_5-branch, and it solves the problems I was seeing on ptx. Bootstrapped and tested on x86_64-linux. Ok? Bernd * tree-ssa-address.c (move_hint_to_base): Remove arg TYPE. All callers changed. Don't cast the new base to a pointer type. (addr_to_parts): If the base has an integer type, use that instead of sizetype for calculations. Index: gcc/tree-ssa-address.c =================================================================== --- gcc/tree-ssa-address.c (revision 436508) +++ gcc/tree-ssa-address.c (working copy) @@ -443,12 +443,10 @@ move_fixed_address_to_symbol (struct mem /* If ADDR contains an instance of BASE_HINT, move it to PARTS->base. */ static void -move_hint_to_base (tree type, struct mem_address *parts, tree base_hint, - aff_tree *addr) +move_hint_to_base (struct mem_address *parts, tree base_hint, aff_tree *addr) { unsigned i; tree val = NULL_TREE; - int qual; for (i = 0; i < addr->n; i++) { @@ -463,13 +461,7 @@ move_hint_to_base (tree type, struct mem if (i == addr->n) return; - /* Cast value to appropriate pointer type. We cannot use a pointer - to TYPE directly, as the back-end will assume registers of pointer - type are aligned, and just the base itself may not actually be. - We use void pointer to the type's address space instead. */ - qual = ENCODE_QUAL_ADDR_SPACE (TYPE_ADDR_SPACE (type)); - type = build_qualified_type (void_type_node, qual); - parts->base = fold_convert (build_pointer_type (type), val); + parts->base = val; aff_combination_remove_elt (addr, i); } @@ -639,7 +631,7 @@ addr_to_parts (tree type, aff_tree *addr tree base_hint, struct mem_address *parts, bool speed) { - tree part; + tree part, int_type; unsigned i; parts->symbol = NULL_TREE; @@ -671,21 +663,29 @@ addr_to_parts (tree type, aff_tree *addr there is no reliable way how to distinguish between pointer and its offset, this is just a guess. */ if (!parts->symbol && base_hint) - move_hint_to_base (type, parts, base_hint, addr); + move_hint_to_base (parts, base_hint, addr); if (!parts->symbol && !parts->base) move_pointer_to_base (parts, addr); + /* The call to move_hint_to_base may have promoted an integer to the base. + Since addresses in different address spaces can have different sizes, do + not cast to sizetype in that case, but use the type of the base. */ + if (parts->base && TREE_CODE (TREE_TYPE (parts->base)) == INTEGER_TYPE) + int_type = TREE_TYPE (parts->base); + else + int_type = sizetype; + /* Then try to process the remaining elements. */ for (i = 0; i < addr->n; i++) { - part = fold_convert (sizetype, addr->elts[i].val); + part = fold_convert (int_type, addr->elts[i].val); if (addr->elts[i].coef != 1) - part = fold_build2 (MULT_EXPR, sizetype, part, - wide_int_to_tree (sizetype, addr->elts[i].coef)); + part = fold_build2 (MULT_EXPR, int_type, part, + wide_int_to_tree (int_type, addr->elts[i].coef)); add_to_parts (parts, part); } if (addr->rest) - add_to_parts (parts, fold_convert (sizetype, addr->rest)); + add_to_parts (parts, fold_convert (int_type, addr->rest)); } /* Force the PARTS to register. */