From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1895) id 141933858C78; Fri, 29 Sep 2023 12:14:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 141933858C78 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1695989694; bh=vECnK1nReqSQ4rDv5py5Fd767oI2dC9FPNCxwaB7Vu8=; h=From:To:Subject:Date:From; b=LfrUB/ant4t4bUA3s6kgq7uBjZen/EGhNjheXsV8naN+z4DfxYy3uqYy972HXYUw9 cveIgeuFph/vbofXj+gyaXNG6uuBGukgDQYg8NQ61GqvDRKUq9P81tmxczOh5usb4S g4TmhAXEP4AQHLzsvCGXHZwIYHiPpP4F9XHfupas= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Wilco Dijkstra To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-7921] AArch64: Fix memmove operand corruption [PR111121] X-Act-Checkin: gcc X-Git-Author: Wilco Dijkstra X-Git-Refname: refs/heads/releases/gcc-13 X-Git-Oldrev: ccebfd86c163a50d08297d366c56dc06fbb5dea7 X-Git-Newrev: c534a9b198caa3807bcc592a3c5bac3f971417f7 Message-Id: <20230929121454.141933858C78@sourceware.org> Date: Fri, 29 Sep 2023 12:14:54 +0000 (GMT) List-Id: https://gcc.gnu.org/g:c534a9b198caa3807bcc592a3c5bac3f971417f7 commit r13-7921-gc534a9b198caa3807bcc592a3c5bac3f971417f7 Author: Wilco Dijkstra Date: Tue Sep 26 16:42:45 2023 +0100 AArch64: Fix memmove operand corruption [PR111121] A MOPS memmove may corrupt registers since there is no copy of the input operands to temporary registers. Fix this by calling aarch64_expand_cpymem_mops. Reviewed-by: Richard Sandiford gcc/ChangeLog/ PR target/111121 * config/aarch64/aarch64.md (aarch64_movmemdi): Add new expander. (movmemdi): Call aarch64_expand_cpymem_mops for correct expansion. * config/aarch64/aarch64.cc (aarch64_expand_cpymem_mops): Add support for memmove. * config/aarch64/aarch64-protos.h (aarch64_expand_cpymem_mops): Add new function. gcc/testsuite/ChangeLog/ PR target/111121 * gcc.target/aarch64/mops_4.c: Add memmove testcases. (cherry picked from commit d8b56c95782aeeee79ec40932ca88d00fd9f2ee2) Diff: --- gcc/config/aarch64/aarch64-protos.h | 1 + gcc/config/aarch64/aarch64.cc | 15 ++++++---- gcc/config/aarch64/aarch64.md | 31 ++++++++++++-------- gcc/testsuite/gcc.target/aarch64/mops_4.c | 48 +++++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 18 deletions(-) diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index e727e207367..32716f6cb15 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -763,6 +763,7 @@ bool aarch64_emit_approx_div (rtx, rtx, rtx); bool aarch64_emit_approx_sqrt (rtx, rtx, bool); tree aarch64_vector_load_decl (tree); void aarch64_expand_call (rtx, rtx, rtx, bool); +bool aarch64_expand_cpymem_mops (rtx *, bool); bool aarch64_expand_cpymem (rtx *); bool aarch64_expand_setmem (rtx *); bool aarch64_float_const_zero_rtx_p (rtx); diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 66c148b3538..02515d4683a 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -24851,10 +24851,11 @@ aarch64_copy_one_block_and_progress_pointers (rtx *src, rtx *dst, *dst = aarch64_progress_pointer (*dst); } -/* Expand a cpymem using the MOPS extension. OPERANDS are taken - from the cpymem pattern. Return true iff we succeeded. */ -static bool -aarch64_expand_cpymem_mops (rtx *operands) +/* Expand a cpymem/movmem using the MOPS extension. OPERANDS are taken + from the cpymem/movmem pattern. IS_MEMMOVE is true if this is a memmove + rather than memcpy. Return true iff we succeeded. */ +bool +aarch64_expand_cpymem_mops (rtx *operands, bool is_memmove = false) { if (!TARGET_MOPS) return false; @@ -24866,8 +24867,10 @@ aarch64_expand_cpymem_mops (rtx *operands) rtx dst_mem = replace_equiv_address (operands[0], dst_addr); rtx src_mem = replace_equiv_address (operands[1], src_addr); rtx sz_reg = copy_to_mode_reg (DImode, operands[2]); - emit_insn (gen_aarch64_cpymemdi (dst_mem, src_mem, sz_reg)); - + if (is_memmove) + emit_insn (gen_aarch64_movmemdi (dst_mem, src_mem, sz_reg)); + else + emit_insn (gen_aarch64_cpymemdi (dst_mem, src_mem, sz_reg)); return true; } diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 21b7f1e3edf..50239d72fc0 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -1667,7 +1667,22 @@ } ) -(define_insn "aarch64_movmemdi" +(define_expand "aarch64_movmemdi" + [(parallel + [(set (match_operand 2) (const_int 0)) + (clobber (match_dup 3)) + (clobber (match_dup 4)) + (clobber (reg:CC CC_REGNUM)) + (set (match_operand 0) + (unspec:BLK [(match_operand 1) (match_dup 2)] UNSPEC_MOVMEM))])] + "TARGET_MOPS" + { + operands[3] = XEXP (operands[0], 0); + operands[4] = XEXP (operands[1], 0); + } +) + +(define_insn "*aarch64_movmemdi" [(parallel [ (set (match_operand:DI 2 "register_operand" "+&r") (const_int 0)) (clobber (match_operand:DI 0 "register_operand" "+&r")) @@ -1700,17 +1715,9 @@ && INTVAL (sz_reg) < aarch64_mops_memmove_size_threshold) FAIL; - rtx addr_dst = XEXP (operands[0], 0); - rtx addr_src = XEXP (operands[1], 0); - - if (!REG_P (sz_reg)) - sz_reg = force_reg (DImode, sz_reg); - if (!REG_P (addr_dst)) - addr_dst = force_reg (DImode, addr_dst); - if (!REG_P (addr_src)) - addr_src = force_reg (DImode, addr_src); - emit_insn (gen_aarch64_movmemdi (addr_dst, addr_src, sz_reg)); - DONE; + if (aarch64_expand_cpymem_mops (operands, true)) + DONE; + FAIL; } ) diff --git a/gcc/testsuite/gcc.target/aarch64/mops_4.c b/gcc/testsuite/gcc.target/aarch64/mops_4.c index 1b87759cb5e..dd796115cb4 100644 --- a/gcc/testsuite/gcc.target/aarch64/mops_4.c +++ b/gcc/testsuite/gcc.target/aarch64/mops_4.c @@ -50,6 +50,54 @@ copy3 (int *x, int *y, long z, long *res) *res = z; } +/* +** move1: +** mov (x[0-9]+), x0 +** cpyp \[\1\]!, \[x1\]!, x2! +** cpym \[\1\]!, \[x1\]!, x2! +** cpye \[\1\]!, \[x1\]!, x2! +** str x0, \[x3\] +** ret +*/ +void +move1 (int *x, int *y, long z, int **res) +{ + __builtin_memmove (x, y, z); + *res = x; +} + +/* +** move2: +** mov (x[0-9]+), x1 +** cpyp \[x0\]!, \[\1\]!, x2! +** cpym \[x0\]!, \[\1\]!, x2! +** cpye \[x0\]!, \[\1\]!, x2! +** str x1, \[x3\] +** ret +*/ +void +move2 (int *x, int *y, long z, int **res) +{ + __builtin_memmove (x, y, z); + *res = y; +} + +/* +** move3: +** mov (x[0-9]+), x2 +** cpyp \[x0\]!, \[x1\]!, \1! +** cpym \[x0\]!, \[x1\]!, \1! +** cpye \[x0\]!, \[x1\]!, \1! +** str x2, \[x3\] +** ret +*/ +void +move3 (int *x, int *y, long z, long *res) +{ + __builtin_memmove (x, y, z); + *res = z; +} + /* ** set1: ** mov (x[0-9]+), x0