]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
x86: Correct last_4x_vec_label in ix86_expand_movmem
authorH.J. Lu <hjl.tools@gmail.com>
Fri, 1 May 2026 01:13:21 +0000 (09:13 +0800)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 1 May 2026 10:14:07 +0000 (18:14 +0800)
commit b41f96465190751561f6909e858604ceab00595b
Author: H.J. Lu <hjl.tools@gmail.com>

    x86-64: Inline memmove with overlapping unaligned loads and stores

has

      rtx_code_label *last_4x_vec_label = nullptr;
      if (min_size == 0 || min_size < 4 * move_max)
        last_4x_vec_label = gen_label_rtx ();

      /* Jump to LAST_4X_VEC_LABEL if size < 4 * MOVE_MAX.  */
      if (last_4x_vec_label)
        emit_cmp_and_jump_insns (count_exp, GEN_INT (4 * move_max), LTU,
                                 nullptr, count_mode, 1,
                                 last_4x_vec_label);

...

      if (last_4x_vec_label)
        {
          /* Size > 2 * MOVE_MAX and size <= 4 * MOVE_MAX.  */
          emit_label (last_4x_vec_label);

The last_4x_vec_label block covers min_size <= 4 * MOVE_MAX, not
min_size < 4 * MOVE_MAX.  When MOVE_MAX == 16 bytes and min_size == 64,
the last_4x_vec_label isn't generated.  Change min_size < 4 * move_max
to min_size <= 4 * move_max to correct the last_4x_vec_label condition.

Tested on Linux/x86-64.

gcc/

PR target/125117
* config/i386/i386-expand.cc (ix86_expand_movmem): Generate
last_4x_vec_label when min_size <= 4 * MOVE_MAX.

gcc/testsuite/

PR target/125117
* gcc.dg/pr125117.c: New test.
* gfortran.dg/pr125117.f90: Likewise.
* gcc.target/i386/builtin-memmove-10.c: Updated.
* gcc.target/i386/builtin-memmove-15.c: Likewise.
* gcc.target/i386/builtin-memmove-2a.c: Likewise.
* gcc.target/i386/builtin-memmove-2b.c: Likewise.
* gcc.target/i386/builtin-memmove-2c.c: Likewise.
* gcc.target/i386/builtin-memmove-2d.c: Likewise.
* gcc.target/i386/builtin-memmove-3a.c: Likewise.
* gcc.target/i386/builtin-memmove-3b.c: Likewise.
* gcc.target/i386/builtin-memmove-3c.c: Likewise.
* gcc.target/i386/builtin-memmove-4a.c: Likewise.
* gcc.target/i386/builtin-memmove-4b.c: Likewise.
* gcc.target/i386/builtin-memmove-4c.c: Likewise.
* gcc.target/i386/builtin-memmove-5b.c: Likewise.
* gcc.target/i386/builtin-memmove-5c.c: Likewise.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
17 files changed:
gcc/config/i386/i386-expand.cc
gcc/testsuite/gcc.dg/pr125117.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/builtin-memmove-10.c
gcc/testsuite/gcc.target/i386/builtin-memmove-15.c
gcc/testsuite/gcc.target/i386/builtin-memmove-2a.c
gcc/testsuite/gcc.target/i386/builtin-memmove-2b.c
gcc/testsuite/gcc.target/i386/builtin-memmove-2c.c
gcc/testsuite/gcc.target/i386/builtin-memmove-2d.c
gcc/testsuite/gcc.target/i386/builtin-memmove-3a.c
gcc/testsuite/gcc.target/i386/builtin-memmove-3b.c
gcc/testsuite/gcc.target/i386/builtin-memmove-3c.c
gcc/testsuite/gcc.target/i386/builtin-memmove-4a.c
gcc/testsuite/gcc.target/i386/builtin-memmove-4b.c
gcc/testsuite/gcc.target/i386/builtin-memmove-4c.c
gcc/testsuite/gcc.target/i386/builtin-memmove-5b.c
gcc/testsuite/gcc.target/i386/builtin-memmove-5c.c
gcc/testsuite/gfortran.dg/pr125117.f90 [new file with mode: 0644]

index 366ad513da961e986adfb06e415b6da21a93c5ea..df44a4eb99dae54bacc2b40e99c47cdb17d7d0e9 100644 (file)
@@ -10585,12 +10585,12 @@ ix86_expand_movmem (rtx operands[])
                                 more_8x_vec_label);
 
       rtx_code_label *last_4x_vec_label = nullptr;
