From patchwork Wed Dec 2 01:34:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Leoshkevich X-Patchwork-Id: 1409248 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=pass (p=none dis=none) header.from=gcc.gnu.org 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=Us4ZJFNN; dkim-atps=neutral Received: from sourceware.org (unknown [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 4Cm1jN6K10z9ryj for ; Wed, 2 Dec 2020 12:34:31 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2A2B83833000; Wed, 2 Dec 2020 01:34:26 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2A2B83833000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1606872866; bh=LuNyH9nfrk0GspAwSV6AMBPQcKAQm9pa6K4MMspz04A=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=Us4ZJFNNKCKDAYmdGhhPVcE1AYCKRXftDcXnEaa6f2E1dPtZnV9c/7yCjY7UGYfjZ Gna4rDigN3iZhuwnQghiKFDZFfRqL05DWCc3lmcPf5xvul7E/CYqeaTt2Evp8m1JMu c+u2h1PumQuymZmw3caY0cDKMOaLvuKFLNK0v4Kc= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) by sourceware.org (Postfix) with ESMTPS id B998C3857827 for ; Wed, 2 Dec 2020 01:34:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org B998C3857827 Received: from pps.filterd (m0098421.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 0B21W0h9153527 for ; Tue, 1 Dec 2020 20:34:22 -0500 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 355d9dvnfg-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Tue, 01 Dec 2020 20:34:20 -0500 Received: from pps.filterd (ppma03fra.de.ibm.com [127.0.0.1]) by ppma03fra.de.ibm.com (8.16.0.42/8.16.0.42) with SMTP id 0B21WqBn022080 for ; Wed, 2 Dec 2020 01:34:18 GMT Received: from b06cxnps4075.portsmouth.uk.ibm.com (d06relay12.portsmouth.uk.ibm.com [9.149.109.197]) by ppma03fra.de.ibm.com with ESMTP id 353e685fmn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 02 Dec 2020 01:34:18 +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 0B21YFeD5767848 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 2 Dec 2020 01:34:15 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6F07A11C04C; Wed, 2 Dec 2020 01:34:15 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1C1E511C054; Wed, 2 Dec 2020 01:34:15 +0000 (GMT) Received: from localhost.localdomain (unknown [9.145.42.202]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Wed, 2 Dec 2020 01:34:15 +0000 (GMT) To: gcc-patches@gcc.gnu.org Subject: [PATCH] IBM Z: Use llihf and oilf to load large immediates into GPRs Date: Wed, 2 Dec 2020 02:34:12 +0100 Message-Id: <20201202013412.440301-1-iii@linux.ibm.com> X-Mailer: git-send-email 2.25.4 MIME-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.312, 18.0.737 definitions=2020-12-01_12:2020-11-30, 2020-12-01 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 impostorscore=0 lowpriorityscore=0 phishscore=0 mlxlogscore=999 clxscore=1015 mlxscore=0 malwarescore=0 spamscore=0 bulkscore=0 adultscore=0 suspectscore=1 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2009150000 definitions=main-2012020003 X-Spam-Status: No, score=-11.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, 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 Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" Bootstrapped and regtesed on s390x-redhat-linux. There are slight improvements in all SPEC benchmarks, no regressions that could not be "fixed" by adding nops. Ok for master? Currently GCC loads large immediates into GPRs from the literal pool, which is not as efficient as loading two halves with llihf and oilf. gcc/ChangeLog: 2020-11-30 Ilya Leoshkevich * config/s390/s390-protos.h (s390_const_int_pool_entry_p): New function. * config/s390/s390.c (s390_const_int_pool_entry_p): New function. * config/s390/s390.md: Add define_peephole2 that produces llihf and oilf. gcc/testsuite/ChangeLog: 2020-11-30 Ilya Leoshkevich * gcc.target/s390/load-imm64-1.c: New test. * gcc.target/s390/load-imm64-2.c: New test. --- gcc/config/s390/s390-protos.h | 1 + gcc/config/s390/s390.c | 31 ++++++++++++++++++++ gcc/config/s390/s390.md | 22 ++++++++++++++ gcc/testsuite/gcc.target/s390/load-imm64-1.c | 10 +++++++ gcc/testsuite/gcc.target/s390/load-imm64-2.c | 10 +++++++ 5 files changed, 74 insertions(+) create mode 100644 gcc/testsuite/gcc.target/s390/load-imm64-1.c create mode 100644 gcc/testsuite/gcc.target/s390/load-imm64-2.c diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h index ad2f7f77c18..eb10c3f4bbb 100644 --- a/gcc/config/s390/s390-protos.h +++ b/gcc/config/s390/s390-protos.h @@ -135,6 +135,7 @@ extern void s390_split_access_reg (rtx, rtx *, rtx *); extern void print_operand_address (FILE *, rtx); extern void print_operand (FILE *, rtx, int); extern void s390_output_pool_entry (rtx, machine_mode, unsigned int); +extern bool s390_const_int_pool_entry_p (rtx, HOST_WIDE_INT *); extern int s390_label_align (rtx_insn *); extern int s390_agen_dep_p (rtx_insn *, rtx_insn *); extern rtx_insn *s390_load_got (void); diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 02f18366aa1..e3d68d3543b 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -9400,6 +9400,37 @@ s390_output_pool_entry (rtx exp, machine_mode mode, unsigned int align) } } +/* Return true if MEM refers to an integer constant in the literal pool. If + VAL is not nullptr, then also fill it with the constant's value. */ + +bool +s390_const_int_pool_entry_p (rtx mem, HOST_WIDE_INT *val) +{ + /* Try to match the following: + - (mem (unspec [(symbol_ref) (reg)] UNSPEC_LTREF)). + - (mem (symbol_ref)). */ + + if (!MEM_P (mem)) + return false; + + rtx addr = XEXP (mem, 0); + rtx sym; + if (GET_CODE (addr) == UNSPEC && XINT (addr, 1) == UNSPEC_LTREF) + sym = XVECEXP (addr, 0, 0); + else + sym = addr; + + if (GET_CODE (sym) != SYMBOL_REF || !CONSTANT_POOL_ADDRESS_P (sym)) + return false; + + rtx val_rtx = get_pool_constant (sym); + if (!CONST_INT_P (val_rtx)) + return false; + + if (val != nullptr) + *val = INTVAL (val_rtx); + return true; +} /* Return an RTL expression representing the value of the return address for the frame COUNT steps up from the current frame. FRAME is the diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 910415a5974..79e9a75ba2f 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -2116,6 +2116,28 @@ (define_peephole2 [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))] "") +; Split loading of 64-bit constants into GPRs into llihf + oilf - +; counterintuitively, using oilf is faster than iilf. oilf clobbers +; cc, so cc must be dead. +(define_peephole2 + [(set (match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "memory_operand" ""))] + "TARGET_64BIT + && TARGET_EXTIMM + && GENERAL_REG_P (operands[0]) + && s390_const_int_pool_entry_p (operands[1], nullptr) + && peep2_reg_dead_p (1, gen_rtx_REG (CCmode, CC_REGNUM))" + [(set (match_dup 0) (match_dup 2)) + (parallel + [(set (match_dup 0) (ior:DI (match_dup 0) (match_dup 3))) + (clobber (reg:CC CC_REGNUM))])] +{ + HOST_WIDE_INT val; + gcc_assert (s390_const_int_pool_entry_p (operands[1], &val)); + operands[2] = gen_rtx_CONST_INT (DImode, val & 0xFFFFFFFF00000000); + operands[3] = gen_rtx_CONST_INT (DImode, val & 0x00000000FFFFFFFF); +}) + ; ; movsi instruction pattern(s). ; diff --git a/gcc/testsuite/gcc.target/s390/load-imm64-1.c b/gcc/testsuite/gcc.target/s390/load-imm64-1.c new file mode 100644 index 00000000000..db0a89395aa --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/load-imm64-1.c @@ -0,0 +1,10 @@ +/* Test that large 64-bit constants are loaded with llihf + oilf when lgrl is + not available. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -march=z9-109" } */ + +unsigned long magic (void) { return 0x3f08c5392f756cd; } + +/* { dg-final { scan-assembler-times {\n\tllihf\t} 1 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {\n\toilf\t} 1 { target lp64 } } } */ diff --git a/gcc/testsuite/gcc.target/s390/load-imm64-2.c b/gcc/testsuite/gcc.target/s390/load-imm64-2.c new file mode 100644 index 00000000000..43c00cdca3a --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/load-imm64-2.c @@ -0,0 +1,10 @@ +/* Test that large 64-bit constants are loaded with llihf + oilf when lgrl is + available. */ + +/* { dg-do compile } */ +/* { dg-options "-O3 -march=z10" } */ + +unsigned long magic (void) { return 0x3f08c5392f756cd; } + +/* { dg-final { scan-assembler-times {\n\tllihf\t} 1 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {\n\toilf\t} 1 { target lp64 } } } */