From patchwork Thu Feb 17 18:56:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Meissner X-Patchwork-Id: 51190 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 A9004385AC1F for ; Thu, 17 Feb 2022 18:56:39 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A9004385AC1F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1645124199; bh=Oh7QtXBk+uEI0a6HP7Yj6ZBqyFW5BYH9j597Y/mtwqQ=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=CeHs/Hrf4+MF1AwPF6o+trN+5kKfMJU7Hkqnq4XVFFYkVp2UppWHs1VTw7zetma4t oILxTOt5D8JMIu0WrZHLRAZ1lryF89hniVOsaqdMWSnpADVCgE7J+x6Mc0t4vGmuUo RmYV44YbHiqMyO+LlZ0RXgxcyAc4re86I3TAzPuY= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) by sourceware.org (Postfix) with ESMTPS id 0BE7E3858D20 for ; Thu, 17 Feb 2022 18:56:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 0BE7E3858D20 Received: from pps.filterd (m0098413.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 21HIZHDa025251; Thu, 17 Feb 2022 18:56:09 GMT Received: from pps.reinject (localhost [127.0.0.1]) by mx0b-001b2d01.pphosted.com with ESMTP id 3e9hdc6uq8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 17 Feb 2022 18:56:09 +0000 Received: from m0098413.ppops.net (m0098413.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 21HIhUC9009387; Thu, 17 Feb 2022 18:56:09 GMT Received: from ppma02dal.us.ibm.com (a.bd.3ea9.ip4.static.sl-reverse.com [169.62.189.10]) by mx0b-001b2d01.pphosted.com with ESMTP id 3e9hdc6upv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 17 Feb 2022 18:56:08 +0000 Received: from pps.filterd (ppma02dal.us.ibm.com [127.0.0.1]) by ppma02dal.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 21HIrxJc007142; Thu, 17 Feb 2022 18:56:08 GMT Received: from b03cxnp08025.gho.boulder.ibm.com (b03cxnp08025.gho.boulder.ibm.com [9.17.130.17]) by ppma02dal.us.ibm.com with ESMTP id 3e64hdfmge-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 17 Feb 2022 18:56:08 +0000 Received: from b03ledav001.gho.boulder.ibm.com (b03ledav001.gho.boulder.ibm.com [9.17.130.232]) by b03cxnp08025.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 21HIu6SO32309618 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 17 Feb 2022 18:56:06 GMT Received: from b03ledav001.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 9DFCE6E050; Thu, 17 Feb 2022 18:56:06 +0000 (GMT) Received: from b03ledav001.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 116D46E052; Thu, 17 Feb 2022 18:56:06 +0000 (GMT) Received: from toto.the-meissners.org (unknown [9.77.136.59]) by b03ledav001.gho.boulder.ibm.com (Postfix) with ESMTPS; Thu, 17 Feb 2022 18:56:05 +0000 (GMT) Date: Thu, 17 Feb 2022 13:56:04 -0500 To: gcc-patches@gcc.gnu.org, Michael Meissner , Segher Boessenkool , David Edelsohn , Bill Schmidt , Peter Bergner , Will Schmidt Subject: [PATCH] Don't do int cmoves for IEEE comparisons, PR target/104256. Message-ID: Mail-Followup-To: Michael Meissner , gcc-patches@gcc.gnu.org, Segher Boessenkool , David Edelsohn , Bill Schmidt , Peter Bergner , Will Schmidt MIME-Version: 1.0 Content-Disposition: inline X-TM-AS-GCONF: 00 X-Proofpoint-GUID: _wBTDd4bjNtMHait6gkr_IUTwLcq1rxd X-Proofpoint-ORIG-GUID: mjhtkYSeQXsaGFlJWseA4cGYVWXO5J4S X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.816,Hydra:6.0.425,FMLib:17.11.62.513 definitions=2022-02-17_07,2022-02-17_01,2021-12-02_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 clxscore=1015 malwarescore=0 priorityscore=1501 mlxlogscore=999 bulkscore=0 lowpriorityscore=0 spamscore=0 adultscore=0 phishscore=0 mlxscore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2201110000 definitions=main-2202170083 X-Spam-Status: No, score=-10.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, GIT_PATCH_0, KAM_MANYTO, KAM_SHORT, RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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: Michael Meissner via Gcc-patches From: Michael Meissner Reply-To: Michael Meissner Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Don't do int cmoves for IEEE comparisons, PR target/104256. Protect int cmove from raising an assertion if it is trying to do an int conditional move where the test involves floating point comparisons that can't easily be reversed due to NaNs. The code used to generate the condition, and possibly reverse the condition if ISEL could not handle it by rewriting the OP in the comparison rtx. Unfortunately there are some conditions like UNLE that can't easily be reversed due to NaNs. The patch changes the code so that it does the reversal before generating the comparison. If the comparison cannot be reversed, it just returns false, which indicates that we can't do an int conditional move in this case. I have tested this on a little endian power9 system doing a bootstrap. There were no regressions. Can I install this in the trunk? Neither GCC 10 nor GCC 11 seem to generate an assertion faiure, so I don't plan to backport it. 2022-02-17 Michael Meissner gcc/ PR target/104256 * config/rs6000/rs6000.cc (rs6000_emit_int_cmove): Don't do integer conditional moves if the test needs to be reversed and there isn't a direct reverse comparison. gcc/testsuite/ PR target/104256 * gcc.target/powerpc/ppc-fortran/pr104254.f90: New test. --- gcc/config/rs6000/rs6000.cc | 36 ++++++++++--------- .../powerpc/ppc-fortran/pr104254.f90 | 25 +++++++++++++ 2 files changed, 44 insertions(+), 17 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/ppc-fortran/pr104254.f90 diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index f56cf66313a..15d324d13aa 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -16174,18 +16174,35 @@ rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond) { rtx condition_rtx, cr; machine_mode mode = GET_MODE (dest); - enum rtx_code cond_code; rtx (*isel_func) (rtx, rtx, rtx, rtx, rtx); bool signedp; if (mode != SImode && (!TARGET_POWERPC64 || mode != DImode)) return false; + /* Swap the comparison if isel can't handle it directly. Don't generate int + cmoves if we can't swap the condition code due to NaNs. */ + enum rtx_code op_code = GET_CODE (op); + if (op_code != LT && op_code != GT && op_code != LTU && op_code != GTU + && op_code != EQ) + { + if (!COMPARISON_P (op)) + return false; + + enum rtx_code rev_code = reverse_condition (op_code); + if (rev_code == UNKNOWN) + return false; + + std::swap (false_cond, true_cond); + op = gen_rtx_fmt_ee (rev_code, GET_MODE (op), + XEXP (op, 0), + XEXP (op, 1)); + } + /* We still have to do the compare, because isel doesn't do a compare, it just looks at the CRx bits set by a previous compare instruction. */ condition_rtx = rs6000_generate_compare (op, mode); - cond_code = GET_CODE (condition_rtx); cr = XEXP (condition_rtx, 0); signedp = GET_MODE (cr) == CCmode; @@ -16193,21 +16210,6 @@ rs6000_emit_int_cmove (rtx dest, rtx op, rtx true_cond, rtx false_cond) ? (signedp ? gen_isel_signed_si : gen_isel_unsigned_si) : (signedp ? gen_isel_signed_di : gen_isel_unsigned_di)); - switch (cond_code) - { - case LT: case GT: case LTU: case GTU: case EQ: - /* isel handles these directly. */ - break; - - default: - /* We need to swap the sense of the comparison. */ - { - std::swap (false_cond, true_cond); - PUT_CODE (condition_rtx, reverse_condition (cond_code)); - } - break; - } - false_cond = force_reg (mode, false_cond); if (true_cond != const0_rtx) true_cond = force_reg (mode, true_cond); diff --git a/gcc/testsuite/gcc.target/powerpc/ppc-fortran/pr104254.f90 b/gcc/testsuite/gcc.target/powerpc/ppc-fortran/pr104254.f90 new file mode 100644 index 00000000000..d1bfab23482 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/ppc-fortran/pr104254.f90 @@ -0,0 +1,25 @@ +! { dg-do compile } +! { dg-require-effective-target powerpc_p9vector_ok } +! { dg-options "-mdejagnu-cpu=power9 -O1 -fnon-call-exceptions" } + +! PR target/104254. GCC would raise an assertion error if this program was +! compiled with -O1 and -fnon-call-exceptions on a power9 or higher. The issue +! occurs because at this optimization level, the compiler is trying to make +! a conditional move to store integers using a 32-bit floating point compare. +! It wants to use UNLE, which is not supported for integer modes. + + real :: a(2), nan + real, allocatable :: c(:) + integer :: ia(1) + + nan = 0.0 + nan = 0.0/nan + + a(:) = nan + ia = maxloc (a) + if (ia(1).ne.1) STOP 1 + + allocate (c(1)) + c(:) = nan + deallocate (c) +end