From patchwork Tue Apr 27 01:49:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Leoshkevich X-Patchwork-Id: 1470515 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=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=JBvcwKLT; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (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 4FTl772lcVz9sWW for ; Tue, 27 Apr 2021 11:49:21 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E1D48396C83A; Tue, 27 Apr 2021 01:49:18 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E1D48396C83A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1619488158; bh=apho6byEv1sHsmRy27TFIw9vUG/6kkZnTD4macImlwo=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=JBvcwKLT8Hik0Rm9iLITS/wpP6Vaf2FdUTueFe2A0XVABmj8OyKAQ313lUWqYqlhm bEuo06c7GeVBs8iJMPgXXM7G0TMkFS8dPngmfTG2lu+ao8TUoIgiKFEYLFRGgAEySm PjNvQIQ53RlHxbnN0Hky8tm+pA7vIKAXwgeO0OoM= 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 BC1363857009; Tue, 27 Apr 2021 01:49:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org BC1363857009 Received: from pps.filterd (m0098399.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 13R1ZBF0152121; Mon, 26 Apr 2021 21:49:14 -0400 Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 38676ttdap-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 26 Apr 2021 21:49:14 -0400 Received: from m0098399.ppops.net (m0098399.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.43/8.16.0.43) with SMTP id 13R1h1Vc173535; Mon, 26 Apr 2021 21:49:14 -0400 Received: from ppma06fra.de.ibm.com (48.49.7a9f.ip4.static.sl-reverse.com [159.122.73.72]) by mx0a-001b2d01.pphosted.com with ESMTP id 38676ttd8k-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 26 Apr 2021 21:49:14 -0400 Received: from pps.filterd (ppma06fra.de.ibm.com [127.0.0.1]) by ppma06fra.de.ibm.com (8.16.0.43/8.16.0.43) with SMTP id 13R1ig7k004373; Tue, 27 Apr 2021 01:49:11 GMT Received: from b06avi18626390.portsmouth.uk.ibm.com (b06avi18626390.portsmouth.uk.ibm.com [9.149.26.192]) by ppma06fra.de.ibm.com with ESMTP id 384akh8kee-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 27 Apr 2021 01:49:11 +0000 Received: from d06av24.portsmouth.uk.ibm.com (mk.ibm.com [9.149.105.60]) by b06avi18626390.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 13R1mhPa31129990 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 27 Apr 2021 01:48:43 GMT Received: from d06av24.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6F33042041; Tue, 27 Apr 2021 01:49:07 +0000 (GMT) Received: from d06av24.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 29C1242045; Tue, 27 Apr 2021 01:49:07 +0000 (GMT) Received: from vm.lan (unknown [9.145.157.105]) by d06av24.portsmouth.uk.ibm.com (Postfix) with ESMTP; Tue, 27 Apr 2021 01:49:07 +0000 (GMT) To: Andreas Krebbel Subject: [PATCH] IBM Z: Handle hard registers in s390_md_asm_adjust() Date: Tue, 27 Apr 2021 03:49:04 +0200 Message-Id: <20210427014904.80951-1-iii@linux.ibm.com> X-Mailer: git-send-email 2.29.2 X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: pA7pJFQv-1YcwRGE8VZRIJWGJj4-X_B7 X-Proofpoint-GUID: xNjwT07lbRVqY1kXlV1uJKMzMH7-aBjX X-Proofpoint-UnRewURL: 0 URL was un-rewritten MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391, 18.0.761 definitions=2021-04-26_12:2021-04-26, 2021-04-26 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 suspectscore=0 clxscore=1015 lowpriorityscore=0 adultscore=0 mlxlogscore=999 bulkscore=0 spamscore=0 phishscore=0 impostorscore=0 mlxscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2104060000 definitions=main-2104270007 X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, 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: , X-Patchwork-Original-From: Ilya Leoshkevich via Gcc-patches From: Ilya Leoshkevich Reply-To: Ilya Leoshkevich Cc: Jakub Jelinek , gcc-patches@gcc.gnu.org Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" Bootstrapped and regtested on s390x-redhat-linux. Tested with valgrind on top of 52a5515ed (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100278). Ok for master? gen_fprx2_to_tf() and gen_tf_to_fprx2() cannot handle hard registers, since the subregs they create do not pass validation. Change s390_md_asm_adjust() to manually copy between hard VRs and FPRs instead of using these two functions. gcc/ChangeLog: PR target/100217 * config/s390/s390.c (s390_hard_fp_reg_p): New function. (s390_md_asm_adjust): Handle hard registers. * config/s390/vector.md (*df_to_tf_1): New pattern. gcc/testsuite/ChangeLog: PR target/100217 * gcc.target/s390/vector/long-double-asm-in-out-hard-fp-reg.c: New test. * gcc.target/s390/vector/long-double-asm-inout-hard-fp-reg.c: New test. --- gcc/config/s390/s390.c | 50 +++++++++++++++++-- gcc/config/s390/vector.md | 8 +++ .../long-double-asm-in-out-hard-fp-reg.c | 28 +++++++++++ .../long-double-asm-inout-hard-fp-reg.c | 27 ++++++++++ 4 files changed, 109 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.target/s390/vector/long-double-asm-in-out-hard-fp-reg.c create mode 100644 gcc/testsuite/gcc.target/s390/vector/long-double-asm-inout-hard-fp-reg.c diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index a9c945c5ee9..ed6cea9b1f7 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -16754,6 +16754,23 @@ f_constraint_p (const char *constraint) return seen_f_p && !seen_v_p; } +/* Return TRUE iff X is a hard floating-point (and not a vector) register. */ + +static bool +s390_hard_fp_reg_p (rtx x) +{ + if (!(REG_P (x) && HARD_REGISTER_P (x) && REG_ATTRS (x))) + return false; + + tree decl = REG_EXPR (x); + if (!(HAS_DECL_ASSEMBLER_NAME_P (decl) && DECL_ASSEMBLER_NAME_SET_P (decl))) + return false; + + const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); + + return name[0] == '*' && name[1] == 'f'; +} + /* Implement TARGET_MD_ASM_ADJUST hook in order to fix up "f" constraints when long doubles are stored in vector registers. */ @@ -16787,9 +16804,23 @@ s390_md_asm_adjust (vec &outputs, vec &inputs, gcc_assert (allows_reg); gcc_assert (!is_inout); /* Copy output value from a FPR pair into a vector register. */ - rtx fprx2 = gen_reg_rtx (FPRX2mode); + rtx fprx2; push_to_sequence2 (after_md_seq, after_md_end); - emit_insn (gen_fprx2_to_tf (outputs[i], fprx2)); + if (s390_hard_fp_reg_p (outputs[i])) + { + fprx2 = gen_rtx_REG (FPRX2mode, REGNO (outputs[i])); + /* The first half is already at the correct location, copy only the + * second one. Use gen_rtx_raw_SUBREG() in order to skip subreg + * validation - we need to build (subreg:DF (reg:TF %fN) 8), which + * will otherwise be rejected by s390_can_change_mode_class(). */ + emit_move_insn (gen_rtx_raw_SUBREG (DFmode, outputs[i], 8), + simplify_gen_subreg (DFmode, fprx2, FPRX2mode, 8)); + } + else + { + fprx2 = gen_reg_rtx (FPRX2mode); + emit_insn (gen_fprx2_to_tf (outputs[i], fprx2)); + } after_md_seq = get_insns (); after_md_end = get_last_insn (); end_sequence (); @@ -16813,8 +16844,19 @@ s390_md_asm_adjust (vec &outputs, vec &inputs, continue; gcc_assert (allows_reg); /* Copy input value from a vector register into a FPR pair. */ - rtx fprx2 = gen_reg_rtx (FPRX2mode); - emit_insn (gen_tf_to_fprx2 (fprx2, inputs[i])); + rtx fprx2; + if (s390_hard_fp_reg_p (inputs[i])) + { + fprx2 = gen_rtx_REG (FPRX2mode, REGNO (inputs[i])); + /* Copy only the second half. */ + emit_move_insn (gen_rtx_raw_SUBREG (DFmode, fprx2, 8), + gen_rtx_raw_SUBREG (DFmode, inputs[i], 8)); + } + else + { + fprx2 = gen_reg_rtx (FPRX2mode); + emit_insn (gen_tf_to_fprx2 (fprx2, inputs[i])); + } inputs[i] = fprx2; input_modes[i] = FPRX2mode; } diff --git a/gcc/config/s390/vector.md b/gcc/config/s390/vector.md index c80d582a300..648e00625e1 100644 --- a/gcc/config/s390/vector.md +++ b/gcc/config/s390/vector.md @@ -634,6 +634,14 @@ } [(set_attr "op_type" "VRR,*")]) +(define_insn "*df_to_tf_1" + [(set (subreg:DF (match_operand:TF 0 "nonimmediate_operand" "+v") 8) + (match_operand:DF 1 "general_operand" "f"))] + "TARGET_VXE" + ; M4 == 0 corresponds to %v0[0] = %v0[0]; %v0[1] = %v1[0]; + "vpdi\t%v0,%v0,%v1,0" + [(set_attr "op_type" "VRR")]) + (define_insn "*vec_ti_to_v1ti" [(set (match_operand:V1TI 0 "nonimmediate_operand" "=v,v,R, v, v,v") (vec_duplicate:V1TI (match_operand:TI 1 "general_operand" "v,R,v,j00,jm1,d")))] diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-asm-in-out-hard-fp-reg.c b/gcc/testsuite/gcc.target/s390/vector/long-double-asm-in-out-hard-fp-reg.c new file mode 100644 index 00000000000..b9b23bb9188 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/vector/long-double-asm-in-out-hard-fp-reg.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */ +/* { dg-do run { target { s390_z14_hw } } } */ +#include +#include + +__attribute__ ((noipa)) static long double +sqxbr (long double x) +{ + register long double in asm("f0") = x; + register long double out asm("f1"); + + asm("sqxbr\t%0,%1" : "=f"(out) : "f"(in)); + asm("# %0" : "+f"(out)); + + return out; +} + +/* { dg-final { scan-assembler-times {\n\tvpdi\t%v2,%v0,%v2,5\n} 1 } } */ +/* { dg-final { scan-assembler-times {\n\tvpdi\t%v1,%v1,%v3,0\n} 2 } } */ + +int +main (void) +{ + long double x = 0x1.0000000000001p+0L, + exp = 1.00000000000000011102230246251564788e+0L; + assert (sqxbr (x) == exp); +} diff --git a/gcc/testsuite/gcc.target/s390/vector/long-double-asm-inout-hard-fp-reg.c b/gcc/testsuite/gcc.target/s390/vector/long-double-asm-inout-hard-fp-reg.c new file mode 100644 index 00000000000..130324b0846 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/vector/long-double-asm-inout-hard-fp-reg.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */ +/* { dg-do run { target { s390_z14_hw } } } */ +#include +#include + +__attribute__ ((noipa)) static long double +sqxbr (long double x) +{ + register long double inout asm("f4") = x; + + asm("sqxbr\t%0,%0" : "+f"(inout)); + asm("# %0" : "+f"(inout)); + + return inout; +} + +/* { dg-final { scan-assembler-times {\n\tvpdi\t%v6,%v4,%v6,5\n} 1 } } */ +/* { dg-final { scan-assembler-times {\n\tvpdi\t%v4,%v4,%v6,0\n} 2 } } */ + +int +main (void) +{ + long double x = 0x1.0000000000001p+0L, + exp = 1.00000000000000011102230246251564788e+0L; + assert (sqxbr (x) == exp); +}