From patchwork Tue Feb 5 15:07:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernd Edlinger X-Patchwork-Id: 1036807 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-495305-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=hotmail.de Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="p2HA+I5K"; dkim-atps=neutral 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 43v7HL5Wmgz9sNG for ; Wed, 6 Feb 2019 02:07:57 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:content-type:mime-version; q=dns; s= default; b=wp9kLkMwhNDqFJvVGZRkdbmy9kS/IL2fgJG0T6VlNtiNRcgKImzYW D78fvjw9g5zqQEw/bqofrfYfLnsybIRfrCtw6FDTO5B7M3ZJ/DV2yzjgJ/cJggd7 lwfA8njxqRXWxkSfLWCBALpIMDEIi5ydcImqdVBSegwdrpjDAnq2CE= 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:from :to:subject:date:message-id:content-type:mime-version; s= default; bh=2ElZOckLbdEqCUqri0rxF2tsmMo=; b=p2HA+I5KqreC3/inN054 Pec3rtnsneGCR54nK4S7pwLZfmimXa26KZ3KfAAJZfW4FcOz8GaaS0dQXfnpnlVY RUkBIzOQbxh+idv+MHGVLHgCudvIDpI6/PcQBj9D1g/H3pI4OSSOAPW61XmQUsr2 X1T45z9ujH0On7G5EWDNuT8= Received: (qmail 72149 invoked by alias); 5 Feb 2019 15:07:51 -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 72137 invoked by uid 89); 5 Feb 2019 15:07:50 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-10.6 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KAM_NUMSUBJECT, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 spammy=index.jsp, UD:index.jsp, indexjsp X-HELO: EUR01-HE1-obe.outbound.protection.outlook.com Received: from mail-oln040092065081.outbound.protection.outlook.com (HELO EUR01-HE1-obe.outbound.protection.outlook.com) (40.92.65.81) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 05 Feb 2019 15:07:48 +0000 Received: from HE1EUR01FT043.eop-EUR01.prod.protection.outlook.com (10.152.0.59) by HE1EUR01HT086.eop-EUR01.prod.protection.outlook.com (10.152.1.100) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.1580.10; Tue, 5 Feb 2019 15:07:45 +0000 Received: from VI1PR07MB4864.eurprd07.prod.outlook.com (10.152.0.51) by HE1EUR01FT043.mail.protection.outlook.com (10.152.0.207) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.20.1580.10 via Frontend Transport; Tue, 5 Feb 2019 15:07:44 +0000 Received: from VI1PR07MB4864.eurprd07.prod.outlook.com ([fe80::ddcc:fc12:2074:191f]) by VI1PR07MB4864.eurprd07.prod.outlook.com ([fe80::ddcc:fc12:2074:191f%5]) with mapi id 15.20.1601.016; Tue, 5 Feb 2019 15:07:44 +0000 From: Bernd Edlinger To: "gcc-patches@gcc.gnu.org" , Richard Biener , Richard Earnshaw , "Ramana Radhakrishnan" Subject: [PATCH] Fix not 8-byte aligned ldrd/strd on ARMv5 Date: Tue, 5 Feb 2019 15:07:44 +0000 Message-ID: x-microsoft-original-message-id: <5d4ff198-da9e-b98f-a245-983c97f84498@hotmail.de> MIME-Version: 1.0 Hi, due to the AAPCS parameter passing of 8-byte aligned structures, which happen to be 8-byte aligned or only 4-byte aligned in the test case, ldrd instructions are generated that may access 4-byte aligned stack slots, which will trap on ARMv5 and ARMv6 according to the following document: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0473m/dom1361290002364.html says: "In ARMv5TE, or in ARMv6 when SCTLR.U is 0, LDRD and STRD doubleword data transfers must be eight-byte aligned. Use ALIGN 8 before memory allocation directives such as DCQ if the data is to be accessed using LDRD or STRD. This is not required in ARMv6 when SCTLR.U is 1, or in ARMv7, because in these versions, doubleword data transfers can be word-aligned." The reason why the ldrd instruction is generated seems to be a missing alignment check in the function output_move_double. But when that is fixed, it turns out that if the parameter happens to be 8-byte aligned by chance, they still have MEM_ALIGN = 4, which prevents the ldrd completely. The reason for that is in function.c (assign_parm_find_stack_rtl), where values that happen to be aligned to STACK_BOUNDARY, are only aligned to PARM_BOUNDARY. Bootstrapped and reg-tested on x86_64-pc-linux-gnu and arm-linux-gnueabihf with all languages. Is it OK for trunk? Thanks Bernd. 2019-02-05 Bernd Edlinger * config/arm/arm.c (output_move_double): Check required memory alignment for ldrd/strd instructions. * function.c (assign_parm_find_stack_rtl): Use larger alignment when possible. testsuite: 2019-02-05 Bernd Edlinger * gcc.target/arm/unaligned-argument-1.c: New test. * gcc.target/arm/unaligned-argument-2.c: New test. Index: gcc/config/arm/arm.c =================================================================== --- gcc/config/arm/arm.c (revision 268337) +++ gcc/config/arm/arm.c (working copy) @@ -18303,6 +18303,8 @@ output_move_double (rtx *operands, bool emit, int otherops[0] = gen_rtx_REG (SImode, 1 + reg0); gcc_assert (code1 == MEM); /* Constraints should ensure this. */ + bool allow_ldrd = TARGET_LDRD + && align_ok_ldrd_strd (MEM_ALIGN (operands[1]), 0); switch (GET_CODE (XEXP (operands[1], 0))) { @@ -18310,8 +18312,8 @@ output_move_double (rtx *operands, bool emit, int if (emit) { - if (TARGET_LDRD - && !(fix_cm3_ldrd && reg0 == REGNO(XEXP (operands[1], 0)))) + if (allow_ldrd + && !(fix_cm3_ldrd && reg0 == REGNO (XEXP (operands[1], 0)))) output_asm_insn ("ldrd%?\t%0, [%m1]", operands); else output_asm_insn ("ldmia%?\t%m1, %M0", operands); @@ -18319,7 +18321,7 @@ output_move_double (rtx *operands, bool emit, int break; case PRE_INC: - gcc_assert (TARGET_LDRD); + gcc_assert (allow_ldrd); if (emit) output_asm_insn ("ldrd%?\t%0, [%m1, #8]!", operands); break; @@ -18327,7 +18329,7 @@ output_move_double (rtx *operands, bool emit, int case PRE_DEC: if (emit) { - if (TARGET_LDRD) + if (allow_ldrd) output_asm_insn ("ldrd%?\t%0, [%m1, #-8]!", operands); else output_asm_insn ("ldmdb%?\t%m1!, %M0", operands); @@ -18337,7 +18339,7 @@ output_move_double (rtx *operands, bool emit, int case POST_INC: if (emit) { - if (TARGET_LDRD) + if (allow_ldrd) output_asm_insn ("ldrd%?\t%0, [%m1], #8", operands); else output_asm_insn ("ldmia%?\t%m1!, %M0", operands); @@ -18345,7 +18347,7 @@ output_move_double (rtx *operands, bool emit, int break; case POST_DEC: - gcc_assert (TARGET_LDRD); + gcc_assert (allow_ldrd); if (emit) output_asm_insn ("ldrd%?\t%0, [%m1], #-8", operands); break; @@ -18483,7 +18485,7 @@ output_move_double (rtx *operands, bool emit, int } otherops[0] = gen_rtx_REG(SImode, REGNO(operands[0]) + 1); operands[1] = otherops[0]; - if (TARGET_LDRD + if (allow_ldrd && (REG_P (otherops[2]) || TARGET_THUMB2 || (CONST_INT_P (otherops[2]) @@ -18544,7 +18546,7 @@ output_move_double (rtx *operands, bool emit, int if (count) *count = 2; - if (TARGET_LDRD) + if (allow_ldrd) return "ldrd%?\t%0, [%1]"; return "ldmia%?\t%1, %M0"; @@ -18589,7 +18591,8 @@ output_move_double (rtx *operands, bool emit, int values but user assembly constraints can force an odd starting register. */ bool allow_strd = TARGET_LDRD - && !(TARGET_ARM && (REGNO (operands[1]) & 1) == 1); + && !(TARGET_ARM && (REGNO (operands[1]) & 1) == 1) + && align_ok_ldrd_strd (MEM_ALIGN (operands[0]), 0); switch (GET_CODE (XEXP (operands[0], 0))) { case REG: Index: gcc/function.c =================================================================== --- gcc/function.c (revision 268337) +++ gcc/function.c (working copy) @@ -2698,8 +2698,20 @@ assign_parm_find_stack_rtl (tree parm, struct assi intentionally forcing upward padding. Otherwise we have to come up with a guess at the alignment based on OFFSET_RTX. */ poly_int64 offset; - if (data->locate.where_pad != PAD_DOWNWARD || data->entry_parm) + if (data->locate.where_pad == PAD_NONE || data->entry_parm) align = boundary; + else if (data->locate.where_pad == PAD_UPWARD) + { + align = boundary; + if (poly_int_rtx_p (offset_rtx, &offset) + && STACK_POINTER_OFFSET == 0) + { + unsigned int offset_align = known_alignment (offset) * BITS_PER_UNIT; + if (offset_align == 0 || offset_align > STACK_BOUNDARY) + offset_align = STACK_BOUNDARY; + align = MAX (align, offset_align); + } + } else if (poly_int_rtx_p (offset_rtx, &offset)) { align = least_bit_hwi (boundary); Index: gcc/testsuite/gcc.target/arm/unaligned-argument-1.c =================================================================== --- gcc/testsuite/gcc.target/arm/unaligned-argument-1.c (revision 0) +++ gcc/testsuite/gcc.target/arm/unaligned-argument-1.c (working copy) @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-marm -march=armv6 -mno-unaligned-access -mfloat-abi=soft -mabi=aapcs -O3" } */ + +struct s { + int a, b; +} __attribute__((aligned(8))); + +struct s f0; + +void f(int a, int b, int c, int d, struct s f) +{ + /* f is on a 64 bit aligned stack slot, thus ldrd OK. */ + f0 = f; +} + +/* { dg-final { scan-assembler-times "ldrd" 1 } } */ +/* { dg-final { scan-assembler-times "strd" 1 } } */ Index: gcc/testsuite/gcc.target/arm/unaligned-argument-2.c =================================================================== --- gcc/testsuite/gcc.target/arm/unaligned-argument-2.c (revision 0) +++ gcc/testsuite/gcc.target/arm/unaligned-argument-2.c (working copy) @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-marm -march=armv6 -mno-unaligned-access -mfloat-abi=soft -mabi=aapcs -O3" } */ + +struct s { + int a, b; +} __attribute__((aligned(8))); + +struct s f0; + +void f(int a, int b, int c, int d, int e, struct s f) +{ + /* f is on a 32 bit aligned stack slot, thus no ldrd. */ + f0 = f; +} + +/* { dg-final { scan-assembler-times "ldrd" 0 } } */ +/* { dg-final { scan-assembler-times "strd" 1 } } */