From patchwork Wed Nov 23 09:35:19 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 83578 Delivered-To: patch@linaro.org Received: by 10.140.97.165 with SMTP id m34csp2540509qge; Wed, 23 Nov 2016 01:35:45 -0800 (PST) X-Received: by 10.84.191.228 with SMTP id a91mr4770579pld.46.1479893745793; Wed, 23 Nov 2016 01:35:45 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id v142si32863120pgb.7.2016.11.23.01.35.45 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 23 Nov 2016 01:35:45 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-442329-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-442329-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-442329-patch=linaro.org@gcc.gnu.org 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:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=Tq5fdbcCCdoz/FFy AvPmm8JSwMhYEVg1B2z6559bgmxhZ3zKb9q2h3+83CQ0SSErybVGuBo+l2QMK1qw ZeU3cY14AFNW/iOL9b/yHP4BpzWMr/NMQptghgvNKH0bytlEurjKCpbH9mHQXdLv 5la6E2/qQnC2NOx5/fyZxVdu2ls= 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:mime-version:content-type :content-transfer-encoding; s=default; bh=IPNtVn1GcE8MvTRDGCSO7c jeCQA=; b=k1h67cCl694D3+trlQqt6ithGg8uqQbAuxH7ADUtqBvQAJ2OJc6DYB JlhU2NDkH4gfsdGkw/oZwH4iQ5uadGpW5IkaR659SFHTutL5r0reJ33JEfPXA1YP NhZY0C+B08+SfmN1/h/DoQvqOV292ixrSBlO6o1IzRh0AFybG1JK4= Received: (qmail 117927 invoked by alias); 23 Nov 2016 09:35:27 -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 117739 invoked by uid 89); 23 Nov 2016 09:35:25 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.1 required=5.0 tests=AWL, BAYES_00, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=no version=3.3.2 spammy=get_mode, INSN, GET_MODE, SET X-HELO: smtp.eu.adacore.com Received: from mel.act-europe.fr (HELO smtp.eu.adacore.com) (194.98.77.210) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 23 Nov 2016 09:35:22 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 2532881335 for ; Wed, 23 Nov 2016 10:35:20 +0100 (CET) Received: from smtp.eu.adacore.com ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 4TqF9AK_goV6 for ; Wed, 23 Nov 2016 10:35:20 +0100 (CET) Received: from polaris.localnet (bon31-6-88-161-99-133.fbx.proxad.net [88.161.99.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.eu.adacore.com (Postfix) with ESMTPSA id E6956812E8 for ; Wed, 23 Nov 2016 10:35:19 +0100 (CET) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [patch] Fix PR rtl-optimization/78437 Date: Wed, 23 Nov 2016 10:35:19 +0100 Message-ID: <1482247.PF6A0dtnAY@polaris> User-Agent: KMail/4.14.10 (Linux/3.16.7-48-desktop; KDE/4.14.9; x86_64; ; ) MIME-Version: 1.0 Hi, this is a wrong code regression at -O2 on the mainline for Alpha coming from the REE pass (Alpha is one of the 3 architectures enabling REE at -O2 but I'm probably going to enable it for 64-bit SPARC too). The problem arises when a copy is needed in combine_reaching_defs: /* If the destination operand of the extension is a different register than the source operand, then additional restrictions are needed. Note we have to handle cases where we have nested extensions in the source operand. */ bool copy_needed = (REGNO (SET_DEST (PATTERN (cand->insn))) != REGNO (get_extended_src_reg (SET_SRC (PATTERN (cand->insn))))); if (copy_needed) { /* Considering transformation of (set (reg1) (expression)) ... (set (reg2) (any_extend (reg1))) into (set (reg2) (any_extend (expression))) (set (reg1) (reg2)) Note that the mode of reg1 is changed by the transformation, e.g. from QImode to DImode, so the transformation can change the upper bits of reg1. But there is no general check that this will not affect the other reaching uses of reg1: (set (reg1:QI) (expression:QI)) ... (set (reg2:DI) (any_extend:DI (reg1:QI))) ... (use (reg1:DI)) I initially thought that this would only matter for WORD_REGISTER_OPERATIONS targets like Alpha, where the first set in QImode can implicitly set the whole DImode register so the use reads well-defined upper bits, but I now wonder whether this also matters for !WORD_REGISTER_OPERATIONS targets, e.g. x86: (set (reg1:DI) ... ... (set (reg1:QI) (expression:QI)) ... (set (reg2:DI) (any_extend:DI (reg1:QI))) ... (use (reg1:DI)) where the use reads well-defined upper bits from the very first set. Hence the 2 attached versions of the fix: pr78437-1.diff only adds the check for WORD_REGISTER_OPERATIONS targets and was confirmed by Uros as fixing the regression of gcc.dg/atomic/stdatomic-compare-exchange-[1,2].c on Alpha, while pr78437-2.diff adds the check for all targets and was also tested on x86-64. Thoughts? PR rtl-optimization/78437 * ree.c (get_uses): New function. (combine_reaching_defs): When a copy is needed, return false if any reaching use of the source register reads it in a mode larger than the mode it is set in[ and if WORD_REGISTER_OPERATIONS is true]. -- Eric Botcazou Index: ree.c =================================================================== --- ree.c (revision 242632) +++ ree.c (working copy) @@ -499,6 +499,35 @@ get_defs (rtx_insn *insn, rtx reg, vecnext) + { + /* Problem getting some use for this instruction. */ + if (ref_link->ref == NULL) + return NULL; + if (DF_REF_CLASS (ref_link->ref) != DF_REF_REGULAR) + return NULL; + } + + return ref_chain; +} + /* Return true if INSN is (SET (reg REGNO (def_reg)) (if_then_else (cond) (REG x1) (REG x2))) and store x1 and x2 in REG_1 and REG_2. */ @@ -827,6 +856,24 @@ combine_reaching_defs (ext_cand *cand, c if (reg_overlap_mentioned_p (tmp_reg, SET_DEST (PATTERN (cand->insn)))) return false; + /* We must make sure that changing the mode of SRC_REG as destination + register will not affect its reaching uses, which may read its value + in a larger mode because either 1) DEF_INSN implicitly sets it in + word mode for WORD_REGISTER_OPERATIONS targets or 2) DEF_INSN does + not modify its upper bits for !WORD_REGISTER_OPERATIONS targets. */ + const unsigned int prec + = GET_MODE_PRECISION (GET_MODE (SET_DEST (*dest_sub_rtx))); + if (prec < BITS_PER_WORD) + { + struct df_link *uses = get_uses (def_insn, src_reg); + if (!uses) + return false; + + for (df_link *use = uses; use; use = use->next) + if (GET_MODE_PRECISION (GET_MODE (*DF_REF_LOC (use->ref))) > prec) + return false; + } + /* The destination register of the extension insn must not be used or set between the def_insn and cand->insn exclusive. */ if (reg_used_between_p (SET_DEST (PATTERN (cand->insn)),