From patchwork Mon Dec 6 18:43:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robin Dapp X-Patchwork-Id: 48547 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A476F3858428 for ; Mon, 6 Dec 2021 18:47:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A476F3858428 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1638816474; bh=e+++01CcF+kFVO8wqNH23U8Fcs1qNS2mdOOSi3W67tY=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=FrbouyJPsBjsTLbds3rPYxGBTOIwket18dvltXX5I/4qAf99mKBjEmYsXX1uSUJhc CHfwV+Mo9U5H7gRDyK/rdq/v3ZCxy5FOCQ9809lo9jQwmBIXqSc8afWjzOVKvwa1Ea Sq4JABA7Qr3ld2icJMi1rktgl8W6VujbM33I5aow= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) by sourceware.org (Postfix) with ESMTPS id E9A453858C60 for ; Mon, 6 Dec 2021 18:46:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E9A453858C60 Received: from pps.filterd (m0098404.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1B6IGCSP016309; Mon, 6 Dec 2021 18:46:01 GMT Received: from ppma06ams.nl.ibm.com (66.31.33a9.ip4.static.sl-reverse.com [169.51.49.102]) by mx0a-001b2d01.pphosted.com with ESMTP id 3csqna0knf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 Dec 2021 18:46:00 +0000 Received: from pps.filterd (ppma06ams.nl.ibm.com [127.0.0.1]) by ppma06ams.nl.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 1B6IghV9026357; Mon, 6 Dec 2021 18:45:58 GMT Received: from b06cxnps4074.portsmouth.uk.ibm.com (d06relay11.portsmouth.uk.ibm.com [9.149.109.196]) by ppma06ams.nl.ibm.com with ESMTP id 3cqykhysk8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 Dec 2021 18:45:58 +0000 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps4074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1B6IjtCX28049848 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 6 Dec 2021 18:45:55 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id F1D2811C04A; Mon, 6 Dec 2021 18:45:54 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A42D111C04C; Mon, 6 Dec 2021 18:45:54 +0000 (GMT) Received: from li-926bd7cc-2dd1-11b2-a85c-f6adc0f5efec.ibm.com (unknown [9.171.69.25]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Mon, 6 Dec 2021 18:45:54 +0000 (GMT) To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: [PATCH v3 1/7] ifcvt: Check if cmovs are needed. Date: Mon, 6 Dec 2021 19:43:46 +0100 Message-Id: <20211206184352.42264-2-rdapp@linux.ibm.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211206184352.42264-1-rdapp@linux.ibm.com> References: <20211206184352.42264-1-rdapp@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: 2k5oSosIk7WeBG3aglh6QBd50-HA5N1n X-Proofpoint-ORIG-GUID: 2k5oSosIk7WeBG3aglh6QBd50-HA5N1n X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-06_07,2021-12-06_02,2021-12-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 clxscore=1015 bulkscore=0 phishscore=0 impostorscore=0 spamscore=0 mlxscore=0 suspectscore=0 adultscore=0 priorityscore=1501 mlxlogscore=999 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2112060111 X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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: Robin Dapp via Gcc-patches From: Robin Dapp Reply-To: Robin Dapp Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" When if-converting multiple SETs and we encounter a swap-style idiom if (a > b) { tmp = c; // [1] c = d; d = tmp; } ifcvt should not generate a conditional move for the instruction at [1]. In order to achieve that, this patch goes through all relevant SETs and marks the relevant instructions. This helps to evaluate costs. On top, only generate temporaries if the current cmov is going to overwrite one of the comparands of the initial compare. --- gcc/ifcvt.c | 174 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 150 insertions(+), 24 deletions(-) diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 017944f4f79..c98668d5646 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -98,6 +98,8 @@ static int dead_or_predicable (basic_block, basic_block, basic_block, edge, int); static void noce_emit_move_insn (rtx, rtx); static rtx_insn *block_has_only_trap (basic_block); +static void need_cmov_or_rewire (basic_block, hash_set *, + hash_map *); /* Count the number of non-jump active insns in BB. */ @@ -3203,6 +3205,11 @@ noce_convert_multiple_sets (struct noce_if_info *if_info) auto_vec unmodified_insns; int count = 0; + hash_set need_no_cmov; + hash_map rewired_src; + + need_cmov_or_rewire (then_bb, &need_no_cmov, &rewired_src); + FOR_BB_INSNS (then_bb, insn) { /* Skip over non-insns. */ @@ -3213,26 +3220,49 @@ noce_convert_multiple_sets (struct noce_if_info *if_info) gcc_checking_assert (set); rtx target = SET_DEST (set); - rtx temp = gen_reg_rtx (GET_MODE (target)); + rtx temp; + rtx new_val = SET_SRC (set); + if (int *ii = rewired_src.get (insn)) + new_val = simplify_replace_rtx (new_val, targets[*ii], + temporaries[*ii]); rtx old_val = target; - /* If we were supposed to read from an earlier write in this block, - we've changed the register allocation. Rewire the read. While - we are looking, also try to catch a swap idiom. */ - for (int i = count - 1; i >= 0; --i) - if (reg_overlap_mentioned_p (new_val, targets[i])) - { - /* Catch a "swap" style idiom. */ - if (find_reg_note (insn, REG_DEAD, new_val) != NULL_RTX) - /* The write to targets[i] is only live until the read - here. As the condition codes match, we can propagate - the set to here. */ - new_val = SET_SRC (single_set (unmodified_insns[i])); - else - new_val = temporaries[i]; - break; - } + /* As we are transforming + if (x > y) + { + a = b; + c = d; + } + into + a = (x > y) ... + c = (x > y) ... + + we potentially check x > y before every set. + Even though the check might be removed by subsequent passes, this means + that we cannot transform + if (x > y) + { + x = y; + ... + } + into + x = (x > y) ... + ... + since this would invalidate x and the following to-be-removed checks. + Therefore we introduce a temporary every time we are about to + overwrite a variable used in the check. Costing of a sequence with + these is going to be inaccurate so only use temporaries when + needed. */ + if (reg_overlap_mentioned_p (target, cond)) + temp = gen_reg_rtx (GET_MODE (target)); + else + temp = target; + + /* We have identified swap-style idioms before. A normal + set will need to be a cmov while the first instruction of a swap-style + idiom can be a regular move. This helps with costing. */ + bool need_cmov = !need_no_cmov.contains (insn); /* If we had a non-canonical conditional jump (i.e. one where the fallthrough is to the "else" case) we need to reverse @@ -3275,16 +3305,29 @@ noce_convert_multiple_sets (struct noce_if_info *if_info) old_val = lowpart_subreg (dst_mode, old_val, src_mode); } - /* Actually emit the conditional move. */ - rtx temp_dest = noce_emit_cmove (if_info, temp, cond_code, + rtx temp_dest = NULL_RTX; + + if (need_cmov) + { + /* Actually emit the conditional move. */ + temp_dest = noce_emit_cmove (if_info, temp, cond_code, x, y, new_val, old_val); - /* If we failed to expand the conditional move, drop out and don't - try to continue. */ - if (temp_dest == NULL_RTX) + /* If we failed to expand the conditional move, drop out and don't + try to continue. */ + if (temp_dest == NULL_RTX) + { + end_sequence (); + return FALSE; + } + } + else { - end_sequence (); - return FALSE; + if (if_info->then_else_reversed) + noce_emit_move_insn (temp, old_val); + else + noce_emit_move_insn (temp, new_val); + temp_dest = temp; } /* Bookkeeping. */ @@ -3808,6 +3851,89 @@ check_cond_move_block (basic_block bb, return TRUE; } +/* Find local swap-style idioms in BB and mark the first insn (1) + that is only a temporary as not needing a conditional move as + it is going to be dead afterwards anyway. + + (1) int tmp = a; + a = b; + b = tmp; + + ifcvt + --> + + tmp = a; + a = cond ? b : a_old; + b = cond ? tmp : b_old; + + Additionally, store the index of insns like (2) when a subsequent + SET reads from their destination. + + (2) int c = a; + int d = c; + + ifcvt + --> + + c = cond ? a : c_old; + d = cond ? d : c; // Need to use c rather than c_old here. +*/ + +static void +need_cmov_or_rewire (basic_block bb, + hash_set *need_no_cmov, + hash_map *rewired_src) +{ + rtx_insn *insn; + int count = 0; + auto_vec insns; + auto_vec dests; + + /* Iterate over all SETs, storing the destinations + in DEST. + - If we hit a SET that reads from a destination + that we have seen before and the corresponding register + is dead afterwards, the register does not need to be + moved conditionally. + - If we encounter a previously changed register, + rewire the read to the original source. */ + FOR_BB_INSNS (bb, insn) + { + rtx set, src, dest; + + if (!active_insn_p (insn)) + continue; + + set = single_set (insn); + if (set == NULL_RTX) + continue; + + src = SET_SRC (set); + if (SUBREG_P (src)) + src = SUBREG_REG (src); + dest = SET_DEST (set); + + /* Check if the current SET's source is the same + as any previously seen destination. + This is quadratic but the number of insns in BB + is bounded by PARAM_MAX_RTL_IF_CONVERSION_INSNS. */ + if (REG_P (src)) + for (int i = count - 1; i >= 0; --i) + if (reg_overlap_mentioned_p (src, dests[i])) + { + if (find_reg_note (insn, REG_DEAD, src) != NULL_RTX) + need_no_cmov->add (insns[i]); + else + rewired_src->put (insn, i); + } + + insns.safe_push (insn); + dests.safe_push (dest); + + count++; + } +} + /* Given a basic block BB suitable for conditional move conversion, a condition COND, and pointer maps THEN_VALS and ELSE_VALS containing the register values depending on COND, emit the insns in the block as From patchwork Mon Dec 6 18:43:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robin Dapp X-Patchwork-Id: 48549 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 28F3F3858422 for ; Mon, 6 Dec 2021 18:50:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 28F3F3858422 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1638816610; bh=9jPTbKNA3y3RigOP2jj5733//8gZHfm1QIErhfrUiHc=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=yfBLFbCBqBwgT31SkABfnd4SW+TU4nww7/OxTMMHlvtxEP0NfWK30zQXg9iJC/XMx YHGdtdQp0DXWjkvVo7dZLJpM0xyPeC8facvg/v+0w63Sg1+p48mmUr2oJAnscIHpp2 0NhSOU2S8WLRvsPlrx8YXnUrNGDx/VcMiCU7n/Ro= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) by sourceware.org (Postfix) with ESMTPS id 0C9243858428 for ; Mon, 6 Dec 2021 18:46:18 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 0C9243858428 Received: from pps.filterd (m0187473.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1B6INEu5027533; Mon, 6 Dec 2021 18:46:07 GMT Received: from ppma01fra.de.ibm.com (46.49.7a9f.ip4.static.sl-reverse.com [159.122.73.70]) by mx0a-001b2d01.pphosted.com with ESMTP id 3csqrkgdrb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 Dec 2021 18:46:06 +0000 Received: from pps.filterd (ppma01fra.de.ibm.com [127.0.0.1]) by ppma01fra.de.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 1B6IiNZI015921; Mon, 6 Dec 2021 18:46:04 GMT Received: from b06cxnps3075.portsmouth.uk.ibm.com (d06relay10.portsmouth.uk.ibm.com [9.149.109.195]) by ppma01fra.de.ibm.com with ESMTP id 3cqyy96xrg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 Dec 2021 18:46:04 +0000 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps3075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1B6Ik1PP31261170 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 6 Dec 2021 18:46:01 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 38CDB11C04C; Mon, 6 Dec 2021 18:46:01 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id EA6EB11C050; Mon, 6 Dec 2021 18:46:00 +0000 (GMT) Received: from li-926bd7cc-2dd1-11b2-a85c-f6adc0f5efec.ibm.com (unknown [9.171.69.25]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Mon, 6 Dec 2021 18:46:00 +0000 (GMT) To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: [PATCH v3 2/7] ifcvt: Allow constants for noce_convert_multiple. Date: Mon, 6 Dec 2021 19:43:47 +0100 Message-Id: <20211206184352.42264-3-rdapp@linux.ibm.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211206184352.42264-1-rdapp@linux.ibm.com> References: <20211206184352.42264-1-rdapp@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: 2E2RfYH1G8EBSsNOmfxRV-ZGHDf_vP1O X-Proofpoint-GUID: 2E2RfYH1G8EBSsNOmfxRV-ZGHDf_vP1O X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-06_07,2021-12-06_02,2021-12-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 lowpriorityscore=0 phishscore=0 mlxlogscore=687 priorityscore=1501 malwarescore=0 suspectscore=0 adultscore=0 bulkscore=0 spamscore=0 mlxscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2112060111 X-Spam-Status: No, score=-11.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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: Robin Dapp via Gcc-patches From: Robin Dapp Reply-To: Robin Dapp Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" This lifts the restriction of not allowing constants for noce_convert_multiple. The code later checks if a valid sequence is produced anyway. --- gcc/ifcvt.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index c98668d5646..4642176957e 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -3282,7 +3282,9 @@ noce_convert_multiple_sets (struct noce_if_info *if_info) we'll end up trying to emit r4:HI = cond ? (r1:SI) : (r3:HI). Wrap the two cmove operands into subregs if appropriate to prevent that. */ - if (GET_MODE (new_val) != GET_MODE (temp)) + + if (!CONSTANT_P (new_val) + && GET_MODE (new_val) != GET_MODE (temp)) { machine_mode src_mode = GET_MODE (new_val); machine_mode dst_mode = GET_MODE (temp); @@ -3293,7 +3295,8 @@ noce_convert_multiple_sets (struct noce_if_info *if_info) } new_val = lowpart_subreg (dst_mode, new_val, src_mode); } - if (GET_MODE (old_val) != GET_MODE (temp)) + if (!CONSTANT_P (old_val) + && GET_MODE (old_val) != GET_MODE (temp)) { machine_mode src_mode = GET_MODE (old_val); machine_mode dst_mode = GET_MODE (temp); @@ -3435,9 +3438,9 @@ bb_ok_for_noce_convert_multiple_sets (basic_block test_bb) if (!REG_P (dest)) return false; - if (!(REG_P (src) - || (GET_CODE (src) == SUBREG && REG_P (SUBREG_REG (src)) - && subreg_lowpart_p (src)))) + if (!((REG_P (src) || CONSTANT_P (src)) + || (GET_CODE (src) == SUBREG && REG_P (SUBREG_REG (src)) + && subreg_lowpart_p (src)))) return false; /* Destination must be appropriate for a conditional write. */ From patchwork Mon Dec 6 18:43:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robin Dapp X-Patchwork-Id: 48548 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4AE123858411 for ; Mon, 6 Dec 2021 18:49:13 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4AE123858411 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1638816553; bh=uDV9gubH5YjlfcpRfXPDI5FaKDqqrreLvUmoT3wgtB4=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=JxCu6Pt35dOfhIHmoo6iCRzOY+WKRlneq5BZBtPU9hH4gTiSG/huECGUC+HQYrbAc HrU8pywpdeelrTwcr1hqe7jfP0+uobPRz2NPYROABICvnGelrKC7SYvVEIP+KyzE7z 54qtyZKJt82XMz1K/7SP9/y1N0/nrZMMggt0sx+4= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) by sourceware.org (Postfix) with ESMTPS id 32C073858D28 for ; Mon, 6 Dec 2021 18:46:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 32C073858D28 Received: from pps.filterd (m0098394.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1B6Ho2jj014488; Mon, 6 Dec 2021 18:46:12 GMT Received: from ppma04ams.nl.ibm.com (63.31.33a9.ip4.static.sl-reverse.com [169.51.49.99]) by mx0a-001b2d01.pphosted.com with ESMTP id 3cspsust7h-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 Dec 2021 18:46:12 +0000 Received: from pps.filterd (ppma04ams.nl.ibm.com [127.0.0.1]) by ppma04ams.nl.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 1B6Ih4jd023381; Mon, 6 Dec 2021 18:46:10 GMT Received: from b06avi18626390.portsmouth.uk.ibm.com (b06avi18626390.portsmouth.uk.ibm.com [9.149.26.192]) by ppma04ams.nl.ibm.com with ESMTP id 3cqyyafpe1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 Dec 2021 18:46:09 +0000 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06avi18626390.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1B6IcR5S29229374 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 6 Dec 2021 18:38:27 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id D5B4E11C052; Mon, 6 Dec 2021 18:46:06 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 51E0811C05B; Mon, 6 Dec 2021 18:46:06 +0000 (GMT) Received: from li-926bd7cc-2dd1-11b2-a85c-f6adc0f5efec.ibm.com (unknown [9.171.69.25]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Mon, 6 Dec 2021 18:46:06 +0000 (GMT) To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: [PATCH v3 3/7] ifcvt: Improve costs handling for noce_convert_multiple. Date: Mon, 6 Dec 2021 19:43:48 +0100 Message-Id: <20211206184352.42264-4-rdapp@linux.ibm.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211206184352.42264-1-rdapp@linux.ibm.com> References: <20211206184352.42264-1-rdapp@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: JC0469XQdL4WeYhell0J3VxibyCIPskG X-Proofpoint-ORIG-GUID: JC0469XQdL4WeYhell0J3VxibyCIPskG X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-06_07,2021-12-06_02,2021-12-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 phishscore=0 lowpriorityscore=0 malwarescore=0 suspectscore=0 spamscore=0 clxscore=1015 priorityscore=1501 adultscore=0 mlxlogscore=999 bulkscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2112060111 X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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: Robin Dapp via Gcc-patches From: Robin Dapp Reply-To: Robin Dapp Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" When noce_convert_multiple is called the original costs are not yet initialized. Therefore, up to now, costs were only ever unfairly compared against COSTS_N_INSNS (2). This would lead to default_noce_conversion_profitable_p () rejecting all but the most contrived of sequences. This patch temporarily initializes the original costs by counting adding costs for all sets inside the then_bb. --- gcc/ifcvt.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 4642176957e..7e1ae2564a3 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -3408,14 +3408,17 @@ noce_convert_multiple_sets (struct noce_if_info *if_info) (SET (REG) (REG)) insns suitable for conversion to a series of conditional moves. Also check that we have more than one set (other routines can handle a single set better than we would), and - fewer than PARAM_MAX_RTL_IF_CONVERSION_INSNS sets. */ + fewer than PARAM_MAX_RTL_IF_CONVERSION_INSNS sets. While going + through the insns store the sum of their potential costs in COST. */ static bool -bb_ok_for_noce_convert_multiple_sets (basic_block test_bb) +bb_ok_for_noce_convert_multiple_sets (basic_block test_bb, unsigned *cost) { rtx_insn *insn; unsigned count = 0; unsigned param = param_max_rtl_if_conversion_insns; + bool speed_p = optimize_bb_for_speed_p (test_bb); + unsigned potential_cost = 0; FOR_BB_INSNS (test_bb, insn) { @@ -3451,9 +3454,13 @@ bb_ok_for_noce_convert_multiple_sets (basic_block test_bb) if (!can_conditionally_move_p (GET_MODE (dest))) return false; + potential_cost += insn_cost (insn, speed_p); + count++; } + *cost += potential_cost; + /* If we would only put out one conditional move, the other strategies this pass tries are better optimized and will be more appropriate. Some targets want to strictly limit the number of conditional moves @@ -3501,11 +3508,24 @@ noce_process_if_block (struct noce_if_info *if_info) to calculate a value for x. ??? For future expansion, further expand the "multiple X" rules. */ - /* First look for multiple SETS. */ + /* First look for multiple SETS. The original costs already include + a base cost of COSTS_N_INSNS (2): one instruction for the compare + (which we will be needing either way) and one instruction for the + branch. When comparing costs we want to use the branch instruction + cost and the sets vs. the cmovs generated here. Therefore subtract + the costs of the compare before checking. + ??? Actually, instead of the branch instruction costs we might want + to use COSTS_N_INSNS (BRANCH_COST ()) as in other places. */ + + unsigned potential_cost = if_info->original_cost - COSTS_N_INSNS (1); + unsigned old_cost = if_info->original_cost; if (!else_bb && HAVE_conditional_move - && bb_ok_for_noce_convert_multiple_sets (then_bb)) + && bb_ok_for_noce_convert_multiple_sets (then_bb, &potential_cost)) { + /* Temporarily set the original costs to what we estimated so + we can determine if the transformation is worth it. */ + if_info->original_cost = potential_cost; if (noce_convert_multiple_sets (if_info)) { if (dump_file && if_info->transform_name) @@ -3513,6 +3533,9 @@ noce_process_if_block (struct noce_if_info *if_info) if_info->transform_name); return TRUE; } + + /* Restore the original costs. */ + if_info->original_cost = old_cost; } bool speed_p = optimize_bb_for_speed_p (test_bb); From patchwork Mon Dec 6 18:43:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robin Dapp X-Patchwork-Id: 48550 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 506CE3858437 for ; Mon, 6 Dec 2021 18:51:12 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 506CE3858437 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1638816672; bh=TH0b8THLJ2U7E40SSRm1oWDlAhys/HyzjmDnMPQ52W0=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=g0yz854mONZJlultKNHlurYohC/uhfHqBZNlPivL0QuoB//fZOTGQ7EXBH59DN+yP k7M+d3M54TzyfH4iXybTPzHdOORUZ7mmnscNEzK9ENJHOHUiMTDQUNI6bFukyh02vB uY+GiqGNWFag03kVScngeD5vKhiDiNwk4nZjr3IQ= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) by sourceware.org (Postfix) with ESMTPS id E3AAA3858435 for ; Mon, 6 Dec 2021 18:46:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E3AAA3858435 Received: from pps.filterd (m0098394.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1B6Ho2KL014556; Mon, 6 Dec 2021 18:46:19 GMT Received: from ppma06ams.nl.ibm.com (66.31.33a9.ip4.static.sl-reverse.com [169.51.49.102]) by mx0a-001b2d01.pphosted.com with ESMTP id 3cspsust9a-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 Dec 2021 18:46:18 +0000 Received: from pps.filterd (ppma06ams.nl.ibm.com [127.0.0.1]) by ppma06ams.nl.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 1B6Igccm026328; Mon, 6 Dec 2021 18:46:16 GMT Received: from b06avi18878370.portsmouth.uk.ibm.com (b06avi18878370.portsmouth.uk.ibm.com [9.149.26.194]) by ppma06ams.nl.ibm.com with ESMTP id 3cqykhysmx-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 Dec 2021 18:46:16 +0000 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06avi18878370.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1B6IkC7l31719932 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 6 Dec 2021 18:46:12 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id D104711C050; Mon, 6 Dec 2021 18:46:12 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 917D011C04A; Mon, 6 Dec 2021 18:46:12 +0000 (GMT) Received: from li-926bd7cc-2dd1-11b2-a85c-f6adc0f5efec.ibm.com (unknown [9.171.69.25]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Mon, 6 Dec 2021 18:46:12 +0000 (GMT) To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: [PATCH v3 4/7] ifcvt/optabs: Allow using a CC comparison for emit_conditional_move. Date: Mon, 6 Dec 2021 19:43:49 +0100 Message-Id: <20211206184352.42264-5-rdapp@linux.ibm.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211206184352.42264-1-rdapp@linux.ibm.com> References: <20211206184352.42264-1-rdapp@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: dHYKcS-bNSTvtaVRIpp99NaTHNsqWUIP X-Proofpoint-ORIG-GUID: dHYKcS-bNSTvtaVRIpp99NaTHNsqWUIP X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-06_07,2021-12-06_02,2021-12-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 phishscore=0 lowpriorityscore=0 malwarescore=0 suspectscore=0 spamscore=0 clxscore=1015 priorityscore=1501 adultscore=0 mlxlogscore=999 bulkscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2112060111 X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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: Robin Dapp via Gcc-patches From: Robin Dapp Reply-To: Robin Dapp Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Currently we only ever call emit_conditional_move with the comparison (as well as its comparands) we got from the jump. Thus, backends are going to emit a CC comparison for every conditional move that is being generated instead of re-using the existing CC. This, combined with emitting temporaries for each conditional move, causes sky-high costs for conditional moves. This patch allows to re-use a CC so the costing situation is improved a bit. --- gcc/expmed.c | 8 +-- gcc/expr.c | 10 ++-- gcc/ifcvt.c | 45 ++++++++++------- gcc/optabs.c | 135 ++++++++++++++++++++++++++++++++++++++------------- gcc/optabs.h | 4 +- gcc/rtl.h | 11 ++++- 6 files changed, 150 insertions(+), 63 deletions(-) diff --git a/gcc/expmed.c b/gcc/expmed.c index 59734d4841c..af51bad7cfc 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -4122,8 +4122,8 @@ expand_sdiv_pow2 (scalar_int_mode mode, rtx op0, HOST_WIDE_INT d) temp = force_reg (mode, temp); /* Construct "temp2 = (temp2 < 0) ? temp : temp2". */ - temp2 = emit_conditional_move (temp2, LT, temp2, const0_rtx, - mode, temp, temp2, mode, 0); + temp2 = emit_conditional_move (temp2, { LT, temp2, const0_rtx, mode }, + temp, temp2, mode, 0); if (temp2) { rtx_insn *seq = get_insns (); @@ -6125,10 +6125,10 @@ emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1, return 0; if (and_them) - tem = emit_conditional_move (target, code, op0, op1, mode, + tem = emit_conditional_move (target, { code, op0, op1, mode }, tem, const0_rtx, GET_MODE (tem), 0); else - tem = emit_conditional_move (target, code, op0, op1, mode, + tem = emit_conditional_move (target, { code, op0, op1, mode }, trueval, tem, GET_MODE (tem), 0); if (tem == 0) diff --git a/gcc/expr.c b/gcc/expr.c index e0bcbccd905..c5631a9dd2e 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -8840,8 +8840,9 @@ expand_cond_expr_using_cmove (tree treeop0 ATTRIBUTE_UNUSED, op2 = gen_lowpart (mode, op2); /* Try to emit the conditional move. */ - insn = emit_conditional_move (temp, comparison_code, - op00, op01, comparison_mode, + insn = emit_conditional_move (temp, + { comparison_code, op00, op01, + comparison_mode }, op1, op2, mode, unsignedp); @@ -9732,8 +9733,9 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, start_sequence (); /* Try to emit the conditional move. */ - insn = emit_conditional_move (target, comparison_code, - op0, cmpop1, mode, + insn = emit_conditional_move (target, + { comparison_code, + op0, cmpop1, mode }, op0, op1, mode, unsignedp); diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 7e1ae2564a3..3e78e1bb03d 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -772,7 +772,7 @@ static int noce_try_addcc (struct noce_if_info *); static int noce_try_store_flag_constants (struct noce_if_info *); static int noce_try_store_flag_mask (struct noce_if_info *); static rtx noce_emit_cmove (struct noce_if_info *, rtx, enum rtx_code, rtx, - rtx, rtx, rtx); + rtx, rtx, rtx, rtx = NULL, rtx = NULL); static int noce_try_cmove (struct noce_if_info *); static int noce_try_cmove_arith (struct noce_if_info *); static rtx noce_get_alt_condition (struct noce_if_info *, rtx, rtx_insn **); @@ -1711,7 +1711,8 @@ noce_try_store_flag_mask (struct noce_if_info *if_info) static rtx noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code, - rtx cmp_a, rtx cmp_b, rtx vfalse, rtx vtrue) + rtx cmp_a, rtx cmp_b, rtx vfalse, rtx vtrue, rtx cc_cmp, + rtx rev_cc_cmp) { rtx target ATTRIBUTE_UNUSED; int unsignedp ATTRIBUTE_UNUSED; @@ -1743,23 +1744,30 @@ noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code, end_sequence (); } - /* Don't even try if the comparison operands are weird - except that the target supports cbranchcc4. */ - if (! general_operand (cmp_a, GET_MODE (cmp_a)) - || ! general_operand (cmp_b, GET_MODE (cmp_b))) - { - if (!have_cbranchcc4 - || GET_MODE_CLASS (GET_MODE (cmp_a)) != MODE_CC - || cmp_b != const0_rtx) - return NULL_RTX; - } - unsignedp = (code == LTU || code == GEU || code == LEU || code == GTU); - target = emit_conditional_move (x, code, cmp_a, cmp_b, VOIDmode, - vtrue, vfalse, GET_MODE (x), - unsignedp); + if (cc_cmp != NULL_RTX && rev_cc_cmp != NULL_RTX) + target = emit_conditional_move (x, cc_cmp, rev_cc_cmp, + vtrue, vfalse, GET_MODE (x)); + else + { + /* Don't even try if the comparison operands are weird + except that the target supports cbranchcc4. */ + if (! general_operand (cmp_a, GET_MODE (cmp_a)) + || ! general_operand (cmp_b, GET_MODE (cmp_b))) + { + if (!have_cbranchcc4 + || GET_MODE_CLASS (GET_MODE (cmp_a)) != MODE_CC + || cmp_b != const0_rtx) + return NULL_RTX; + } + + target = emit_conditional_move (x, { code, cmp_a, cmp_b, VOIDmode }, + vtrue, vfalse, GET_MODE (x), + unsignedp); + } + if (target) return target; @@ -1795,8 +1803,9 @@ noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code, promoted_target = gen_reg_rtx (GET_MODE (reg_vtrue)); - target = emit_conditional_move (promoted_target, code, cmp_a, cmp_b, - VOIDmode, reg_vtrue, reg_vfalse, + target = emit_conditional_move (promoted_target, + { code, cmp_a, cmp_b, VOIDmode }, + reg_vtrue, reg_vfalse, GET_MODE (reg_vtrue), unsignedp); /* Nope, couldn't do it in that mode either. */ if (!target) diff --git a/gcc/optabs.c b/gcc/optabs.c index 019bbb62882..9513b666e5a 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -52,6 +52,8 @@ static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *, static rtx expand_unop_direct (machine_mode, optab, rtx, rtx, int); static void emit_libcall_block_1 (rtx_insn *, rtx, rtx, rtx, bool); +static rtx emit_conditional_move_1 (rtx, rtx, rtx, rtx, machine_mode); + /* Debug facility for use in GDB. */ void debug_optab_libfuncs (void); @@ -624,12 +626,13 @@ expand_doubleword_shift_condmove (scalar_int_mode op1_mode, optab binoptab, /* Select between them. Do the INTO half first because INTO_SUPERWORD might be the current value of OUTOF_TARGET. */ - if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode, + if (!emit_conditional_move (into_target, { cmp_code, cmp1, cmp2, op1_mode }, into_target, into_superword, word_mode, false)) return false; if (outof_target != 0) - if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode, + if (!emit_conditional_move (outof_target, + { cmp_code, cmp1, cmp2, op1_mode }, outof_target, outof_superword, word_mode, false)) return false; @@ -4843,8 +4846,8 @@ emit_indirect_jump (rtx loc) is not supported. */ rtx -emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1, - machine_mode cmode, rtx op2, rtx op3, +emit_conditional_move (rtx target, struct rtx_comparison comp, + rtx op2, rtx op3, machine_mode mode, int unsignedp) { rtx comparison; @@ -4866,31 +4869,33 @@ emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1, /* If one operand is constant, make it the second one. Only do this if the other operand is not constant as well. */ - if (swap_commutative_operands_p (op0, op1)) + if (swap_commutative_operands_p (comp.op0, comp.op1)) { - std::swap (op0, op1); - code = swap_condition (code); + std::swap (comp.op0, comp.op1); + comp.code = swap_condition (comp.code); } /* get_condition will prefer to generate LT and GT even if the old comparison was against zero, so undo that canonicalization here since comparisons against zero are cheaper. */ - if (code == LT && op1 == const1_rtx) - code = LE, op1 = const0_rtx; - else if (code == GT && op1 == constm1_rtx) - code = GE, op1 = const0_rtx; - if (cmode == VOIDmode) - cmode = GET_MODE (op0); + if (comp.code == LT && comp.op1 == const1_rtx) + comp.code = LE, comp.op1 = const0_rtx; + else if (comp.code == GT && comp.op1 == constm1_rtx) + comp.code = GE, comp.op1 = const0_rtx; + + if (comp.mode == VOIDmode) + comp.mode = GET_MODE (comp.op0); - enum rtx_code orig_code = code; + enum rtx_code orig_code = comp.code; bool swapped = false; if (swap_commutative_operands_p (op2, op3) - && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL)) + && ((reversed = + reversed_comparison_code_parts (comp.code, comp.op0, comp.op1, NULL)) != UNKNOWN)) { std::swap (op2, op3); - code = reversed; + comp.code = reversed; swapped = true; } @@ -4907,8 +4912,10 @@ emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1, for (int pass = 0; ; pass++) { - code = unsignedp ? unsigned_condition (code) : code; - comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1); + comp.code = unsignedp ? unsigned_condition (comp.code) : comp.code; + comparison = + simplify_gen_relational (comp.code, VOIDmode, + comp.mode, comp.op0, comp.op1); /* We can get const0_rtx or const_true_rtx in some circumstances. Just punt and let the caller figure out how best to deal with this @@ -4919,24 +4926,16 @@ emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1, save_pending_stack_adjust (&save); last = get_last_insn (); do_pending_stack_adjust (); - machine_mode cmpmode = cmode; + machine_mode cmpmode = comp.mode; prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1), GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN, &comparison, &cmpmode); if (comparison) { - class expand_operand ops[4]; - - create_output_operand (&ops[0], target, mode); - create_fixed_operand (&ops[1], comparison); - create_input_operand (&ops[2], op2, mode); - create_input_operand (&ops[3], op3, mode); - if (maybe_expand_insn (icode, 4, ops)) - { - if (ops[0].value != target) - convert_move (target, ops[0].value, false); - return target; - } + rtx res = emit_conditional_move_1 (target, comparison, + op2, op3, mode); + if (res != NULL_RTX) + return res; } delete_insns_since (last); restore_pending_stack_adjust (&save); @@ -4948,17 +4947,85 @@ emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1, /* If the preferred op2/op3 order is not usable, retry with other operand order, perhaps it will expand successfully. */ if (swapped) - code = orig_code; - else if ((reversed = reversed_comparison_code_parts (orig_code, op0, op1, + comp.code = orig_code; + else if ((reversed = + reversed_comparison_code_parts (orig_code, comp.op0, comp.op1, NULL)) != UNKNOWN) - code = reversed; + comp.code = reversed; else return NULL_RTX; std::swap (op2, op3); } } +/* Helper function that, in addition to COMPARISON, also tries + the reversed REV_COMPARISON with swapped OP2 and OP3. As opposed + to when we pass the specific constituents of a comparison, no + additional insns are emitted for it. It might still be necessary + to emit more than one insn for the final conditional move, though. */ + +rtx +emit_conditional_move (rtx target, rtx comparison, rtx rev_comparison, + rtx op2, rtx op3, machine_mode mode) +{ + rtx res = emit_conditional_move_1 (target, comparison, op2, op3, mode); + + if (res != NULL_RTX) + return res; + + return emit_conditional_move_1 (target, rev_comparison, op3, op2, mode); +} + +/* Helper for emitting a conditional move. */ + +static rtx +emit_conditional_move_1 (rtx target, rtx comparison, + rtx op2, rtx op3, machine_mode mode) +{ + enum insn_code icode; + + if (comparison == NULL_RTX || !COMPARISON_P (comparison)) + return NULL_RTX; + + /* If the two source operands are identical, that's just a move. */ + if (rtx_equal_p (op2, op3)) + { + if (!target) + target = gen_reg_rtx (mode); + + emit_move_insn (target, op3); + return target; + } + + if (mode == VOIDmode) + mode = GET_MODE (op2); + + icode = direct_optab_handler (movcc_optab, mode); + + if (icode == CODE_FOR_nothing) + return NULL_RTX; + + if (!target) + target = gen_reg_rtx (mode); + + class expand_operand ops[4]; + + create_output_operand (&ops[0], target, mode); + create_fixed_operand (&ops[1], comparison); + create_input_operand (&ops[2], op2, mode); + create_input_operand (&ops[3], op3, mode); + + if (maybe_expand_insn (icode, 4, ops)) + { + if (ops[0].value != target) + convert_move (target, ops[0].value, false); + return target; + } + + return NULL_RTX; +} + /* Emit a conditional negate or bitwise complement using the negcc or notcc optabs if available. Return NULL_RTX if such operations diff --git a/gcc/optabs.h b/gcc/optabs.h index 3bbceff92d9..700dfa24139 100644 --- a/gcc/optabs.h +++ b/gcc/optabs.h @@ -279,8 +279,8 @@ extern void emit_indirect_jump (rtx); #endif /* Emit a conditional move operation. */ -rtx emit_conditional_move (rtx, enum rtx_code, rtx, rtx, machine_mode, - rtx, rtx, machine_mode, int); +rtx emit_conditional_move (rtx, rtx_comparison, rtx, rtx, machine_mode, int); +rtx emit_conditional_move (rtx, rtx, rtx, rtx, rtx, machine_mode); /* Emit a conditional negate or bitwise complement operation. */ rtx emit_conditional_neg_or_complement (rtx, rtx_code, machine_mode, rtx, diff --git a/gcc/rtl.h b/gcc/rtl.h index 5473cc9f2dd..85d0bdf48b1 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -4589,7 +4589,16 @@ word_register_operation_p (const_rtx x) return true; } } - + +/* Holds an rtx comparison to simplify passing many parameters pertaining to a + single comparison. */ + +struct rtx_comparison { + rtx_code code; + rtx op0, op1; + machine_mode mode; +}; + /* gtype-desc.c. */ extern void gt_ggc_mx (rtx &); extern void gt_pch_nx (rtx &); From patchwork Mon Dec 6 18:43:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robin Dapp X-Patchwork-Id: 48551 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6BECF385843B for ; Mon, 6 Dec 2021 18:52:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6BECF385843B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1638816735; bh=xhtZzBZxejbV/5h9CuJZSR+qBAYxPGFBxremizatopQ=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=yrHLZLmMiON5c/wK9a9nzhrIRhQVrCsQ+tZSv4X7/Bzegd2ClpNJ13otXerDJkPZN M0sT4EkPQOORSQ0AE/zC/+aQxH8Cp6txic+x7FDcemDWSz9I8K7Ym0dOXQ7X3m+j9G oNLzgEradyCm+z34ilaXIk+F879YJE4BMX6zW9SQ= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) by sourceware.org (Postfix) with ESMTPS id 8D84B3858414 for ; Mon, 6 Dec 2021 18:46:28 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8D84B3858414 Received: from pps.filterd (m0187473.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1B6INDxL027507; Mon, 6 Dec 2021 18:46:24 GMT Received: from ppma03fra.de.ibm.com (6b.4a.5195.ip4.static.sl-reverse.com [149.81.74.107]) by mx0a-001b2d01.pphosted.com with ESMTP id 3csqrkgdx8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 Dec 2021 18:46:24 +0000 Received: from pps.filterd (ppma03fra.de.ibm.com [127.0.0.1]) by ppma03fra.de.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 1B6IhtPN027625; Mon, 6 Dec 2021 18:46:22 GMT Received: from b06cxnps4076.portsmouth.uk.ibm.com (d06relay13.portsmouth.uk.ibm.com [9.149.109.198]) by ppma03fra.de.ibm.com with ESMTP id 3cqyy96w78-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 Dec 2021 18:46:22 +0000 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps4076.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1B6IkIKo29098454 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 6 Dec 2021 18:46:18 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id A1C4711C04C; Mon, 6 Dec 2021 18:46:18 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6DFA511C052; Mon, 6 Dec 2021 18:46:18 +0000 (GMT) Received: from li-926bd7cc-2dd1-11b2-a85c-f6adc0f5efec.ibm.com (unknown [9.171.69.25]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Mon, 6 Dec 2021 18:46:18 +0000 (GMT) To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: [PATCH v3 5/7] ifcvt: Try re-using CC for conditional moves. Date: Mon, 6 Dec 2021 19:43:50 +0100 Message-Id: <20211206184352.42264-6-rdapp@linux.ibm.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211206184352.42264-1-rdapp@linux.ibm.com> References: <20211206184352.42264-1-rdapp@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: iL1atfFL9bu6ErFv4Nhpzlx9laNzXjgr X-Proofpoint-GUID: iL1atfFL9bu6ErFv4Nhpzlx9laNzXjgr X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-06_07,2021-12-06_02,2021-12-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 lowpriorityscore=0 phishscore=0 mlxlogscore=999 priorityscore=1501 malwarescore=0 suspectscore=0 adultscore=0 bulkscore=0 spamscore=0 mlxscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2112060111 X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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: Robin Dapp via Gcc-patches From: Robin Dapp Reply-To: Robin Dapp Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Following up on the previous patch, this patch makes noce_convert_multiple emit two cmov sequences: The same one as before and a second one that tries to re-use the existing CC. Then their costs are compared and the cheaper one is selected. --- gcc/ifcvt.c | 112 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 88 insertions(+), 24 deletions(-) diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 3e78e1bb03d..d1e7db1ee27 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -83,7 +83,7 @@ static rtx_insn *last_active_insn (basic_block, int); static rtx_insn *find_active_insn_before (basic_block, rtx_insn *); static rtx_insn *find_active_insn_after (basic_block, rtx_insn *); static basic_block block_fallthru (basic_block); -static rtx cond_exec_get_condition (rtx_insn *); +static rtx cond_exec_get_condition (rtx_insn *, bool); static rtx noce_get_condition (rtx_insn *, rtx_insn **, bool); static int noce_operand_ok (const_rtx); static void merge_if_block (ce_if_block *); @@ -427,7 +427,7 @@ cond_exec_process_insns (ce_if_block *ce_info ATTRIBUTE_UNUSED, /* Return the condition for a jump. Do not do any special processing. */ static rtx -cond_exec_get_condition (rtx_insn *jump) +cond_exec_get_condition (rtx_insn *jump, bool get_reversed = false) { rtx test_if, cond; @@ -439,8 +439,9 @@ cond_exec_get_condition (rtx_insn *jump) /* If this branches to JUMP_LABEL when the condition is false, reverse the condition. */ - if (GET_CODE (XEXP (test_if, 2)) == LABEL_REF - && label_ref_label (XEXP (test_if, 2)) == JUMP_LABEL (jump)) + if (get_reversed || (GET_CODE (XEXP (test_if, 2)) == LABEL_REF + && label_ref_label (XEXP (test_if, 2)) + == JUMP_LABEL (jump))) { enum rtx_code rev = reversed_comparison_code (cond, jump); if (rev == UNKNOWN) @@ -3146,6 +3147,46 @@ bb_valid_for_noce_process_p (basic_block test_bb, rtx cond, return false; } +/* Helper function to emit a cmov sequence. */ + +static rtx_insn* +try_emit_cmove_seq (struct noce_if_info *if_info, rtx temp, + rtx cond, rtx new_val, rtx old_val, bool need_cmov, + unsigned *cost, rtx *temp_dest, + rtx cc_cmp = NULL, rtx rev_cc_cmp = NULL) +{ + rtx_insn *seq = NULL; + *cost = 0; + + rtx x = XEXP (cond, 0); + rtx y = XEXP (cond, 1); + rtx_code cond_code = GET_CODE (cond); + + start_sequence (); + + if (need_cmov) + *temp_dest = noce_emit_cmove (if_info, temp, cond_code, + x, y, new_val, old_val, cc_cmp, rev_cc_cmp); + else + { + *temp_dest = temp; + if (if_info->then_else_reversed) + noce_emit_move_insn (temp, old_val); + else + noce_emit_move_insn (temp, new_val); + } + + if (*temp_dest != NULL_RTX) + { + seq = get_insns (); + *cost = seq_cost (seq, if_info->speed_p); + } + + end_sequence (); + + return seq; +} + /* We have something like: if (x > y) @@ -3203,7 +3244,9 @@ noce_convert_multiple_sets (struct noce_if_info *if_info) rtx cond = noce_get_condition (jump, &cond_earliest, false); rtx x = XEXP (cond, 0); rtx y = XEXP (cond, 1); - rtx_code cond_code = GET_CODE (cond); + + rtx cc_cmp = cond_exec_get_condition (jump); + rtx rev_cc_cmp = cond_exec_get_condition (jump, /* get_reversed */ true); /* The true targets for a conditional move. */ auto_vec targets; @@ -3317,31 +3360,51 @@ noce_convert_multiple_sets (struct noce_if_info *if_info) old_val = lowpart_subreg (dst_mode, old_val, src_mode); } - rtx temp_dest = NULL_RTX; + /* Try emitting a conditional move passing the backend the + canonicalized comparison. The backend is then able to + recognize expressions like - if (need_cmov) + if (x > y) + y = x; + + as min/max and emit an insn, accordingly. */ + unsigned cost1 = 0, cost2 = 0; + rtx_insn *seq, *seq1, *seq2; + rtx temp_dest = NULL_RTX, temp_dest1 = NULL_RTX, temp_dest2 = NULL_RTX; + + seq1 = try_emit_cmove_seq (if_info, temp, cond, + new_val, old_val, need_cmov, + &cost1, &temp_dest1); + + /* Here, we try to pass the backend a non-canonicalized cc comparison + as well. This allows the backend to emit a cmov directly without + creating an additional compare for each. If successful, costing + is easier and this sequence is usually preferred. */ + seq2 = try_emit_cmove_seq (if_info, target, cond, + new_val, old_val, need_cmov, + &cost2, &temp_dest2, cc_cmp, rev_cc_cmp); + + /* Check which version is less expensive. */ + if (seq1 != NULL_RTX && (cost1 <= cost2 || seq2 == NULL_RTX)) { - /* Actually emit the conditional move. */ - temp_dest = noce_emit_cmove (if_info, temp, cond_code, - x, y, new_val, old_val); - - /* If we failed to expand the conditional move, drop out and don't - try to continue. */ - if (temp_dest == NULL_RTX) - { - end_sequence (); - return FALSE; - } + seq = seq1; + temp_dest = temp_dest1; + } + else if (seq2 != NULL_RTX) + { + seq = seq2; + temp_dest = temp_dest2; } else { - if (if_info->then_else_reversed) - noce_emit_move_insn (temp, old_val); - else - noce_emit_move_insn (temp, new_val); - temp_dest = temp; + /* Nothing worked, bail out. */ + end_sequence (); + return FALSE; } + /* End the sub sequence and emit to the main sequence. */ + emit_insn (seq); + /* Bookkeeping. */ count++; targets.safe_push (target); @@ -3355,7 +3418,8 @@ noce_convert_multiple_sets (struct noce_if_info *if_info) /* Now fixup the assignments. */ for (int i = 0; i < count; i++) - noce_emit_move_insn (targets[i], temporaries[i]); + if (targets[i] != temporaries[i]) + noce_emit_move_insn (targets[i], temporaries[i]); /* Actually emit the sequence if it isn't too expensive. */ rtx_insn *seq = get_insns (); From patchwork Mon Dec 6 18:43:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robin Dapp X-Patchwork-Id: 48552 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 937D03858425 for ; Mon, 6 Dec 2021 18:53:12 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 937D03858425 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1638816792; bh=AddDOVqQ8cUBhfJPKazF1c/NgSWdyNezAfx1/yl+4fE=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=MStGYgqAvzNA91E8q3SHlxTgJIwxvtkBY9zrB2cSr1YCW8JPSi2KrFX7a+/M3x6qQ +NHtUeq2AAyNuBQUA+IgFQWf+3aesneK3qJ+CyEeaMRn+eK56b94F+1M7XDv010p8u prwiLIBxnzED1uBBC2Yb5GI87OUU7VDX7iCjt+DE= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) by sourceware.org (Postfix) with ESMTPS id 51BFA3858436 for ; Mon, 6 Dec 2021 18:46:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 51BFA3858436 Received: from pps.filterd (m0098394.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1B6Ho1qb014470; Mon, 6 Dec 2021 18:46:30 GMT Received: from ppma01fra.de.ibm.com (46.49.7a9f.ip4.static.sl-reverse.com [159.122.73.70]) by mx0a-001b2d01.pphosted.com with ESMTP id 3cspsustce-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 Dec 2021 18:46:29 +0000 Received: from pps.filterd (ppma01fra.de.ibm.com [127.0.0.1]) by ppma01fra.de.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 1B6IiR8H015962; Mon, 6 Dec 2021 18:46:27 GMT Received: from b06cxnps4075.portsmouth.uk.ibm.com (d06relay12.portsmouth.uk.ibm.com [9.149.109.197]) by ppma01fra.de.ibm.com with ESMTP id 3cqyy96xte-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 Dec 2021 18:46:27 +0000 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps4075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1B6IkO5D30146848 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 6 Dec 2021 18:46:24 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 36A4511C04C; Mon, 6 Dec 2021 18:46:24 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E4C9A11C054; Mon, 6 Dec 2021 18:46:23 +0000 (GMT) Received: from li-926bd7cc-2dd1-11b2-a85c-f6adc0f5efec.ibm.com (unknown [9.171.69.25]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Mon, 6 Dec 2021 18:46:23 +0000 (GMT) To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: [PATCH v3 6/7] testsuite/s390: Add tests for noce_convert_multiple. Date: Mon, 6 Dec 2021 19:43:51 +0100 Message-Id: <20211206184352.42264-7-rdapp@linux.ibm.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211206184352.42264-1-rdapp@linux.ibm.com> References: <20211206184352.42264-1-rdapp@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: adryorcLHvBD-RweNSpuST9xuCFpXwBh X-Proofpoint-ORIG-GUID: adryorcLHvBD-RweNSpuST9xuCFpXwBh X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-06_07,2021-12-06_02,2021-12-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 phishscore=0 lowpriorityscore=0 malwarescore=0 suspectscore=0 spamscore=0 clxscore=1015 priorityscore=1501 adultscore=0 mlxlogscore=999 bulkscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2112060111 X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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: Robin Dapp via Gcc-patches From: Robin Dapp Reply-To: Robin Dapp Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Add new s390-specific tests that check if we convert two SETs into two loads on condition. Remove the s390-specific target-check in gcc.dg/ifcvt-4.c. --- gcc/testsuite/gcc.dg/ifcvt-4.c | 2 +- .../gcc.target/s390/ifcvt-two-insns-bool.c | 39 +++++++++++++++++++ .../gcc.target/s390/ifcvt-two-insns-int.c | 39 +++++++++++++++++++ .../gcc.target/s390/ifcvt-two-insns-long.c | 39 +++++++++++++++++++ 4 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/s390/ifcvt-two-insns-bool.c create mode 100644 gcc/testsuite/gcc.target/s390/ifcvt-two-insns-int.c create mode 100644 gcc/testsuite/gcc.target/s390/ifcvt-two-insns-long.c diff --git a/gcc/testsuite/gcc.dg/ifcvt-4.c b/gcc/testsuite/gcc.dg/ifcvt-4.c index ec142cfd943..871ab950756 100644 --- a/gcc/testsuite/gcc.dg/ifcvt-4.c +++ b/gcc/testsuite/gcc.dg/ifcvt-4.c @@ -2,7 +2,7 @@ /* { dg-additional-options "-misel" { target { powerpc*-*-* } } } */ /* { dg-additional-options "-march=z196" { target { s390x-*-* } } } */ /* { dg-additional-options "-mtune-ctrl=^one_if_conv_insn" { target { i?86-*-* x86_64-*-* } } } */ -/* { dg-skip-if "Multiple set if-conversion not guaranteed on all subtargets" { "arm*-*-* avr-*-* hppa*64*-*-* s390-*-* visium-*-*" riscv*-*-* msp430-*-* } } */ +/* { dg-skip-if "Multiple set if-conversion not guaranteed on all subtargets" { "arm*-*-* avr-*-* hppa*64*-*-* visium-*-*" riscv*-*-* msp430-*-* } } */ /* { dg-skip-if "" { "s390x-*-*" } { "-m31" } } */ typedef int word __attribute__((mode(word))); diff --git a/gcc/testsuite/gcc.target/s390/ifcvt-two-insns-bool.c b/gcc/testsuite/gcc.target/s390/ifcvt-two-insns-bool.c new file mode 100644 index 00000000000..4415cb49f11 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/ifcvt-two-insns-bool.c @@ -0,0 +1,39 @@ +/* Check if conversion for two instructions. */ + +/* { dg-do run } */ +/* { dg-options "-O2 -march=z13 --save-temps" } */ + +/* { dg-final { scan-assembler "lochinhe\t%r.?,1" } } */ +/* { dg-final { scan-assembler "locrnhe\t.*" } } */ +#include +#include +#include +#include + +__attribute__ ((noinline)) +int foo (int *a, unsigned int n) +{ + int min = 999999; + bool bla = false; + for (int i = 0; i < n; i++) + { + if (a[i] < min) + { + min = a[i]; + bla = true; + } + } + + if (bla) + min += 1; + return min; +} + +int main() +{ + int a[] = {2, 1, -13, INT_MAX, INT_MIN, 0}; + + int res = foo (a, sizeof (a)); + + assert (res == (INT_MIN + 1)); +} diff --git a/gcc/testsuite/gcc.target/s390/ifcvt-two-insns-int.c b/gcc/testsuite/gcc.target/s390/ifcvt-two-insns-int.c new file mode 100644 index 00000000000..db8df84cced --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/ifcvt-two-insns-int.c @@ -0,0 +1,39 @@ +/* Check if conversion for two instructions. */ + +/* { dg-do run } */ +/* { dg-options "-O2 -march=z13 --save-temps" } */ + +/* { dg-final { scan-assembler "lochinhe\t%r.?,1" } } */ +/* { dg-final { scan-assembler "locrnhe\t.*" } } */ +#include +#include +#include +#include + +__attribute__ ((noinline)) +int foo (int *a, unsigned int n) +{ + int min = 999999; + int bla = 0; + for (int i = 0; i < n; i++) + { + if (a[i] < min) + { + min = a[i]; + bla = 1; + } + } + + if (bla) + min += 1; + return min; +} + +int main() +{ + int a[] = {2, 1, -13, INT_MAX, INT_MIN, 0}; + + int res = foo (a, sizeof (a)); + + assert (res == (INT_MIN + 1)); +} diff --git a/gcc/testsuite/gcc.target/s390/ifcvt-two-insns-long.c b/gcc/testsuite/gcc.target/s390/ifcvt-two-insns-long.c new file mode 100644 index 00000000000..bee63328729 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/ifcvt-two-insns-long.c @@ -0,0 +1,39 @@ +/* Check if conversion for two instructions. */ + +/* { dg-do run } */ +/* { dg-options "-O2 -march=z13 --save-temps" } */ + +/* { dg-final { scan-assembler "locghinhe\t%r.?,1" } } */ +/* { dg-final { scan-assembler "locgrnhe\t.*" } } */ +#include +#include +#include +#include + +__attribute__ ((noinline)) +long foo (long *a, unsigned long n) +{ + long min = 999999; + long bla = 0; + for (int i = 0; i < n; i++) + { + if (a[i] < min) + { + min = a[i]; + bla = 1; + } + } + + if (bla) + min += 1; + return min; +} + +int main() +{ + long a[] = {2, 1, -13, LONG_MAX, LONG_MIN, 0}; + + long res = foo (a, sizeof (a)); + + assert (res == (LONG_MIN + 1)); +} From patchwork Mon Dec 6 18:43:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robin Dapp X-Patchwork-Id: 48553 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B9F373858434 for ; Mon, 6 Dec 2021 18:54:09 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B9F373858434 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1638816849; bh=pQu7dEX8igQe12bjklQQnavpUdcxGlyPurzD806fGuM=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=Lo4OkLi6a9pj9lP3/D8h/lH2U+4aeQAYV7I+XesLnhQnh9Y5l3EGIEEvojJz0JncJ I+4VrIuIfJX2g5UcvqWLJJ4T8XDCEe7ySip3L0ZkWBtmwuL79rMdzsjdvMNrgoidu/ Y3pFuszNcbjb5A3JVXgy3tkpba55zVXTvXPJFYTU= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) by sourceware.org (Postfix) with ESMTPS id 940C23858431 for ; Mon, 6 Dec 2021 18:46:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 940C23858431 Received: from pps.filterd (m0098410.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 1B6HnvoQ013051; Mon, 6 Dec 2021 18:46:37 GMT Received: from ppma04fra.de.ibm.com (6a.4a.5195.ip4.static.sl-reverse.com [149.81.74.106]) by mx0a-001b2d01.pphosted.com with ESMTP id 3csq7bhb6y-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 Dec 2021 18:46:37 +0000 Received: from pps.filterd (ppma04fra.de.ibm.com [127.0.0.1]) by ppma04fra.de.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 1B6IhlPj008953; Mon, 6 Dec 2021 18:46:34 GMT Received: from b06cxnps4075.portsmouth.uk.ibm.com (d06relay12.portsmouth.uk.ibm.com [9.149.109.197]) by ppma04fra.de.ibm.com with ESMTP id 3cqyy9ex1k-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 Dec 2021 18:46:34 +0000 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps4075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 1B6IkVKT19464592 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 6 Dec 2021 18:46:31 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 20A8B11C052; Mon, 6 Dec 2021 18:46:31 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id D771A11C050; Mon, 6 Dec 2021 18:46:30 +0000 (GMT) Received: from li-926bd7cc-2dd1-11b2-a85c-f6adc0f5efec.ibm.com (unknown [9.171.69.25]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Mon, 6 Dec 2021 18:46:30 +0000 (GMT) To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: [PATCH v3 7/7] ifcvt: Run second pass if it is possible to omit a temporary. Date: Mon, 6 Dec 2021 19:43:52 +0100 Message-Id: <20211206184352.42264-8-rdapp@linux.ibm.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20211206184352.42264-1-rdapp@linux.ibm.com> References: <20211206184352.42264-1-rdapp@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: XeOsF01lAOQ-B7qVM-F_GDcK6p6MN02n X-Proofpoint-GUID: XeOsF01lAOQ-B7qVM-F_GDcK6p6MN02n X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.790,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2021-12-06_07,2021-12-06_02,2021-12-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=0 adultscore=0 clxscore=1015 mlxlogscore=999 priorityscore=1501 bulkscore=0 mlxscore=0 impostorscore=0 malwarescore=0 lowpriorityscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2110150000 definitions=main-2112060111 X-Spam-Status: No, score=-12.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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: Robin Dapp via Gcc-patches From: Robin Dapp Reply-To: Robin Dapp Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" If one of the to-be-converted SETs requires the original comparison (i.e. in order to generate a min/max insn) but no other insn after it does, we can omit creating temporaries, thus facilitating costing. --- gcc/ifcvt.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index d1e7db1ee27..3be5bb131df 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -3262,6 +3262,11 @@ noce_convert_multiple_sets (struct noce_if_info *if_info) need_cmov_or_rewire (then_bb, &need_no_cmov, &rewired_src); + int last_needs_comparison = -1; + bool second_try = false; + +restart: + FOR_BB_INSNS (then_bb, insn) { /* Skip over non-insns. */ @@ -3305,8 +3310,12 @@ noce_convert_multiple_sets (struct noce_if_info *if_info) Therefore we introduce a temporary every time we are about to overwrite a variable used in the check. Costing of a sequence with these is going to be inaccurate so only use temporaries when - needed. */ - if (reg_overlap_mentioned_p (target, cond)) + needed. + + If performing a second try, we know how many insns require a + temporary. For the last of these, we can omit creating one. */ + if (reg_overlap_mentioned_p (target, cond) + && (!second_try || count < last_needs_comparison)) temp = gen_reg_rtx (GET_MODE (target)); else temp = target; @@ -3389,6 +3398,8 @@ noce_convert_multiple_sets (struct noce_if_info *if_info) { seq = seq1; temp_dest = temp_dest1; + if (!second_try) + last_needs_comparison = count; } else if (seq2 != NULL_RTX) { @@ -3412,6 +3423,24 @@ noce_convert_multiple_sets (struct noce_if_info *if_info) unmodified_insns.safe_push (insn); } + /* If there are insns that overwrite part of the initial + comparison, we can still omit creating temporaries for + the last of them. + As the second try will always create a less expensive, + valid sequence, we do not need to compare and can discard + the first one. */ + if (!second_try && last_needs_comparison >= 0) + { + end_sequence (); + start_sequence (); + count = 0; + targets.truncate (0); + temporaries.truncate (0); + unmodified_insns.truncate (0); + second_try = true; + goto restart; + } + /* We must have seen some sort of insn to insert, otherwise we were given an empty BB to convert, and we can't handle that. */ gcc_assert (!unmodified_insns.is_empty ());