From patchwork Thu Apr 23 08:08:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Oliva X-Patchwork-Id: 1275655 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=adacore.com Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49791l0Ss4z9sSM for ; Thu, 23 Apr 2020 18:09:13 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6B6783851C34; Thu, 23 Apr 2020 08:09:11 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from rock.gnat.com (rock.gnat.com [205.232.38.15]) by sourceware.org (Postfix) with ESMTP id 6FF3B3851C06 for ; Thu, 23 Apr 2020 08:09:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 6FF3B3851C06 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=adacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=oliva@adacore.com Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 22474116639; Thu, 23 Apr 2020 04:09:09 -0400 (EDT) X-Virus-Scanned: Debian amavisd-new at gnat.com Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id zFzH1mbzOSF6; Thu, 23 Apr 2020 04:09:09 -0400 (EDT) Received: from free.home (tron.gnat.com [IPv6:2620:20:4000:0:46a8:42ff:fe0e:e294]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by rock.gnat.com (Postfix) with ESMTPS id BE0DF116634; Thu, 23 Apr 2020 04:09:08 -0400 (EDT) Received: from livre.home (livre.home [172.31.160.2]) by free.home (8.15.2/8.15.2) with ESMTPS id 03N88tQ1168568 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 23 Apr 2020 05:08:56 -0300 From: Alexandre Oliva To: gcc-patches@gcc.gnu.org Subject: [rs6000] fix mffsl emulation Organization: Free thinker, does not speak for AdaCore Date: Thu, 23 Apr 2020 05:08:55 -0300 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 X-Spam-Status: No, score=-23.4 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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: , Cc: Segher Boessenkool , David Edelsohn Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" The emulation of mffsl with mffs, used when !TARGET_P9_MISC, is going through the motions, but not storing the result in the given operands[0]; it rather modifies operands[0] without effect. It also creates a DImode pseudo that it doesn't use, a DFmode pseudo that's unnecessary AFAICT, and it's not indented per the GNU Coding Standards. The patch below fixes all of these. I wasn't sure simplify_gen_subreg might possibly emit any code in obscure cases, so I left it in place, and accommodated the possibility that the result of the mode conversion back might need copying to the requested output operand. In my tests, the output was always a REG:DF, so the subreg was trivial and the conversion back got the original REG:DF output back. I'm concerned about several issues in the mffsl testcase. First, I don't see that comparing the values as doubles rather than as long longs is desirable. These are FPSCR bitfields, not FP numbers. I understand mffs et al use double because they output to FP registers, but... The bit patterns might not even be well-formed FP numbers. Another issue with the test is that, if the compare fails, it calls mffsl again to print the value, as if it would yield the same result. But part of the FPSCR that mffsl (emulated with mmfl or not) copies to the output FP register is the FPCC, so the fcmpu used to compare the result of the first mmfsl will modify FPSCR and thus the result of the second mmfsl call. Yet another issue is that the test assumed the mmfs bits not extracted by mffsl are all zero. This appears to be the case, as the bits left out are for sticky exceptions, but there are reserved parts of FPSCR that might turn out to be set in the future, and then the masking in the GCC-emulated version of mffsl would zero out those bits and cause the compare to fail. So I put in masking in the mffs result before the compare, but then, what if mffsl is changed so that it copies additional nonzero bits? Should we mask both mffs and mffsl outputs? Or is it safe to leave those bits alone and assume them to be zero at the entry point of main(), as the test used to do? Regstrapped on powerpc64le-linux-gnu. Ok to install? for gcc/ChangeLog * gcc/config/rs6000/rs6000.md (rs6000_mffsl): Copy result to output operand in emulation. Simplify. for gcc/testsuite/ChangeLog * gcc.target/powerpc/test_mffsl.c: Call mffsl only once. Reinterpret the doubles as long longs for compares. Mask out mffs bits that are not expected from mffsl. --- gcc/config/rs6000/rs6000.md | 26 +++++++++++++------------ gcc/testsuite/gcc.target/powerpc/test_mffsl.c | 12 ++++++++---- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 11ab745..8f1ab55 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -13620,18 +13620,20 @@ if (!TARGET_P9_MISC) { - rtx tmp_di = gen_reg_rtx (DImode); - rtx tmp_df = gen_reg_rtx (DFmode); - - /* The mffs instruction reads the entire FPSCR. Emulate the mffsl - instruction using the mffs instruction and masking off the bits - the mmsl instruciton actually reads. */ - emit_insn (gen_rs6000_mffs (tmp_df)); - tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0); - emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0x70007f0ffLL))); - - operands[0] = simplify_gen_subreg (DFmode, tmp_di, DImode, 0); - DONE; + rtx tmp_df = operands[0]; + rtx tmp_di; + + /* The mffs instruction reads the entire FPSCR. Emulate the mffsl + instruction using the mffs instruction and masking off the bits + the mmsl instruciton actually reads. */ + emit_insn (gen_rs6000_mffs (tmp_df)); + tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0); + emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0x70007f0ffLL))); + + tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0); + if (operands[0] != tmp_df) + emit_move_insn (operands[0], tmp_df); + DONE; } emit_insn (gen_rs6000_mffsl_hw (operands[0])); diff --git a/gcc/testsuite/gcc.target/powerpc/test_mffsl.c b/gcc/testsuite/gcc.target/powerpc/test_mffsl.c index 93a8ec2..a1f73aa 100644 --- a/gcc/testsuite/gcc.target/powerpc/test_mffsl.c +++ b/gcc/testsuite/gcc.target/powerpc/test_mffsl.c @@ -14,17 +14,21 @@ int main () union blah { double d; unsigned long long ll; - } conv_val; + } mffs_val, mffsl_val; /* Test reading the FPSCR register. */ __asm __volatile ("mffs %0" : "=f"(f14)); - conv_val.d = f14; + mffs_val.d = f14; + /* Select the bits obtained by mffsl. */ + mffs_val.ll &= 0x70007f0ffLL; - if (conv_val.d != __builtin_mffsl()) + mffsl_val.d = __builtin_mffsl (); + + if (mffs_val.ll != mffsl_val.ll) { #ifdef DEBUG printf("ERROR, __builtin_mffsl() returned 0x%llx, not the expecected value 0x%llx\n", - __builtin_mffsl(), conv_val.d); + mffsl_val.ll, mffs_val.ll); #else abort(); #endif