From patchwork Thu Apr 27 10:44:42 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Polacek X-Patchwork-Id: 755960 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 3wDD9V6ljXz9sNJ for ; Thu, 27 Apr 2017 20:45:02 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="FyXtsGoZ"; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=fD23tW48KF8+bbBR5Ypotb+LHYkLstfEdHrjDh+G46F6IbbpFotWs 1ef1AoFjx/suQTxyCopNPUGl9FxUpPdOP8lP/gjU76qVSOXf2NdtPdBRXUOi7td3 eG2jDAtefXqGa55J/pL8z6c2IAI1RoCf+TlCCbwG6RKVzimdhSDP9I= 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:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=Ww4sLmEn0tO2QlEQXbR536x7Is8=; b=FyXtsGoZzPsbC/DvjtA+ xizv457iQ8C0gwH3544LwXWZar1IdekqNoIzSrGjwhgttY29PJddJ/JZV0B3Qh3e niQyg4HeZ+6VYVlRTy3LttLal0puu95kgO3Sfygi68dxgTt/IXku9+sV/6Z990Sy YG6SsEvM5LpMd/8pqAfaq5E= Received: (qmail 68435 invoked by alias); 27 Apr 2017 10:44:50 -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 68421 invoked by uid 89); 27 Apr 2017 10:44:49 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 27 Apr 2017 10:44:46 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2F6D54E339; Thu, 27 Apr 2017 10:44:47 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 2F6D54E339 Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx09.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=polacek@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 2F6D54E339 Received: from redhat.com (ovpn-204-214.brq.redhat.com [10.40.204.214]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v3RAigYO019243 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 27 Apr 2017 06:44:44 -0400 Date: Thu, 27 Apr 2017 12:44:42 +0200 From: Marek Polacek To: GCC Patches , Jakub Jelinek , Ramana Radhakrishnan , "Richard Earnshaw (lists)" Subject: [PATCH] Backport the recent ARM ABI patch to 6 (PR target/77728) Message-ID: <20170427104442.GA4255@redhat.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.8.0 (2017-02-23) This is a backport of the ARM ABI fix, except that it doesn't change code, only adds the ABI warning. So there were four changes, three of them are changing "else if (res < 0)" to "if (res != 0)" and the fourth was the "res != 0" change in arm_function_arg_boundary. I've verified on a testcase that we now get the warning but there are no changes in .s files. Bootstrapped/regtested on armv7hl-linux-gnueabi, ok for 6? 2017-04-26 Marek Polacek Ramana Radhakrishnan Jakub Jelinek PR target/77728 * config/arm/arm.c: Include gimple.h. (aapcs_layout_arg): Emit -Wpsabi note if arm_needs_doubleword_align returns negative, increment ncrn if it returned non-zero. (arm_needs_doubleword_align): Return int instead of bool, ignore DECL_ALIGN of non-FIELD_DECL TYPE_FIELDS chain members, but if there is any such non-FIELD_DECL > PARM_BOUNDARY aligned decl, return -1 instead of false. (arm_function_arg): Emit -Wpsabi note if arm_needs_doubleword_align returns negative, increment nregs if it returned non-zero. (arm_setup_incoming_varargs): Likewise. (arm_function_arg_boundary): Emit -Wpsabi note if arm_needs_doubleword_align returns negative, return DOUBLEWORD_ALIGNMENT if it returned non-zero. * g++.dg/abi/pr77728-1.C: New test. Marek diff --git gcc/config/arm/arm.c gcc/config/arm/arm.c index 6373103..b3da8c8 100644 --- gcc/config/arm/arm.c +++ gcc/config/arm/arm.c @@ -61,6 +61,7 @@ #include "builtins.h" #include "tm-constrs.h" #include "rtl-iter.h" +#include "gimple.h" /* This file should be included last. */ #include "target-def.h" @@ -78,7 +79,7 @@ struct four_ints /* Forward function declarations. */ static bool arm_const_not_ok_for_debug_p (rtx); -static bool arm_needs_doubleword_align (machine_mode, const_tree); +static int arm_needs_doubleword_align (machine_mode, const_tree); static int arm_compute_static_chain_stack_bytes (void); static arm_stack_offsets *arm_get_frame_offsets (void); static void arm_add_gc_roots (void); @@ -6137,8 +6138,20 @@ aapcs_layout_arg (CUMULATIVE_ARGS *pcum, machine_mode mode, /* C3 - For double-word aligned arguments, round the NCRN up to the next even number. */ ncrn = pcum->aapcs_ncrn; - if ((ncrn & 1) && arm_needs_doubleword_align (mode, type)) - ncrn++; + if (ncrn & 1) + { + int res = arm_needs_doubleword_align (mode, type); + /* Only warn during RTL expansion of call stmts, otherwise we would + warn e.g. during gimplification even on functions that will be + always inlined, and we'd warn multiple times. Don't warn when + called in expand_function_start either, as we warn instead in + arm_function_arg_boundary in that case. */ + if (res < 0 && warn_psabi && currently_expanding_gimple_stmt) + inform (input_location, "parameter passing for argument of type " + "%qT will change in GCC 7.1", type); + if (res != 0) + ncrn++; + } nregs = ARM_NUM_REGS2(mode, type); @@ -6243,12 +6256,16 @@ arm_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype, } } -/* Return true if mode/type need doubleword alignment. */ -static bool +/* Return 1 if double word alignment is required for argument passing. + Return -1 if double word alignment used to be required for argument + passing before PR77728 ABI fix, but is not required anymore. + Return 0 if double word alignment is not required and wasn't requried + before either. */ +static int arm_needs_doubleword_align (machine_mode mode, const_tree type) { if (!type) - return PARM_BOUNDARY < GET_MODE_ALIGNMENT (mode); + return GET_MODE_ALIGNMENT (mode) > PARM_BOUNDARY; /* Scalar and vector types: Use natural alignment, i.e. of base type. */ if (!AGGREGATE_TYPE_P (type)) @@ -6258,12 +6275,21 @@ arm_needs_doubleword_align (machine_mode mode, const_tree type) if (TREE_CODE (type) == ARRAY_TYPE) return TYPE_ALIGN (TREE_TYPE (type)) > PARM_BOUNDARY; + int ret = 0; /* Record/aggregate types: Use greatest member alignment of any member. */ for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) if (DECL_ALIGN (field) > PARM_BOUNDARY) - return true; + { + if (TREE_CODE (field) == FIELD_DECL) + return 1; + else + /* Before PR77728 fix, we were incorrectly considering also + other aggregate fields, like VAR_DECLs, TYPE_DECLs etc. + Make sure we can warn about that with -Wpsabi. */ + ret = -1; + } - return false; + return ret; } @@ -6320,10 +6346,15 @@ arm_function_arg (cumulative_args_t pcum_v, machine_mode mode, } /* Put doubleword aligned quantities in even register pairs. */ - if (pcum->nregs & 1 - && ARM_DOUBLEWORD_ALIGN - && arm_needs_doubleword_align (mode, type)) - pcum->nregs++; + if ((pcum->nregs & 1) && ARM_DOUBLEWORD_ALIGN) + { + int res = arm_needs_doubleword_align (mode, type); + if (res < 0 && warn_psabi) + inform (input_location, "parameter passing for argument of type " + "%qT will change in GCC 7.1", type); + if (res != 0) + pcum->nregs++; + } /* Only allow splitting an arg between regs and memory if all preceding args were allocated to regs. For args passed by reference we only count @@ -6342,9 +6373,15 @@ arm_function_arg (cumulative_args_t pcum_v, machine_mode mode, static unsigned int arm_function_arg_boundary (machine_mode mode, const_tree type) { - return (ARM_DOUBLEWORD_ALIGN && arm_needs_doubleword_align (mode, type) - ? DOUBLEWORD_ALIGNMENT - : PARM_BOUNDARY); + if (!ARM_DOUBLEWORD_ALIGN) + return PARM_BOUNDARY; + + int res = arm_needs_doubleword_align (mode, type); + if (res < 0 && warn_psabi) + inform (input_location, "parameter passing for argument of type %qT " + "will change in GCC 7.1", type); + + return res != 0 ? DOUBLEWORD_ALIGNMENT : PARM_BOUNDARY; } static int @@ -26402,8 +26439,15 @@ arm_setup_incoming_varargs (cumulative_args_t pcum_v, if (pcum->pcs_variant <= ARM_PCS_AAPCS_LOCAL) { nregs = pcum->aapcs_ncrn; - if ((nregs & 1) && arm_needs_doubleword_align (mode, type)) - nregs++; + if (nregs & 1) + { + int res = arm_needs_doubleword_align (mode, type); + if (res < 0 && warn_psabi) + inform (input_location, "parameter passing for argument of " + "type %qT will change in GCC 7.1", type); + if (res != 0) + nregs++; + } } else nregs = pcum->nregs; diff --git gcc/testsuite/g++.dg/abi/pr77728-1.C gcc/testsuite/g++.dg/abi/pr77728-1.C index e69de29..05f08c9 100644 --- gcc/testsuite/g++.dg/abi/pr77728-1.C +++ gcc/testsuite/g++.dg/abi/pr77728-1.C @@ -0,0 +1,171 @@ +// { dg-do compile { target arm_eabi } } +// { dg-options "-Wpsabi" } + +#include + +template +struct A { double p; }; + +A<0> v; + +template +struct B +{ + typedef A T; + int i, j; +}; + +struct C : public B<0> {}; +struct D {}; +struct E : public D, C {}; +struct F : public B<1> {}; +struct G : public F { static double y; }; +struct H : public G {}; +struct I : public D { long long z; }; +struct J : public D { static double z; int i, j; }; + +template +struct K : public D { typedef A T; int i, j; }; + +struct L { static double h; int i, j; }; + +int +fn1 (int a, B<0> b) // { dg-message "note: parameter passing for argument of type \[^\n\r]* will change in GCC 7\.1" } +{ + return a + b.i; +} + +int +fn2 (int a, B<1> b) +{ + return a + b.i; +} + +int +fn3 (int a, L b) // { dg-message "note: parameter passing for argument of type \[^\n\r]* will change in GCC 7\.1" } +{ + return a + b.i; +} + +int +fn4 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, B<0> n, ...) +// { dg-message "note: parameter passing for argument of type \[^\n\r]* will change in GCC 7\.1" "" { target *-*-* } .-1 } +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +int +fn5 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, B<1> n, ...) +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +int +fn6 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, C n, ...) +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +int +fn7 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, E n, ...) +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +int +fn8 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, H n, ...) +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +int +fn9 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, I n, ...) +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +int +fn10 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, J n, ...) +// { dg-message "note: parameter passing for argument of type \[^\n\r]* will change in GCC 7\.1" "" { target *-*-* } .-1 } +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +int +fn11 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, K<0> n, ...) +// { dg-message "note: parameter passing for argument of type \[^\n\r]* will change in GCC 7\.1" "" { target *-*-* } .-1 } +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +int +fn12 (int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, K<2> n, ...) +{ + va_list ap; + va_start (ap, n); + int x = va_arg (ap, int); + va_end (ap); + return x; +} + +void +test () +{ + static B<0> b0; + static B<1> b1; + static L l; + static C c; + static E e; + static H h; + static I i; + static J j; + static K<0> k0; + static K<2> k2; + fn1 (1, b0); // { dg-message "note: parameter passing for argument of type \[^\n\r]* will change in GCC 7\.1" } + fn2 (1, b1); + fn3 (1, l); // { dg-message "note: parameter passing for argument of type \[^\n\r]* will change in GCC 7\.1" } + fn4 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, b0, 1, 2, 3, 4); + // { dg-message "note: parameter passing for argument of type \[^\n\r]* will change in GCC 7\.1" "" { target *-*-* } .-1 } + fn5 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, b1, 1, 2, 3, 4); + fn6 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, c, 1, 2, 3, 4); + fn7 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, e, 1, 2, 3, 4); + fn8 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, h, 1, 2, 3, 4); + fn9 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, i, 1, 2, 3, 4); + fn10 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, j, 1, 2, 3, 4); + // { dg-message "note: parameter passing for argument of type \[^\n\r]* will change in GCC 7\.1" "" { target *-*-* } .-1 } + fn11 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, k0, 1, 2, 3, 4); + // { dg-message "note: parameter passing for argument of type \[^\n\r]* will change in GCC 7\.1" "" { target *-*-* } .-1 } + fn12 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, k2, 1, 2, 3, 4); +}