-      if (min_size == 0 || min_size < 4 * move_max)
+      if (min_size == 0 || min_size <= 4 * move_max)
        last_4x_vec_label = gen_label_rtx ();
 
-      /* Jump to LAST_4X_VEC_LABEL if size < 4 * MOVE_MAX.  */
+      /* Jump to LAST_4X_VEC_LABEL if size <= 4 * MOVE_MAX.  */
       if (last_4x_vec_label)
-       emit_cmp_and_jump_insns (count_exp, GEN_INT (4 * move_max), LTU,
+       emit_cmp_and_jump_insns (count_exp, GEN_INT (4 * move_max), LEU,
                                 nullptr, count_mode, 1,
                                 last_4x_vec_label);
 
diff --git a/gcc/testsuite/gcc.dg/pr125117.c b/gcc/testsuite/gcc.dg/pr125117.c
new file mode 100644 (file)
index 0000000..6535484
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+/* { dg-options "-O0" } */
+
+#include <string.h>
+#include <stdlib.h>
+
+#define OFFSET 32
+
+char buffer[128];
+char expected[64];
+
+void
+foo (char *dest, char *src, size_t n)
+{
+  if (n == 64)
+    __builtin_memmove (dest, src, n);
+}
+
+int
+main ()
+{
+  memset (buffer, -2, sizeof (buffer));
+  memset (buffer + OFFSET, -1, sizeof (buffer) - OFFSET);
+  memset (expected, -2, sizeof (expected));
+  memset (expected + OFFSET / 2, -1, OFFSET + OFFSET / 2);
+  foo (buffer, buffer + OFFSET / 2, 64);
+  if (memcmp (expected, buffer, 64) != 0)
+    abort ();
+
+  return 0;
+}
index 4f183747e702771b21687313f40911dac5a1e8e6..76afef9d2954cf2fa94f3a794c2e441fb5ce38c8 100644 (file)
@@ -9,25 +9,25 @@
 **.LFB0:
 **     .cfi_startproc
 **     cmpq    \$63, %rdx
-**     ja      .L12
+**     ja      .L13
 **.L1:
 **     ret
 **     .p2align 4,,10
 **     .p2align 3
-**.L12:
+**.L13:
 **     movq    %rdi, %rcx
 **     movq    %rsi, %rax
 **     cmpq    \$128, %rdx
-**     jbe     .L13
+**     jbe     .L14
 **     movq    %rdx, %rsi
 **     cmpq    %rdi, %rax
-**     jb      .L6
+**     jb      .L7
 **     je      .L1
 **     movdqu  -16\(%rax,%rdx\), %xmm7
 **     movdqu  -32\(%rax,%rdx\), %xmm6
 **     movdqu  -48\(%rax,%rdx\), %xmm5
 **     movdqu  -64\(%rax,%rdx\), %xmm4
-**.L7:
+**.L8:
 **     movdqu  \(%rax\), %xmm3
 **     subq    \$64, %rsi
 **     addq    \$64, %rcx
@@ -40,7 +40,7 @@
 **     movups  %xmm1, -32\(%rcx\)
 **     movups  %xmm0, -16\(%rcx\)
 **     cmpq    \$64, %rsi
-**     ja      .L7
+**     ja      .L8
 **     movups  %xmm7, -16\(%rdi,%rdx\)
 **     movups  %xmm6, -32\(%rdi,%rdx\)
 **     movups  %xmm5, -48\(%rdi,%rdx\)
@@ -48,7 +48,9 @@
 **     ret
 **     .p2align 4,,10
 **     .p2align 3
-**.L13:
+**.L14:
+**     cmpq    \$64, %rdx
+**     jbe     .L6
 **     movdqu  \(%rsi\), %xmm7
 **     movdqu  16\(%rsi\), %xmm6
 **     movdqu  32\(%rsi\), %xmm5
 **     .p2align 4,,10
 **     .p2align 3
 **.L6:
+**     movdqu  \(%rsi\), %xmm3
+**     movdqu  16\(%rsi\), %xmm2
+**     movdqu  -16\(%rsi,%rdx\), %xmm1
+**     movdqu  -32\(%rsi,%rdx\), %xmm0
+**     movups  %xmm3, \(%rdi\)
+**     movups  %xmm2, 16\(%rdi\)
+**     movups  %xmm1, -16\(%rdi,%rdx\)
+**     movups  %xmm0, -32\(%rdi,%rdx\)
+**     ret
+**     .p2align 4,,10
+**     .p2align 3
+**.L7:
 **     movdqu  \(%rax\), %xmm3
 **     movdqu  16\(%rax\), %xmm2
 **     leaq    \(%rdi,%rdx\), %rcx
 **     movdqu  32\(%rax\), %xmm1
 **     movdqu  48\(%rax\), %xmm0
 **     addq    %rdx, %rax
-**.L8:
+**.L9:
 **     movdqu  -16\(%rax\), %xmm7
 **     movdqu  -32\(%rax\), %xmm6
 **     subq    \$64, %rsi
 **     movups  %xmm5, 16\(%rcx\)
 **     movups  %xmm4, \(%rcx\)
 **     cmpq    \$64, %rsi
-**     ja      .L8
+**     ja      .L9
 **     movups  %xmm3, \(%rdi\)
 **     movups  %xmm2, 16\(%rdi\)
 **     movups  %xmm1, 32\(%rdi\)
index 5fb833bc7e8ede5d68fdd4df40f0276632e34a5d..339c07f9d701ce6a233a1a0f94a935879f16d148 100644 (file)
@@ -42,7 +42,7 @@
 **     .p2align 3
 **.L5:
 **     cmpl    \$64, %edx
-**     jnb     .L14
+**     j     .L14
 **     movl    %edx, %edx
 **     movdqu  \(%rsi\), %xmm3
 **     movdqu  16\(%rsi\), %xmm2
index 903a31cfd343d51f582d85a9a5367864602c54bc..b77cadfa063edc0dac441abe6c765edb51baf8e4 100644 (file)
@@ -76,7 +76,7 @@
 **     .p2align 3
 **.L18:
 **     cmpq    \$64, %rdx
-**     jb      .L10
+**     jbe     .L10
 **     movdqu  \(%rsi\), %xmm7
 **     movdqu  16\(%rsi\), %xmm6
 **     movdqu  32\(%rsi\), %xmm5
index ac676d078673138d1bb6a0fd6cea2c37b74fc951..9076a0a9ff3da5d9c633758c1de1d67c67a5bb5f 100644 (file)
@@ -80,7 +80,7 @@
 **     .p2align 3
 **.L19:
 **     cmpq    \$128, %rdx
-**     jb      .L11
+**     jbe     .L11
 **     vmovdqu \(%rsi\), %ymm7
 **     vmovdqu 32\(%rsi\), %ymm6
 **     vmovdqu 64\(%rsi\), %ymm5
index 656986b458ebeccaca8f9f818f086ff74c4447a2..946173a6f7890718a3796d683c748c22ca3ed4b2 100644 (file)
@@ -83,7 +83,7 @@
 **     .p2align 3
 **.L20:
 **     cmpq    \$256, %rdx
-**     jb      .L12
+**     jbe     .L12
 **     vmovdqu64       \(%rsi\), %zmm7
 **     vmovdqu64       64\(%rsi\), %zmm6
 **     vmovdqu64       -64\(%rsi,%rdx\), %zmm3
index 324de74519ea529f522f7cc8f0459e9564c7c769..c7c0543b793cbacd8fdebdf19b82c75355597a65 100644 (file)
@@ -94,7 +94,7 @@
 **.L20:
 **     .cfi_def_cfa_offset 40
 **     cmpq    \$32, %rdx
-**     jb      .L9
+**     jbe     .L9
 **     movq    %rbx, \(%rsp\)
 **     movq    %r14, 16\(%rsp\)
 **     .cfi_offset 3, -40
index cddfd49615b3810817dc2a5e9032c0e817aad829..23ab0fa9f9823f0740603ea72b973b7606b653d9 100644 (file)
@@ -22,7 +22,7 @@
 **     cmpq    \$128, %rdx
 **     ja      .L5
 **     cmpq    \$64, %rdx
-**     jnb     .L15
+**     j     .L15
 **     movdqu  \(%rsi\), %xmm3
 **     movdqu  16\(%rsi\), %xmm2
 **     movdqu  -16\(%rsi,%rdx\), %xmm1
index eda5e749c54bb95ac5c6722ffc0a5d0da8870cac..d45adbcdf4818beee179e177e5f6f1afcf1f5883 100644 (file)
@@ -72,7 +72,7 @@
 **     .p2align 3
 **.L17:
 **     cmpq    \$128, %rdx
-**     jb      .L8
+**     jbe     .L8
 **     vmovdqu \(%rsi\), %ymm7
 **     vmovdqu 32\(%rsi\), %ymm6
 **     vmovdqu 64\(%rsi\), %ymm5
index 50fac7e64d1a8cac07dedb711b04e504b2362a30..4b2f27fefa0806206ebe27018f32f185411b5737 100644 (file)
@@ -83,7 +83,7 @@
 **     .p2align 3
 **.L20:
 **     cmpq    \$256, %rdx
-**     jb      .L9
+**     jbe     .L9
 **     vmovdqu64       \(%rsi\), %zmm7
 **     vmovdqu64       64\(%rsi\), %zmm6
 **     vmovdqu64       -64\(%rsi,%rdx\), %zmm3
index 49b84477482b31f03d49333de1cc5df758df4c14..82c2367a1c3d390cab6acd70d6d3a6996356e2a4 100644 (file)
@@ -50,7 +50,7 @@
 **     .p2align 3
 **.L14:
 **     cmpq    \$64, %rdx
-**     jb      .L6
+**     jbe     .L6
 **     movdqu  \(%rsi\), %xmm7
 **     movdqu  16\(%rsi\), %xmm6
 **     movdqu  32\(%rsi\), %xmm5
index f948d17a08052b6150faa4d620da6b175fa7bedf..4004f0d184562cce5fe23f30de549d9abe1f62ee 100644 (file)
@@ -22,7 +22,7 @@
 **     cmpq    \$256, %rdx
 **     ja      .L5
 **     cmpq    \$128, %rdx
-**     jnb     .L16
+**     j     .L16
 **     vmovdqu \(%rsi\), %ymm3
 **     vmovdqu 32\(%rsi\), %ymm2
 **     vmovdqu -32\(%rsi,%rdx\), %ymm1
index 5cf2520d21407d124c5fbbd03afe85d268fd45bd..1319fac0d50f0177e9be3992d5c5a0da5b10fe8e 100644 (file)
@@ -73,7 +73,7 @@
 **     .p2align 3
 **.L17:
 **     cmpq    \$256, %rdx
-**     jb      .L8
+**     jbe     .L8
 **     vmovdqu64       \(%rsi\), %zmm7
 **     vmovdqu64       64\(%rsi\), %zmm6
 **     vmovdqu64       -64\(%rsi,%rdx\), %zmm3
index d42da7f2c80959ee09708297919e21dcf27f5d23..cba000bd282aea6dc5a3e818ee1e868d779e1a60 100644 (file)
@@ -51,7 +51,7 @@
 **     .p2align 3
 **.L15:
 **     cmpq    \$128, %rdx
-**     jb      .L6
+**     jbe     .L6
 **     vmovdqu \(%rsi\), %ymm7
 **     vmovdqu 32\(%rsi\), %ymm6
 **     vmovdqu 64\(%rsi\), %ymm5
index 8eac584029f6cf4a80ddfdadc20074c3120c8997..07f1e05e4f2774fb4f91ce224352e70db626d109 100644 (file)
@@ -22,7 +22,7 @@
 **     cmpq    \$512, %rdx
 **     ja      .L5
 **     cmpq    \$256, %rdx
-**     jnb     .L16
+**     j     .L16
 **     vmovdqu64       \(%rsi\), %zmm3
 **     vmovdqu64       64\(%rsi\), %zmm2
 **     vmovdqu64       -64\(%rsi,%rdx\), %zmm1
diff --git a/gcc/testsuite/gfortran.dg/pr125117.f90 b/gcc/testsuite/gfortran.dg/pr125117.f90
new file mode 100644 (file)
index 0000000..a03250d
--- /dev/null
@@ -0,0 +1,23 @@
+! { dg-do run }
+! { dg-options "-O0" }
+! PR fortran/125117
+
+program test
+  implicit none
+  character(len=64) :: fixed
+  character(:), allocatable :: got
+  fixed = 'hello world'
+  got = getName(fixed)
+  if (trim(got) == 'hello world') then
+    print *, 'PASS'
+  else
+    print *, 'FAIL: got=[', trim(got), ']'
+    call abort()
+  end if
+contains
+  function getName(fixed) result(name)
+    character(len=64), intent(in) :: fixed
+    character(:), allocatable :: name
+    name = fixed
+  end function
+end program