From patchwork Mon Mar 22 02:03:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Edelsohn X-Patchwork-Id: 1456351 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=WvNUhDxE; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4F3d7z3GMHz9sSC for ; Mon, 22 Mar 2021 13:03:25 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id BF5E93858004; Mon, 22 Mar 2021 02:03:17 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BF5E93858004 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1616378597; bh=w+nrNYf24/1ErudLCB6ZJt54CdfRPaf8T7t0EQp1eXU=; h=Date:Subject:To:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=WvNUhDxE5alhXlCmTruyKB40dOBABhWLjPkd7IZI+dCXVpUhik2IMwi2G6LXxPCCK bjNPzKqhYyOu++beWQovNTvbitPfwXgXCI7vLlG0aK99aHt1iMUeoXvSC6ONrLtPVF u5711HPJeyQtAc30FjugqdL5aYWg4G+KSs+xsC1M= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wr1-x42a.google.com (mail-wr1-x42a.google.com [IPv6:2a00:1450:4864:20::42a]) by sourceware.org (Postfix) with ESMTPS id 957493858D29 for ; Mon, 22 Mar 2021 02:03:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 957493858D29 Received: by mail-wr1-x42a.google.com with SMTP id v11so14986762wro.7 for ; Sun, 21 Mar 2021 19:03:14 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=w+nrNYf24/1ErudLCB6ZJt54CdfRPaf8T7t0EQp1eXU=; b=KKyxqb2Hg42X+TdhqmjYNJL94qOEud7wvk1uDWDtW87doVQQ5CFjqL7+tAsiGPhg9Q eyQABaYaumPyxDsWpoDM/YlW9anrh8/xAmI1yWqalDW1RR1jw0IgYTPf2lyydUIap67v s03o4ZE1JBiJ93r8HYehcykCgKM/yjToyuagsO5Ebx9aad0cLpA14uCF7SutEveLCWlZ Vb0zVRDkCqFHHYWBdm5hhdUqy+hC5mnJEezv+niWyT2qKesvwIBdnzFfTrEIMxMGcxU6 MZvU6zygwbr+vijf/V0UZNiqdZHCBaTiqf62Lm9B62sdmCKprIrYvJNM7izUw8T8gMrL f6ug== X-Gm-Message-State: AOAM531hXOZd9NKYZ7MaNWuQZj1cwpw+50ObLYzt5IoBI0sFDkT+twfv OSAzvUBD1d2xpIC7kEwYblT6sdZwk9KMdPtUDIEljEAeTZM= X-Google-Smtp-Source: ABdhPJyz3n12Qhz4x1/XZwPy5B8FGyinrU4Bcu5yVyQqpG1hcBDa9L5wYEvdjpzX9/pF93s3liN7pU668Hdiio9vaBI= X-Received: by 2002:a5d:4281:: with SMTP id k1mr15560289wrq.374.1616378592747; Sun, 21 Mar 2021 19:03:12 -0700 (PDT) MIME-Version: 1.0 Date: Sun, 21 Mar 2021 22:03:01 -0400 Message-ID: Subject: [PATCH] AIX struct alignment (PR 99557) To: GCC Patches X-Spam-Status: No, score=-8.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: David Edelsohn via Gcc-patches From: David Edelsohn Reply-To: David Edelsohn Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" The AIX power alignment rules apply the natural alignment of the "first member" if it is of a floating-point data type (or is an aggregate whose recursively "first" member or element is such a type). The alignment associated with these types for subsequent members use an alignment value where the floating-point data type is considered to have 4-byte alignment. GCC had been stripping array type but had not recursively looked within structs and unions. This also applies to classes and subclasses and, therefore, becomes more prominent with C++. For example, struct A { double x[2]; int y; }; struct B { int i; struct A a; }; struct A has double-word alignment when referenced independently, but word alignment and offset within struct B despite the alignment of struct A. If struct A were the first member of struct B, struct B would have double-word alignment. One must search for the innermost first member to increase the alignment if double and then search for the innermost first member to reduce the alignment if the TYPE had double-word alignment solely because the innermost first member was double. This patch recursively looks through the first member to apply the double-word alignment to the struct / union as a whole and to apply the word alignment to the struct or union as a member within a struct or union. This is an ABI change for GCCon AIX, but GCC on AIX had not correctly implemented the AIX ABI and had not been compatible with the IBM XL compiler. If anyone can double-check that the patch walks the fields correctly and handles the error conditions correctly, it would be appreciated. Bootstrapped on powerpc-ibm-aix7.2.3.0. Thanks, David * config/rs6000/aix.h (ADJUST_FIELD_ALIGN): Call function. * config/rs6000/rs6000-protos.h: Declare. * config/rs6000/rs6000.c: Define. index 2db50c8007f..7fccb31307b 100644 --- a/gcc/config/rs6000/aix.h +++ b/gcc/config/rs6000/aix.h @@ -223,10 +223,8 @@ /* This now supports a natural alignment mode. */ /* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints. */ #define ADJUST_FIELD_ALIGN(FIELD, TYPE, COMPUTED) \ - ((TARGET_ALIGN_NATURAL == 0 \ - && (TYPE_MODE (strip_array_types (TYPE)) == DFmode \ - || TYPE_MODE (strip_array_types (TYPE)) == DCmode)) \ - ? MIN ((COMPUTED), 32) \ + (TARGET_ALIGN_NATURAL == 0 \ + ? rs6000_special_adjust_field_align (TYPE, COMPUTED) \ : (COMPUTED)) /* AIX increases natural record alignment to doubleword if the first diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index 203660b0a78..c44fd3d0263 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -227,6 +227,7 @@ address_is_prefixed (rtx addr, #ifdef TREE_CODE extern unsigned int rs6000_data_alignment (tree, unsigned int, enum data_align) ; extern bool rs6000_special_adjust_field_align_p (tree, unsigned int); +extern unsigned int rs6000_special_adjust_field_align (tree, unsigned int); extern unsigned int rs6000_special_round_type_align (tree, unsigned int, unsigned int); extern unsigned int darwin_rs6000_special_round_type_align (tree, unsigned int, diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 712dd1c460b..eed51e8d4a2 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -7856,6 +7856,41 @@ rs6000_special_adjust_field_align_p (tree type, unsigned int computed) return false; } +/* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints. */ + +unsigned int +rs6000_special_adjust_field_align (tree type, unsigned int computed) +{ + /* If RECORD or UNION, recursively find the first field. */ + while (TREE_CODE (type) == RECORD_TYPE + || TREE_CODE (type) == UNION_TYPE + || TREE_CODE (type) == QUAL_UNION_TYPE) + { + tree field = TYPE_FIELDS (type); + + /* Skip all non field decls */ + while (field != NULL + && (TREE_CODE (field) != FIELD_DECL + || DECL_FIELD_ABI_IGNORED (field))) + field = DECL_CHAIN (field); + + if (field != NULL && field != type) + type = TREE_TYPE (field); + else + break; + } + + /* Strip arrays. */ + while (TREE_CODE (type) == ARRAY_TYPE) + type = TREE_TYPE (type); + + if (type != error_mark_node + && (TYPE_MODE (type) == DFmode || TYPE_MODE (type) == DCmode)) + computed = MIN (computed, 32); + + return computed; +} + /* AIX increases natural record alignment to doubleword if the first field is an FP double while the FP fields remain word aligned. */ @@ -7864,25 +7899,33 @@ rs6000_special_round_type_align (tree type,unsigned int computed, unsigned int specified) { unsigned int align = MAX (computed, specified); - tree field = TYPE_FIELDS (type); - /* Skip all non field decls */ - while (field != NULL - && (TREE_CODE (field) != FIELD_DECL - || DECL_FIELD_ABI_IGNORED (field))) - field = DECL_CHAIN (field); - - if (field != NULL && field != type) + /* If RECORD or UNION, recursively find the first field. */ + while (TREE_CODE (type) == RECORD_TYPE + || TREE_CODE (type) == UNION_TYPE + || TREE_CODE (type) == QUAL_UNION_TYPE) { - type = TREE_TYPE (field); - while (TREE_CODE (type) == ARRAY_TYPE) - type = TREE_TYPE (type); + tree field = TYPE_FIELDS (type); + + /* Skip all non field decls */ + while (field != NULL + && (TREE_CODE (field) != FIELD_DECL + || DECL_FIELD_ABI_IGNORED (field))) + field = DECL_CHAIN (field); - if (type != error_mark_node - && (TYPE_MODE (type) == DFmode || TYPE_MODE (type) == DCmode)) - align = MAX (align, 64); + if (field != NULL && field != type) + type = TREE_TYPE (field); + else + break; } + while (TREE_CODE (type) == ARRAY_TYPE) + type = TREE_TYPE (type); + + if (type != error_mark_node + && (TYPE_MODE (type) == DFmode || TYPE_MODE (type) == DCmode)) + align = MAX (align, 64); + + return align; }