From patchwork Thu Aug 4 14:32:49 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Renlin Li X-Patchwork-Id: 655835 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 3s4sqk5lYvz9sCy for ; Fri, 5 Aug 2016 00:33:21 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=hXrFFkfA; 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:to:cc :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=iyuPJBPolNz00oXxa9KAsiZ+8mH56qY6PwhpOSByxTRcXuFEGJ fpCfiV0dFTVnNEaNyU8DR2e032MHtZm2Bg0DD9d6WxQjWPW90YIIi2RZb9Q16FOc oteg6rLBBUe1wfBtWWnN2KfSMKT7OqTPFHxRwAWbTPBWGcvv9nmvXB+WY= 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:to:cc :from:subject:message-id:date:mime-version:content-type; s= default; bh=ntt8kgFQUql+R3dO6kOSPKDLVEw=; b=hXrFFkfAHiUbE5eQ7UV/ c0X4eTSluxpW5vCz5oRI26ZrarHm18qcyrrhY1YZwFY6WFVtKYDocJrfohcwIbE+ du6vNpzxYrPw8kZj2YQea2kNrKm3UY3mqOAFR5PHDaRpXgc3byyZ2w/YRvrB8ZtA hQR7Wpa/qJlcCBgQHEQinbA= Received: (qmail 22694 invoked by alias); 4 Aug 2016 14:33:08 -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 22685 invoked by uid 89); 4 Aug 2016 14:33:08 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.1 required=5.0 tests=BAYES_00, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=ADDR_EXPR, addr_expr, SImode, simode X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 04 Aug 2016 14:32:54 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 877DC28; Thu, 4 Aug 2016 07:34:15 -0700 (PDT) Received: from [10.2.207.43] (e104453-lin.cambridge.arm.com [10.2.207.43]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 2C9223F25F; Thu, 4 Aug 2016 07:32:50 -0700 (PDT) To: "gcc-patches@gcc.gnu.org" Cc: "law@redhat.com" , Andrew Pinski , Richard Henderson , Ramana Radhakrishnan From: Renlin Li Subject: [PATCH][PR64971]Convert function pointer to Pmode when emit call Message-ID: <57A35211.6090405@foss.arm.com> Date: Thu, 4 Aug 2016 15:32:49 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 X-IsSubscribed: yes Hi all, In the case of PR64971 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64971), the compiler ICE when compiling gcc.c-torture/compile/pr37433.c with ilp32 abi. As we know, in aarch64 ilp32, the ptr_mode is SImode while Pmode is still DImode. It means all address should be DImode, and the backend defines the patterns with this assumption. The generic part expand_expr_addr_expr () function however generates a SYMBOL_REF with SImode, it's later used as the address of a MEM rtx pattern in a call expression. There is no matching pattern for this SImode address, that's why gcc ICEs. (symbol_ref/f:SI ("*.LC0") [flags 0x82] ) But here, I think what expand_expr_addr_expr does is correct. In this particular case, expand_expr_addr_expr is not generating an address. According to the source code, it's generating a function pointer, and later this pointer is used in a call expression. So SImode should be right in this case. The behavior of the test case is, get the address of a piece of memory, cast it into a function pointer, and call the function. IIUC, the flow is like this: CALL_EXPR ( NOP_EXPR (ADDR_EXPR ())) NOP_EXPR here is to convert the address into a function pointer which should be ptr_mode (SImode). So it's the responsibility of call expander to convert the pointer into Pmode to create legal call rtx patern. In the test case, there are two functions. The first function generates function calls with a SYMBOL_REF as address, the second one generates a REG as address. They are all of ptr_mode. However, prepare_call_address () will convert the REG into Pmode to make it as a legal address while SYMBOL_REF is missed. That's why I add the code there. And I want to change the PR64971 into a middle-end issue. The ICE manifests in aarch64 target, but I believe this should be a generic problem for targets which define ptr_mode different from Pmode. There is a test case already, so I didn't add one. aarch64-none-elf regression test Okay, aarch64-linux bootstrap Okay. But I believe this may not help as the default abi is LP64. It will be great if Andrew you can help to do regression test in your aarch64 ilp32 environment. And I double checked that, the backend fix can be removed without any problem. It's good to expose middle-end bugs. Okay for trunk and backport to branch 6? gcc/ChangeLog: 2016-08-04 Renlin Li PR middle-end/64971 * calls.c (prepare_call_address): Convert funexp to Pmode when necessary. * config/aarch64/aarch64.md (sibcall): Remove fix for PR 64971. (sibcall_value): Likewise. diff --git a/gcc/calls.c b/gcc/calls.c index c04d00f..b00c153 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -194,10 +194,19 @@ prepare_call_address (tree fndecl_or_type, rtx funexp, rtx static_chain_value, && targetm.small_register_classes_for_mode_p (FUNCTION_MODE)) ? force_not_mem (memory_address (FUNCTION_MODE, funexp)) : memory_address (FUNCTION_MODE, funexp)); - else if (! sibcallp) + else { - if (!NO_FUNCTION_CSE && optimize && ! flag_no_function_cse) - funexp = force_reg (Pmode, funexp); + /* funexp could be a SYMBOL_REF represents a function pointer which is + of ptr_mode. In this case, it should be converted into address mode + to be a valid address for memory rtx pattern. See PR 64971. */ + if (GET_MODE (funexp) != Pmode) + funexp = convert_memory_address (Pmode, funexp); + + if (! sibcallp) + { + if (!NO_FUNCTION_CSE && optimize && ! flag_no_function_cse) + funexp = force_reg (Pmode, funexp); + } } if (static_chain_value != 0 diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index f15dd8d..c95258b 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -859,13 +859,6 @@ || aarch64_is_noplt_call_p (callee))) XEXP (operands[0], 0) = force_reg (Pmode, callee); - /* FIXME: This is a band-aid. Need to analyze why expand_expr_addr_expr - is generating an SImode symbol reference. See PR 64971. */ - if (TARGET_ILP32 - && GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF - && GET_MODE (XEXP (operands[0], 0)) == SImode) - XEXP (operands[0], 0) = convert_memory_address (Pmode, - XEXP (operands[0], 0)); if (operands[2] == NULL_RTX) operands[2] = const0_rtx; @@ -897,14 +890,6 @@ || aarch64_is_noplt_call_p (callee))) XEXP (operands[1], 0) = force_reg (Pmode, callee); - /* FIXME: This is a band-aid. Need to analyze why expand_expr_addr_expr - is generating an SImode symbol reference. See PR 64971. */ - if (TARGET_ILP32 - && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF - && GET_MODE (XEXP (operands[1], 0)) == SImode) - XEXP (operands[1], 0) = convert_memory_address (Pmode, - XEXP (operands[1], 0)); - if (operands[3] == NULL_RTX) operands[3] = const0_rtx;