]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
RISC-V: Allow by-pieces to do overlapping accesses in block_move_straight
authorChristoph Müllner <christoph.muellner@vrull.eu>
Mon, 29 Apr 2024 00:53:20 +0000 (02:53 +0200)
committerChristoph Müllner <christoph.muellner@vrull.eu>
Wed, 15 May 2024 11:01:45 +0000 (13:01 +0200)
The current implementation of riscv_block_move_straight() emits a couple
of loads/stores with with maximum width (e.g. 8-byte for RV64).
The remainder is handed over to move_by_pieces().
The by-pieces framework utilizes target hooks to decide about the emitted
instructions (e.g. unaligned accesses or overlapping accesses).

Since the current implementation will always request less than XLEN bytes
to be handled by the by-pieces infrastructure, it is impossible that
overlapping memory accesses can ever be emitted (the by-pieces code does
not know of any previous instructions that were emitted by the backend).

This patch changes the implementation of riscv_block_move_straight()
such, that it utilizes the by-pieces framework if the remaining data
is less than 2*XLEN bytes, which is sufficient to enable overlapping
memory accesses (if the requirements for them are given).

The changes in the expansion can be seen in the adjustments of the
cpymem-NN-ooo test cases. The changes in the cpymem-NN tests are
caused by the different instruction ordering of the code emitted
by the by-pieces infrastructure, which emits alternating load/store
sequences.

gcc/ChangeLog:

* config/riscv/riscv-string.cc (riscv_block_move_straight):
Hand over up to 2xXLEN bytes to move_by_pieces().

gcc/testsuite/ChangeLog:

* gcc.target/riscv/cpymem-32-ooo.c: Adjustments for overlapping
access.
* gcc.target/riscv/cpymem-32.c: Adjustments for code emitted by
by-pieces.
* gcc.target/riscv/cpymem-64-ooo.c: Adjustments for overlapping
access.
* gcc.target/riscv/cpymem-64.c: Adjustments for code emitted by
by-pieces.

Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
gcc/config/riscv/riscv-string.cc
gcc/testsuite/gcc.target/riscv/cpymem-32-ooo.c
gcc/testsuite/gcc.target/riscv/cpymem-32.c
gcc/testsuite/gcc.target/riscv/cpymem-64-ooo.c
gcc/testsuite/gcc.target/riscv/cpymem-64.c

index b6cd7032356343dbbffde45f13856a3b266d14ee..96394844bbb697b70ff4dbf0bcacee64c5263577 100644 (file)
@@ -637,18 +637,18 @@ riscv_block_move_straight (rtx dest, rtx src, unsigned HOST_WIDE_INT length,
   delta = bits / BITS_PER_UNIT;
 
   /* Allocate a buffer for the temporary registers.  */
-  regs = XALLOCAVEC (rtx, length / delta);
+  regs = XALLOCAVEC (rtx, length / delta - 1);
 
   /* Load as many BITS-sized chunks as possible.  Use a normal load if
      the source has enough alignment, otherwise use left/right pairs.  */
-  for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++)
+  for (offset = 0, i = 0; offset + 2 * delta <= length; offset += delta, i++)
     {
       regs[i] = gen_reg_rtx (mode);
       riscv_emit_move (regs[i], adjust_address (src, mode, offset));
     }
 
   /* Copy the chunks to the destination.  */
-  for (offset = 0, i = 0; offset + delta <= length; offset += delta, i++)
+  for (offset = 0, i = 0; offset + 2 * delta <= length; offset += delta, i++)
     riscv_emit_move (adjust_address (dest, mode, offset), regs[i]);
 
   /* Mop up any left-over bytes.  */
index 947d58c30fa3bca537e6a1966868db4c3f1ed668..2a48567353a68cb109df342bc4e3c6c155a32188 100644 (file)
@@ -91,8 +91,8 @@ COPY_ALIGNED_N(11)
 **    ...
 **    sw\t[at][0-9],0\([at][0-9]\)
 **    ...
-**    lbu\t[at][0-9],14\([at][0-9]\)
-**    sb\t[at][0-9],14\([at][0-9]\)
+**    lw\t[at][0-9],11\([at][0-9]\)
+**    sw\t[at][0-9],11\([at][0-9]\)
 **    ...
 */
 COPY_N(15)
@@ -104,8 +104,8 @@ COPY_N(15)
 **    ...
 **    sw\t[at][0-9],0\([at][0-9]\)
 **    ...
-**    lbu\t[at][0-9],14\([at][0-9]\)
-**    sb\t[at][0-9],14\([at][0-9]\)
+**    lw\t[at][0-9],11\([at][0-9]\)
+**    sw\t[at][0-9],11\([at][0-9]\)
 **    ...
 */
 COPY_ALIGNED_N(15)
@@ -117,8 +117,8 @@ COPY_ALIGNED_N(15)
 **    ...
 **    sw\t[at][0-9],20\([at][0-9]\)
 **    ...
-**    lbu\t[at][0-9],26\([at][0-9]\)
-**    sb\t[at][0-9],26\([at][0-9]\)
+**    lw\t[at][0-9],23\([at][0-9]\)
+**    sw\t[at][0-9],23\([at][0-9]\)
 **    ...
 */
 COPY_N(27)
