From patchwork Thu May 18 21:03:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alexander Monakov X-Patchwork-Id: 96048 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp797224vqo; Thu, 18 May 2023 14:04:22 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ428GGGzTR9vcGf1KZUmN35KF2fsSWz3DCukOaLWy1BVsnvIKhcyOmI8/6V7BbgRZiIdxJV X-Received: by 2002:a17:907:3f12:b0:969:edf8:f73b with SMTP id hq18-20020a1709073f1200b00969edf8f73bmr458411ejc.60.1684443862577; Thu, 18 May 2023 14:04:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1684443862; cv=none; d=google.com; s=arc-20160816; b=PEjM9XVBLyPacNUN5FA9096lWGMs/SgHXNZu/1gPmlI6JOE1v+O9KeQxiF4nCXVxfi tHFSBNzK1/X04m3kyy4SIn11ITMbUcUSFPcWLTHZCjBUxrYrLDX1yOlikrohmRhQTp5/ TPUogwk4R1T0cBK/bzXzzM5bfCviEF/VOG+vOWmpVAACn0yl38emJdRO4+iQYxXS6yoC FlFLK8RRvSxS77FmI6X5agb7fPcLIt9BUYnjdsaE4JR6eZkonpThiSdY2/zESD0QjCbz T7YTElRq94xSlhOr1UMyPvY2RdcPnCt1RSUV3IuIPjRZOYG9VelYCOWfN3h20wg2yzaF bxQg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:message-id:date:subject:cc :to:dkim-filter:dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=K/B0BxjsnUNorlUPm2x9IdI4A/ciiXl9USa+hD7NWmE=; b=iLSdGEAkA/vI1Dn1Ac4twdwbF29WsC8LU5moOaUd9kyc0SUfP6/Osl5+1y1QJf2SOp 0mYtDsOCQIeJg3T0EIrIhi7ZXyn9JbFBuTnfWo1fwz98q/7nAEeld772EYQGiRsbv1VH awJxJgutnaM/aVhO5Xn8ea99mszdyD+8RNIGO7mIzA3XEQSHS8xJEpPcT/bWx/V9HFD7 mTZgjkZX11LkiPJGFUlDVTNQbUJJJ833QOmrWryBSMEFl7UFperZxCvmCVKhKPuN+11E q4BgQQ6iZhlg5Ft+cE8dLYM/LRpJ+YQJfouobhJkpnKer6odI9hbiLuk0X7jlO3MDw9Z Ikzw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b="gYD7cA/u"; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id de48-20020a1709069bf000b0096f57957646si515896ejc.510.2023.05.18.14.04.22 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 May 2023 14:04:22 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b="gYD7cA/u"; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 3E6933858CDB for ; Thu, 18 May 2023 21:04:21 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3E6933858CDB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1684443861; bh=K/B0BxjsnUNorlUPm2x9IdI4A/ciiXl9USa+hD7NWmE=; h=To:Cc:Subject:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=gYD7cA/u2kxOqxazLhVGQD+MIVfv4hB5g7DAOkzIXoPhFNmvw2mnw+7yb1Ylbp2e0 rjzfC5tqMnZxoXIvTZibtOHF8sU16R5GnAjLmPNPNjQO59WlIngwDU8kb+YHKqE9O8 NuWsKS/JqtE1WiFjOUf4SCxvfWcerlCKxw8Ocyps= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail.ispras.ru (mail.ispras.ru [83.149.199.84]) by sourceware.org (Postfix) with ESMTPS id 8C1223858CDB for ; Thu, 18 May 2023 21:03:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 8C1223858CDB Received: from localhost.intra.ispras.ru (unknown [10.10.3.121]) by mail.ispras.ru (Postfix) with ESMTP id C08AB4076B3F; Thu, 18 May 2023 21:03:35 +0000 (UTC) DKIM-Filter: OpenDKIM Filter v2.11.0 mail.ispras.ru C08AB4076B3F To: gcc-patches@gcc.gnu.org Cc: Alexander Monakov Subject: [PATCH] c-family: implement -ffp-contract=on Date: Fri, 19 May 2023 00:03:31 +0300 Message-Id: <20230518210331.11564-1-amonakov@ispras.ru> X-Mailer: git-send-email 2.32.0 MIME-Version: 1.0 X-Spam-Status: No, score=-6.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, SPAM_BODY, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Alexander Monakov via Gcc-patches From: Alexander Monakov Reply-To: Alexander Monakov Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1766267407776254291?= X-GMAIL-MSGID: =?utf-8?q?1766267407776254291?= Implement -ffp-contract=on for C and C++ without changing default behavior (=off for -std=cNN, =fast for C++ and -std=gnuNN). gcc/c-family/ChangeLog: * c-gimplify.cc (fma_supported_p): New helper. (c_gimplify_expr) [PLUS_EXPR, MINUS_EXPR]: Implement FMA contraction. gcc/ChangeLog: * common.opt (fp_contract_mode) [on]: Remove fallback. * config/sh/sh.md (*fmasf4): Correct flag_fp_contract_mode test. * doc/invoke.texi (-ffp-contract): Update. * trans-mem.cc (diagnose_tm_1): Skip internal function calls. --- gcc/c-family/c-gimplify.cc | 78 ++++++++++++++++++++++++++++++++++++++ gcc/common.opt | 3 +- gcc/config/sh/sh.md | 2 +- gcc/doc/invoke.texi | 8 ++-- gcc/trans-mem.cc | 3 ++ 5 files changed, 88 insertions(+), 6 deletions(-) diff --git a/gcc/c-family/c-gimplify.cc b/gcc/c-family/c-gimplify.cc index ef5c7d919f..f7635d3b0c 100644 --- a/gcc/c-family/c-gimplify.cc +++ b/gcc/c-family/c-gimplify.cc @@ -41,6 +41,8 @@ along with GCC; see the file COPYING3. If not see #include "c-ubsan.h" #include "tree-nested.h" #include "context.h" +#include "tree-pass.h" +#include "internal-fn.h" /* The gimplification pass converts the language-dependent trees (ld-trees) emitted by the parser into language-independent trees @@ -686,6 +688,14 @@ c_build_bind_expr (location_t loc, tree block, tree body) return bind; } +/* Helper for c_gimplify_expr: test if target supports fma-like FN. */ + +static bool +fma_supported_p (enum internal_fn fn, tree type) +{ + return direct_internal_fn_supported_p (fn, type, OPTIMIZE_FOR_BOTH); +} + /* Gimplification of expression trees. */ /* Do C-specific gimplification on *EXPR_P. PRE_P and POST_P are as in @@ -739,6 +749,74 @@ c_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED, break; } + case PLUS_EXPR: + case MINUS_EXPR: + { + tree type = TREE_TYPE (*expr_p); + /* For -ffp-contract=on we need to attempt FMA contraction only + during initial gimplification. Late contraction across statement + boundaries would violate language semantics. */ + if (SCALAR_FLOAT_TYPE_P (type) + && flag_fp_contract_mode == FP_CONTRACT_ON + && cfun && !(cfun->curr_properties & PROP_gimple_any) + && fma_supported_p (IFN_FMA, type)) + { + bool neg_mul = false, neg_add = code == MINUS_EXPR; + + tree *op0_p = &TREE_OPERAND (*expr_p, 0); + tree *op1_p = &TREE_OPERAND (*expr_p, 1); + + /* Look for ±(x * y) ± z, swapping operands if necessary. */ + if (TREE_CODE (*op0_p) == NEGATE_EXPR + && TREE_CODE (TREE_OPERAND (*op0_p, 0)) == MULT_EXPR) + /* '*EXPR_P' is '-(x * y) ± z'. This is fine. */; + else if (TREE_CODE (*op0_p) != MULT_EXPR) + { + std::swap (op0_p, op1_p); + std::swap (neg_mul, neg_add); + } + if (TREE_CODE (*op0_p) == NEGATE_EXPR) + { + op0_p = &TREE_OPERAND (*op0_p, 0); + neg_mul = !neg_mul; + } + if (TREE_CODE (*op0_p) != MULT_EXPR) + break; + auto_vec ops (3); + ops.quick_push (TREE_OPERAND (*op0_p, 0)); + ops.quick_push (TREE_OPERAND (*op0_p, 1)); + ops.quick_push (*op1_p); + + enum internal_fn ifn = IFN_FMA; + if (neg_mul) + { + if (fma_supported_p (IFN_FNMA, type)) + ifn = IFN_FNMA; + else + ops[0] = build1 (NEGATE_EXPR, type, ops[0]); + } + if (neg_add) + { + enum internal_fn ifn2 = ifn == IFN_FMA ? IFN_FMS : IFN_FNMS; + if (fma_supported_p (ifn2, type)) + ifn = ifn2; + else + ops[2] = build1 (NEGATE_EXPR, type, ops[2]); + } + for (auto &&op : ops) + if (gimplify_expr (&op, pre_p, post_p, is_gimple_val, fb_rvalue) + == GS_ERROR) + return GS_ERROR; + + gcall *call = gimple_build_call_internal_vec (ifn, ops); + gimple_seq_add_stmt_without_update (pre_p, call); + *expr_p = create_tmp_var (type); + gimple_call_set_lhs (call, *expr_p); + return GS_ALL_DONE; + } + break; + } + default:; } diff --git a/gcc/common.opt b/gcc/common.opt index a28ca13385..3daec85aef 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1662,9 +1662,8 @@ Name(fp_contract_mode) Type(enum fp_contract_mode) UnknownError(unknown floating EnumValue Enum(fp_contract_mode) String(off) Value(FP_CONTRACT_OFF) -; Not implemented, fall back to conservative FP_CONTRACT_OFF. EnumValue -Enum(fp_contract_mode) String(on) Value(FP_CONTRACT_OFF) +Enum(fp_contract_mode) String(on) Value(FP_CONTRACT_ON) EnumValue Enum(fp_contract_mode) String(fast) Value(FP_CONTRACT_FAST) diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 4622dba012..5cb1795482 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -9269,7 +9269,7 @@ (define_insn_and_split "*fmasf4" (match_operand:SF 3 "arith_reg_operand" "0"))) (clobber (reg:SI FPSCR_STAT_REG)) (use (reg:SI FPSCR_MODES_REG))] - "TARGET_SH2E && flag_fp_contract_mode != FP_CONTRACT_OFF" + "TARGET_SH2E && flag_fp_contract_mode == FP_CONTRACT_FAST" "fmac %1,%2,%0" "&& can_create_pseudo_p ()" [(parallel [(set (match_dup 0) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index b92b857602..cb1e9a1d9f 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -11983,10 +11983,12 @@ This option is enabled by default at optimization levels @option{-O1}, such as forming of fused multiply-add operations if the target has native support for them. @option{-ffp-contract=on} enables floating-point expression contraction -if allowed by the language standard. This is currently not implemented -and treated equal to @option{-ffp-contract=off}. +if allowed by the language standard. This is implemented for C and C++, +where it enables contraction within one expression, but not across +different statements. -The default is @option{-ffp-contract=fast}. +The default is @option{-ffp-contract=off} for C in a standards compliant mode +(@option{-std=c11} or similar), @option{-ffp-contract=fast} otherwise. @opindex fomit-frame-pointer @item -fomit-frame-pointer diff --git a/gcc/trans-mem.cc b/gcc/trans-mem.cc index 4b129663e0..2174faef4c 100644 --- a/gcc/trans-mem.cc +++ b/gcc/trans-mem.cc @@ -637,6 +637,9 @@ diagnose_tm_1 (gimple_stmt_iterator *gsi, bool *handled_ops_p, { case GIMPLE_CALL: { + if (gimple_call_internal_p (stmt)) + break; + tree fn = gimple_call_fn (stmt); if ((d->summary_flags & DIAG_TM_OUTER) == 0