https://gcc.gnu.org/g:8747b25bcd9606418296906091674d97fd4b65a7

commit r17-4049-g8747b25bcd9606418296906091674d97fd4b65a7
Author: Uros Bizjak <[email protected]>
Date:   Thu Sep 10 08:11:56 2026 +0200

    i386: Improve insn conditions of vec_concatv2{sf,si} patterns for SSE4.1
    
    Improve an incorrect insn condition and avoid selecting the SSE
    vec_concatv2sf pattern when SSE4.1 is available.
    
    The SSE4.1 pattern has alternatives that accept a memory operand 1 only
    when operand 2 is zero.  However, its old condition only rejected the
    case where both operands were memory operands.  As a result, a memory
    operand 1 combined with a non-zero register operand 2 could be
    advertised even though that form is not encodable.
    
    Restrict the condition in the same way as the available alternatives:
    when operand 1 is a MEM, operand 2 must be CONST0_RTX.
    
    The generic SSE pattern is also disabled when SSE4.1 is enabled, so that
    the more appropriate SSE4.1 pattern is selected.
    
    gcc/ChangeLog:
    
            * config/i386/sse.md (*vec_concatv2sf_sse4_1): Restrict the 
condition
            to accept only CONST0_RTX as operand 2 when operand 1 is MEM.
            (*vec_concatv2si_sse4_1): Ditto.
            (*vec_concatv2sf_sse): Disable the pattern when SSE4.1 is enabled.
            (*vec_concatv2si_sse): Rename from *vec_concatv2si.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/i386/vec-concatv2sf.c: New test.

Diff:
---
 gcc/config/i386/sse.md                         | 10 ++++++----
 gcc/testsuite/gcc.target/i386/vec-concatv2sf.c | 21 +++++++++++++++++++++
 2 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index fe25d3cdce49..eb3b8eb2fe05 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -12480,7 +12480,8 @@
          "  0, 0,Yv, 0,0, v,m, 0 , m")
          (match_operand:SF 2 "nonimm_or_0_operand"
          " Yr,*x,Yv, jm,jm, m,C,*ym, C")))]
-  "TARGET_SSE4_1 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
+  "TARGET_SSE4_1
+   && (operands[2] == CONST0_RTX (SFmode) || !MEM_P (operands[1]))"
   "@
    unpcklps\t{%2, %0|%0, %2}
    unpcklps\t{%2, %0|%0, %2}
@@ -12544,7 +12545,7 @@
        (vec_concat:V2SF
          (match_operand:SF 1 "nonimmediate_operand" " 0,m, 0, m")
          (match_operand:SF 2 "reg_or_0_operand"     " x,C,*y, C")))]
-  "TARGET_SSE"
+  "TARGET_SSE && !TARGET_SSE4_1"
   "@
    unpcklps\t{%2, %0|%0, %2}
    movss\t{%1, %0|%0, %1}
@@ -22464,7 +22465,8 @@
          "  0, 0, x,Yv, 0, 0,Yv,rm,  0,rm")
          (match_operand:SI 2 "nonimm_or_0_operand"
          "jrjm,jrjm,rm,rm,Yr,*x,Yv, C,*ym, C")))]
-  "TARGET_SSE4_1 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
+  "TARGET_SSE4_1
+   && (operands[2] == CONST0_RTX (SImode) || !MEM_P (operands[1]))"
   "@
    pinsrd\t{$1, %2, %0|%0, %2, 1}
    pinsrd\t{$1, %2, %0|%0, %2, 1}
@@ -22512,7 +22514,7 @@
 ;; ??? In theory we can match memory for the MMX alternative, but allowing
 ;; nonimmediate_operand for operand 2 and *not* allowing memory for the SSE
 ;; alternatives pretty much forces the MMX alternative to be chosen.
-(define_insn "*vec_concatv2si"
+(define_insn "*vec_concatv2si_sse"
   [(set (match_operand:V2SI 0 "register_operand"     "=x,x ,x,x,*y,*y")
        (vec_concat:V2SI
          (match_operand:SI 1 "nonimmediate_operand" " 0,rm,0,m, 0,rm")
diff --git a/gcc/testsuite/gcc.target/i386/vec-concatv2sf.c 
b/gcc/testsuite/gcc.target/i386/vec-concatv2sf.c
new file mode 100644
index 000000000000..925f18a54b6f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vec-concatv2sf.c
@@ -0,0 +1,21 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx -masm=att" } */
+
+typedef float v2sf __attribute__((vector_size (8)));
+
+v2sf
+f1 (float *a, float *b)
+{
+  return (v2sf) { *b, *a };
+}
+
+/* { dg-final { scan-assembler-times "vinsertps\[ \t]" 1 } } */
+/* { dg-final { scan-assembler-not "vunpcklps" } } */
+
+v2sf
+f2 (float *a)
+{
+  return (v2sf) { *a, 0.0 };
+}
+
+/* { dg-final { scan-assembler-times "vmovss\[ \t]" 2 } } */

Reply via email to