From patchwork Tue Feb 20 04:21:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Oliva X-Patchwork-Id: 86013 X-Patchwork-Delegate: jlaw@ventanamicro.com 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 E44E03858D35 for ; Tue, 20 Feb 2024 04:22:04 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-oa1-x35.google.com (mail-oa1-x35.google.com [IPv6:2001:4860:4864:20::35]) by sourceware.org (Postfix) with ESMTPS id 2C8B93858D1E for ; Tue, 20 Feb 2024 04:21:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 2C8B93858D1E Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=adacore.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=adacore.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 2C8B93858D1E Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2001:4860:4864:20::35 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708402900; cv=none; b=g0IpJ3ItR3qRLhZZcDbNQtGgOd19TxFQeIXqm9948+4Br1JigyUTNSl6dgUEft3MCiyWD1ghcIcU0B4QYIe55KkXhRMVPnqW0/j5cler1TcRB3TjJD8gZ1NLtstNtbZfI19CfuDxuLMxF4a+t7DJWtAUIA59rYI6YjaT2r7gYZU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1708402900; c=relaxed/simple; bh=D1MAvqZlwoLALQ578hOj4gMFXn6IUbAZ4EOr0aoBx3g=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=siRHBeFqsOEXfcNn2MljI2J/Y3x6K/Vu1nbyn6gvAuyyb9UUjcSahhScyIdU6HFXbhgjF8VWbWebuvMWcwcGJTs3V2oHbgfTfUgXx7Xj04gJDhuT3cbaFlBT6jQxLbhjKlY4NbFdK9ViHIVZcUw1RRVYZP0vid6Ek0D+YWD3ZPA= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-oa1-x35.google.com with SMTP id 586e51a60fabf-204235d0913so3055463fac.1 for ; Mon, 19 Feb 2024 20:21:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=adacore.com; s=google; t=1708402896; x=1709007696; darn=gcc.gnu.org; h=mime-version:user-agent:message-id:date:organization:subject:cc:to :from:from:to:cc:subject:date:message-id:reply-to; bh=TkpoiLkc6R5Vd4fkVG04UITlOYLejiaq52jbYMJtqbk=; b=QpPMt3JorDEa1+RtpDSUl+ueYhAiO3fLKEUwlQW6k5xAfYoBSF0UFSMTXwq6e+wmlF pHT4zAkvS61DDbHI21DZOgWb7YsSdccfVCY4rjpWFNUu00ow2JHTp8TV8WbworDP1bE7 tquD8udop2HeElk2N4JQ2P0707SKTMGAqMyaLhvLXFuTjNgM7cCl3U52thFFCWLoK3OP YTgSqr/5ZHjJgRayeXWlR+YrvhckIRuFzRddb33JxlldAGdLNsX2kYpAhge+4FtyCGS0 U7o6GA4lUuQOh35zoX87ny8ZdrlMAdS9PJkl77i7cd0l9FW4i+KI+VVuZ7LSK2gx6a6A Xchg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708402896; x=1709007696; h=mime-version:user-agent:message-id:date:organization:subject:cc:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=TkpoiLkc6R5Vd4fkVG04UITlOYLejiaq52jbYMJtqbk=; b=IErDPEmR4g3e2GnM+BL3lXXdu0gT3zl0/joarX/55NQiIFZMdsA6Aqcn6XwjP6o9sV NEdz/8DaaOz8rHC3EZ+LNz7Q//2CACI7GBauGsQF0lAo3dFw6KwpGVKLYcguqWjBD+oQ gVmo82ZX1E+M39kIQm67zeInkSqq1LnQHEJdA/HafW0FjBOGcjn5R0YJsZrJcCrU53Bh sdm8PeGjzWFLaX0s1nmXSSpNPWXt0R1pnuMIQrSrDwKO5y0zyu75FUZfpdAailk/Z7Lm LEfRUCigX4p1Yqs/mo9MtCRAmJJWZfDrc5t0TspkxDXEdyEDGYuIiWsX603zV35fB6FS hfEA== X-Gm-Message-State: AOJu0YwWOyPksJEatQzSF5z31wLglBxP3QcRj5rP3N6lHGkMOzcRC1Dy uUO++HWkx7xB1iRHEnf6D6dzZxyqf46cWd7L0/ZI+8NnPybmIbMkb/o2B42DV0rLuplxgbeEfMW Xhg== X-Google-Smtp-Source: AGHT+IHZtH21ow8vpsvHIpK2LDYkMmRkJ3S6QWbvq3MIvCULEueNxq7nxp7YK92tgvC50FaODSpAPA== X-Received: by 2002:a05:6871:d04b:b0:21e:9b99:53d8 with SMTP id mv11-20020a056871d04b00b0021e9b9953d8mr9152533oac.22.1708402896310; Mon, 19 Feb 2024 20:21:36 -0800 (PST) Received: from free.home ([2804:7f1:218a:c88b:e868:4eaf:8258:c30b]) by smtp.gmail.com with ESMTPSA id c6-20020a6566c6000000b005dc3407850dsm4743101pgw.87.2024.02.19.20.21.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Feb 2024 20:21:35 -0800 (PST) Received: from livre (livre.home [172.31.160.2]) by free.home (8.15.2/8.15.2) with ESMTPS id 41K4LIhi005922 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 20 Feb 2024 01:21:18 -0300 From: Alexandre Oliva To: gcc-patches@gcc.gnu.org Cc: Kito Cheng , Palmer Dabbelt , Andrew Waterman , Jim Wilson , Lehua Ding , Ju-Zhe Zhong Subject: [PATCH] RISC-V: Fix error combine of pred_mov pattern Organization: Free thinker, does not speak for AdaCore Date: Tue, 20 Feb 2024 01:21:18 -0300 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_ASCII_DIVIDERS, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE, WEIRD_QUOTING autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org This backport is the second of two required for the pr111935 testcase, already backported to gcc-13, to pass on riscv64-elf and riscv32-elf. The V_VLS mode iterator, used in the original patch, is not available in gcc-13, and I thought that would be too much to backport (and maybe so are these two patches, WDYT?), so I changed it to V, to match the preexisting gcc-13 pattern. Comments also needed manual adjustment. Regstrapped on x86_64-linux-gnu, along with other backports, and tested manually on riscv64-elf. Ok to install? From: Lehua Ding This patch fix PR110943 which will produce some error code. This is because the error combine of some pred_mov pattern. Consider this code: ``` void foo9 (void *base, void *out, size_t vl) { int64_t scalar = *(int64_t*)(base + 100); vint64m2_t v = __riscv_vmv_v_x_i64m2 (0, 1); *(vint64m2_t*)out = v; } ``` RTL before combine pass: ``` (insn 11 10 12 2 (set (reg/v:RVVM2DI 134 [ v ]) (if_then_else:RVVM2DI (unspec:RVVMF32BI [ (const_vector:RVVMF32BI repeat [ (const_int 1 [0x1]) ]) (const_int 1 [0x1]) (const_int 2 [0x2]) repeated x2 (const_int 0 [0]) (reg:SI 66 vl) (reg:SI 67 vtype) ] UNSPEC_VPREDICATE) (const_vector:RVVM2DI repeat [ (const_int 0 [0]) ]) (unspec:RVVM2DI [ (reg:SI 0 zero) ] UNSPEC_VUNDEF))) "/app/example.c":6:20 1089 {pred_movrvvm2di}) (insn 14 13 0 2 (set (mem:RVVM2DI (reg/v/f:DI 136 [ out ]) [1 MEM[(vint64m2_t *)out_4(D)]+0 S[32, 32] A128]) (reg/v:RVVM2DI 134 [ v ])) "/app/example.c":7:23 717 {*movrvvm2di_whole}) ``` RTL after combine pass: ``` (insn 14 13 0 2 (set (mem:RVVM2DI (reg:DI 138) [1 MEM[(vint64m2_t *)out_4(D)]+0 S[32, 32] A128]) (if_then_else:RVVM2DI (unspec:RVVMF32BI [ (const_vector:RVVMF32BI repeat [ (const_int 1 [0x1]) ]) (const_int 1 [0x1]) (const_int 2 [0x2]) repeated x2 (const_int 0 [0]) (reg:SI 66 vl) (reg:SI 67 vtype) ] UNSPEC_VPREDICATE) (const_vector:RVVM2DI repeat [ (const_int 0 [0]) ]) (unspec:RVVM2DI [ (reg:SI 0 zero) ] UNSPEC_VUNDEF))) "/app/example.c":7:23 1089 {pred_movrvvm2di}) ``` This combine change the semantics of insn 14. I split @pred_mov pattern and restrict the conditon of @pred_mov. PR target/110943 gcc/ChangeLog: * config/riscv/predicates.md (vector_const_int_or_double_0_operand): New predicate. * config/riscv/riscv-vector-builtins.cc (function_expander::function_expander): force_reg mem target operand. * config/riscv/vector.md (@pred_mov): Wrapper. (*pred_mov): Remove imm -> reg pattern. (*pred_broadcast_imm): Add imm -> reg pattern. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/base/pr110943.c: New test. (cherry picked from commit 973eb0deb467c79cc21f265a710a81054cfd3e8c) Dropped from backport: * gcc.target/riscv/rvv/base/zvfhmin-intrinsic.c: Adjust. This backport is a prerequisite for gcc.target/riscv/rvv/base/pr111935.c that was backported from gcc-14 to gcc-13 upstream, presumably without realizing that the test didn't pass in gcc-13. --- gcc/config/riscv/predicates.md | 5 + gcc/config/riscv/riscv-vector-builtins.cc | 9 ++ gcc/config/riscv/vector.md | 98 +++++++++++--------- gcc/testsuite/gcc.target/riscv/rvv/base/pr110943.c | 33 +++++++ 4 files changed, 101 insertions(+), 44 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/base/pr110943.c diff --git a/gcc/config/riscv/predicates.md b/gcc/config/riscv/predicates.md index 1707c80cba256..0600824695ed8 100644 --- a/gcc/config/riscv/predicates.md +++ b/gcc/config/riscv/predicates.md @@ -280,6 +280,11 @@ (define_predicate "vector_const_0_operand" (and (match_code "const_vector") (match_test "satisfies_constraint_Wc0 (op)"))) +(define_predicate "vector_const_int_or_double_0_operand" + (and (match_code "const_vector") + (match_test "satisfies_constraint_vi (op) + || satisfies_constraint_Wc0 (op)"))) + (define_predicate "vector_move_operand" (ior (match_operand 0 "nonimmediate_operand") (and (match_code "const_vector") diff --git a/gcc/config/riscv/riscv-vector-builtins.cc b/gcc/config/riscv/riscv-vector-builtins.cc index 01cea23d3e687..60ad59814cd5d 100644 --- a/gcc/config/riscv/riscv-vector-builtins.cc +++ b/gcc/config/riscv/riscv-vector-builtins.cc @@ -2935,7 +2935,14 @@ function_expander::function_expander (const function_instance &instance, exp (exp_in), target (target_in), opno (0) { if (!function_returns_void_p ()) - create_output_operand (&m_ops[opno++], target, TYPE_MODE (TREE_TYPE (exp))); + { + if (target != NULL_RTX && MEM_P (target)) + /* Since there is no intrinsic where target is a mem operand, it + should be converted to reg if it is a mem operand. */ + target = force_reg (GET_MODE (target), target); + create_output_operand (&m_ops[opno++], target, + TYPE_MODE (TREE_TYPE (exp))); + } } /* Take argument ARGNO from EXP's argument list and convert it into diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md index fb0caab8da360..d84355163408e 100644 --- a/gcc/config/riscv/vector.md +++ b/gcc/config/riscv/vector.md @@ -936,69 +936,61 @@ (define_insn_and_split "@vsetvl_no_side_effects" ;; - 15.1 Vector Mask-Register Logical Instructions ;; ------------------------------------------------------------------------------- -;; vle.v/vse.v/vmv.v.v/vmv.v.x/vmv.v.i/vfmv.v.f. -;; For vle.v/vmv.v.v/vmv.v.x/vmv.v.i/vfmv.v.f, we may need merge and mask operand. +;; vle.v/vse.v/vmv.v.v. +;; For vle.v/vmv.v.v, we may need merge and mask operand. ;; For vse.v, we don't need merge operand, so it should always match "vu". ;; constraint alternative 0 ~ 1 match vle.v. ;; constraint alternative 2 match vse.v. ;; constraint alternative 3 match vmv.v.v. -;; constraint alternative 4 match vmv.v.i. -;; For vmv.v.i, we allow 2 following cases: -;; 1. (const_vector:VNx1QI repeat [ -;; (const_int:QI N)]), -15 <= N < 16. -;; 2. (const_vector:VNx1SF repeat [ -;; (const_double:SF 0.0 [0x0.0p+0])]). - -;; We add "MEM_P (operands[0]) || MEM_P (operands[3]) || CONST_VECTOR_P (operands[1])" here to -;; make sure we don't want CSE to generate the following pattern: -;; (insn 17 8 19 2 (set (reg:VNx1HI 134 [ _1 ]) -;; (if_then_else:VNx1HI (unspec:VNx1BI [ -;; (reg/v:VNx1BI 137 [ mask ]) -;; (reg:DI 151) -;; (const_int 0 [0]) repeated x3 -;; (reg:SI 66 vl) -;; (reg:SI 67 vtype) -;; ] UNSPEC_VPREDICATE) -;; (const_vector:VNx1HI repeat [ -;; (const_int 0 [0]) -;; ]) -;; (reg/v:VNx1HI 140 [ merge ]))) "rvv.c":8:12 608 {pred_movvnx1hi} -;; (expr_list:REG_DEAD (reg:DI 151) -;; (expr_list:REG_DEAD (reg/v:VNx1HI 140 [ merge ]) -;; (expr_list:REG_DEAD (reg/v:VNx1BI 137 [ mask ]) -;; (nil))))) -;; Since both vmv.v.v and vmv.v.i doesn't have mask operand. -(define_insn_and_split "@pred_mov" - [(set (match_operand:V 0 "nonimmediate_operand" "=vr, vr, vd, m, vr, vr, vr, vr") + +;; If operand 3 is a const_vector, then it is left to pred_braordcast patterns. +(define_expand "@pred_mov" + [(set (match_operand:V 0 "nonimmediate_operand") (if_then_else:V (unspec: - [(match_operand: 1 "vector_mask_operand" "vmWc1, Wc1, vm, vmWc1, Wc1, Wc1, Wc1, Wc1") - (match_operand 4 "vector_length_operand" " rK, rK, rK, rK, rK, rK, rK, rK") - (match_operand 5 "const_int_operand" " i, i, i, i, i, i, i, i") - (match_operand 6 "const_int_operand" " i, i, i, i, i, i, i, i") - (match_operand 7 "const_int_operand" " i, i, i, i, i, i, i, i") + [(match_operand: 1 "vector_mask_operand") + (match_operand 4 "vector_length_operand") + (match_operand 5 "const_int_operand") + (match_operand 6 "const_int_operand") + (match_operand 7 "const_int_operand") (reg:SI VL_REGNUM) (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) - (match_operand:V 3 "vector_move_operand" " m, m, m, vr, vr, vr, viWc0, viWc0") - (match_operand:V 2 "vector_merge_operand" " 0, vu, vu, vu, vu, 0, vu, 0")))] - "TARGET_VECTOR && (MEM_P (operands[0]) || MEM_P (operands[3]) - || CONST_VECTOR_P (operands[1]))" + (match_operand:V 3 "vector_move_operand") + (match_operand:V 2 "vector_merge_operand")))] + "TARGET_VECTOR" + {}) + +;; vle.v/vse.v,vmv.v.v +(define_insn_and_split "*pred_mov" + [(set (match_operand:V 0 "nonimmediate_operand" "=vr, vr, vd, m, vr, vr") + (if_then_else:V + (unspec: + [(match_operand: 1 "vector_mask_operand" "vmWc1, Wc1, vm, vmWc1, Wc1, Wc1") + (match_operand 4 "vector_length_operand" " rK, rK, rK, rK, rK, rK") + (match_operand 5 "const_int_operand" " i, i, i, i, i, i") + (match_operand 6 "const_int_operand" " i, i, i, i, i, i") + (match_operand 7 "const_int_operand" " i, i, i, i, i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (match_operand:V 3 "reg_or_mem_operand" " m, m, m, vr, vr, vr") + (match_operand:V 2 "vector_merge_operand" " 0, vu, vu, vu, vu, 0")))] + "(TARGET_VECTOR + && (register_operand (operands[0], mode) + || register_operand (operands[3], mode)))" "@ vle.v\t%0,%3%p1 vle.v\t%0,%3 vle.v\t%0,%3,%1.t vse.v\t%3,%0%p1 vmv.v.v\t%0,%3 - vmv.v.v\t%0,%3 - vmv.v.i\t%0,%v3 - vmv.v.i\t%0,%v3" + vmv.v.v\t%0,%3" "&& register_operand (operands[0], mode) && register_operand (operands[3], mode) && satisfies_constraint_vu (operands[2]) && INTVAL (operands[7]) == riscv_vector::VLMAX" [(set (match_dup 0) (match_dup 3))] "" - [(set_attr "type" "vlde,vlde,vlde,vste,vimov,vimov,vimov,vimov") + [(set_attr "type" "vlde,vlde,vlde,vste,vimov,vimov") (set_attr "mode" "")]) ;; Dedicated pattern for vse.v instruction since we can't reuse pred_mov pattern to include @@ -1367,6 +1359,26 @@ (define_insn "*pred_broadcast_zero" [(set_attr "type" "vimovxv,vimovxv") (set_attr "mode" "")]) +;; Because (vec_duplicate imm) will be converted to (const_vector imm), +;; This pattern is used to handle this case. +(define_insn "*pred_broadcast_imm" + [(set (match_operand:V 0 "register_operand" "=vr, vr") + (if_then_else:V + (unspec: + [(match_operand: 1 "vector_all_trues_mask_operand" " Wc1, Wc1") + (match_operand 4 "vector_length_operand" " rK, rK") + (match_operand 5 "const_int_operand" " i, i") + (match_operand 6 "const_int_operand" " i, i") + (match_operand 7 "const_int_operand" " i, i") + (reg:SI VL_REGNUM) + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) + (match_operand:V 3 "vector_const_int_or_double_0_operand" "viWc0, viWc0") + (match_operand:V 2 "vector_merge_operand" " vu, 0")))] + "TARGET_VECTOR" + "vmv.v.i\t%0,%v3" + [(set_attr "type" "vimov,vimov") + (set_attr "mode" "")]) + ;; ------------------------------------------------------------------------------- ;; ---- Predicated Strided loads/stores ;; ------------------------------------------------------------------------------- diff --git a/gcc/testsuite/gcc.target/riscv/rvv/base/pr110943.c b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110943.c new file mode 100644 index 0000000000000..8a6c00fc94d29 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/pr110943.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=rv64gcv -mabi=lp64d" } */ +/* { dg-final { check-function-bodies "**" "" } } */ + +#include + +/* +** foo9: +** vsetivli\tzero,1,e64,m2,t[au],m[au] +** ... +** vs2r.v\tv[0-9]+,0\([a-x0-9]+\) +** ret +*/ +void foo9 (void *base, void *out, size_t vl) +{ + int64_t scalar = *(int64_t*)(base + 100); + vint64m2_t v = __riscv_vmv_v_x_i64m2 (0, 1); + *(vint64m2_t*)out = v; +} + +/* +** foo10: +** vsetivli\tzero,1,e64,m2,t[au],m[au] +** ... +** vs2r.v\tv[0-9]+,0\([a-x0-9]+\) +** ret +*/ +void foo10 (void *base, void *out, size_t vl) +{ + int64_t scalar = *(int64_t*)(base + 100); + vint64m2_t v = __riscv_vmv_s_x_i64m2 (0, 1); + *(vint64m2_t*)out = v; +}