https://gcc.gnu.org/g:8add706704470554130f04b63e6ea440a171b747

commit r17-2480-g8add706704470554130f04b63e6ea440a171b747
Author: H.J. Lu <[email protected]>
Date:   Thu Jul 16 05:39:33 2026 +0800

    x86: Avoid misaligned prologue if count <= epilogue size
    
    After
    
    commit cbc56384029c9224280b0a1018fb9502797f243d
    Author: H.J. Lu <[email protected]>
    Date:   Fri Jun 26 08:43:20 2026 +0800
    
        determine_block_size: Set len_rtx to min size if min size == max size
    
    ix86_expand_set_or_cpymem may use vector loop on a block of memory whose
    size < epilogue size.  Don't use misaligned prologue if count <= epilogue
    size.
    
    gcc/
    
            PR target/126275
            * config/i386/i386-expand.cc (ix86_expand_set_or_cpymem): Don't
            use misaligned prologue if count <= epilogue size.
    
    gcc/testsuite/
    
            PR target/126275
            * gcc.target/i386/pr126275.c: New.
    
    Signed-off-by: H.J. Lu <[email protected]>

Diff:
---
 gcc/config/i386/i386-expand.cc           | 14 ++++++++-----
 gcc/testsuite/gcc.target/i386/pr126275.c | 36 ++++++++++++++++++++++++++++++++
 2 files changed, 45 insertions(+), 5 deletions(-)

diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index a448e470f737..fceb958b7e6a 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -9765,11 +9765,15 @@ ix86_expand_set_or_cpymem (rtx dst, rtx src, rtx 
count_exp, rtx val_exp,
       /* Destination is aligned after the misaligned prologue.  */
       aligned_dstmem = misaligned_prologue_used;
 
-      if (noalign && !misaligned_prologue_used)
-       {
-         /* Also use misaligned prologue if alignment isn't needed and
-            destination isn't aligned.   Since alignment isn't needed,
-            the destination after prologue won't be aligned.  */
+      if (noalign
+         && !misaligned_prologue_used
+         && (!count
+             || count > (unsigned HOST_WIDE_INT) epilogue_size_needed))
+       {
+         /* Also use misaligned prologue if count > epilogue size,
+            alignment isn't needed and destination isn't aligned.
+            Since alignment isn't needed, the destination after
+            prologue won't be aligned.  */
          aligned_dstmem = (GET_MODE_ALIGNMENT (move_mode)
                            <= MEM_ALIGN (dst));
          if (!aligned_dstmem)
diff --git a/gcc/testsuite/gcc.target/i386/pr126275.c 
b/gcc/testsuite/gcc.target/i386/pr126275.c
new file mode 100644
index 000000000000..21457bed0404
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr126275.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fno-pic -ftree-loop-distribute-patterns 
-fno-tree-dominator-opts -fno-tree-scev-cprop -march=x86-64" } */
+
+/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc').  */
+/* { dg-final { check-function-bodies "**" "" "" { target { *-*-linux* && lp64 
} } {^\t?\.} } } */
+
+/*
+**func:
+**.LFB0:
+**     .cfi_startproc
+**     movl    \$0, %eax
+**     .p2align 3
+**.L2:
+**     addl    \$1, %eax
+**     cmpl    \$18, %eax
+**     jne     .L2
+**     cltq
+**     movabsq \$506381209866536711, %rdx
+**     movq    %rdx, %xmm0
+**     punpcklqdq      %xmm0, %xmm0
+**     movups  %xmm0, buf\(%rax\)
+**     movb    \$7, buf\+16\(%rax\)
+**     ret
+**     .cfi_endproc
+**...
+*/
+
+extern char buf[512];
+
+void
+func (void)
+{
+  int i = 0;
+  for (; i < 18; i++);
+  for (; i < 35; i++) buf[i] = 7;
+}

Reply via email to