@@ -130,8 +130,8 @@ COPY_N(27)
 **    ...
 **    sw\t[at][0-9],20\([at][0-9]\)
 **    ...
-**    lbu\t[at][0-9],26\([at][0-9]\)
-**    sb\t[at][0-9],26\([at][0-9]\)
+**    lw\t[at][0-9],23\([at][0-9]\)
+**    sw\t[at][0-9],23\([at][0-9]\)
 **    ...
 */
 COPY_ALIGNED_N(27)
index 44ba14a1d51fc26d06121acbb50f2f020c1851ab..2030a39ca97079a477fe84eb08727e04af1e3931 100644 (file)
@@ -24,10 +24,10 @@ void copy_aligned_##N (void *to, void *from)                \
 **    ...
 **    lbu\t[at][0-9],0\([at][0-9]\)
 **    ...
-**    lbu\t[at][0-9],6\([at][0-9]\)
-**    ...
 **    sb\t[at][0-9],0\([at][0-9]\)
 **    ...
+**    lbu\t[at][0-9],6\([at][0-9]\)
+**    ...
 **    sb\t[at][0-9],6\([at][0-9]\)
 **    ...
 */
@@ -50,10 +50,9 @@ COPY_ALIGNED_N(7)
 **    ...
 **    lbu\t[at][0-9],0\([at][0-9]\)
 **    ...
-**    lbu\t[at][0-9],7\([at][0-9]\)
-**    ...
 **    sb\t[at][0-9],0\([at][0-9]\)
 **    ...
+**    lbu\t[at][0-9],7\([at][0-9]\)
 **    sb\t[at][0-9],7\([at][0-9]\)
 **    ...
 */
@@ -73,10 +72,9 @@ COPY_ALIGNED_N(8)
 **    ...
 **    lbu\t[at][0-9],0\([at][0-9]\)
 **    ...
-**    lbu\t[at][0-9],10\([at][0-9]\)
-**    ...
 **    sb\t[at][0-9],0\([at][0-9]\)
 **    ...
+**    lbu\t[at][0-9],10\([at][0-9]\)
 **    sb\t[at][0-9],10\([at][0-9]\)
 **    ...
 */
index 108748690cd3398adbbed8e1a2f639e2cedef22a..147324093cb15171c22e023f98ac29e0c5538038 100644 (file)
@@ -110,8 +110,8 @@ COPY_ALIGNED_N(15)
 **    ...
 **    sd\t[at][0-9],16\([at][0-9]\)
 **    ...
-**    lbu\t[at][0-9],26\([at][0-9]\)
-**    sb\t[at][0-9],26\([at][0-9]\)
+**    lw\t[at][0-9],23\([at][0-9]\)
+**    sw\t[at][0-9],23\([at][0-9]\)
 **    ...
 */
 COPY_N(27)
@@ -123,8 +123,8 @@ COPY_N(27)
 **    ...
 **    sd\t[at][0-9],16\([at][0-9]\)
 **    ...
-**    lbu\t[at][0-9],26\([at][0-9]\)
-**    sb\t[at][0-9],26\([at][0-9]\)
+**    lw\t[at][0-9],23\([at][0-9]\)
+**    sw\t[at][0-9],23\([at][0-9]\)
 **    ...
 */
 COPY_ALIGNED_N(27)
index bdfaca0d46a8b441a9b7839e427caf1754f60c66..37b8ef0e0200b142b77b5b421cf9890672c233d2 100644 (file)
@@ -24,10 +24,9 @@ void copy_aligned_##N (void *to, void *from)         \
 **    ...
 **    lbu\t[at][0-9],0\([at][0-9]\)
 **    ...
-**    lbu\t[at][0-9],6\([at][0-9]\)
-**    ...
 **    sb\t[at][0-9],0\([at][0-9]\)
 **    ...
+**    lbu\t[at][0-9],6\([at][0-9]\)
 **    sb\t[at][0-9],6\([at][0-9]\)
 **    ...
 */
@@ -50,10 +49,9 @@ COPY_ALIGNED_N(7)
 **    ...
 **    lbu\t[at][0-9],0\([at][0-9]\)
 **    ...
-**    lbu\t[at][0-9],7\([at][0-9]\)
-**    ...
 **    sb\t[at][0-9],0\([at][0-9]\)
 **    ...
+**    lbu\t[at][0-9],7\([at][0-9]\)
 **    sb\t[at][0-9],7\([at][0-9]\)
 **    ...
 */
@@ -73,10 +71,9 @@ COPY_ALIGNED_N(8)
 **    ...
 **    lbu\t[at][0-9],0\([at][0-9]\)
 **    ...
-**    lbu\t[at][0-9],10\([at][0-9]\)
-**    ...
 **    sb\t[at][0-9],0\([at][0-9]\)
 **    ...
+**    lbu\t[at][0-9],10\([at][0-9]\)
 **    sb\t[at][0-9],10\([at][0-9]\)
 **    ...
 */