AMD General

Hi all,

> -----Original Message-----
> From: Liu, Hongtao <[email protected]>
> Sent: Tuesday, June 23, 2026 12:49 PM
> To: Chandra, Sarvesh <[email protected]>; [email protected]
> Cc: Godbole, Ashwin <[email protected]>; Richard Biener
> <[email protected]>; Uros Bizjak <[email protected]>; Venkataramanan
> Kumar <[email protected]>
> Subject: RE: [PATCH v2] i386: Emit vunpcklpd for register V4DF/V8DF movddup
> [PR107057]
>
> Caution: This message originated from an External Source. Use proper caution
> when opening attachments, clicking links, or responding.
>
>
> > -----Original Message-----
> > From: Sarvesh Chandra <[email protected]>
> > Sent: Tuesday, June 23, 2026 3:17 PM
> > To: [email protected]
> > Cc: Liu, Hongtao <[email protected]>; Ashwin Godbole
> > <[email protected]>; Sarvesh Chandra
> <[email protected]>;
> > Richard Biener <[email protected]>; Uros Bizjak <[email protected]>;
> > Venkataramanan Kumar <[email protected]>
> > Subject: [PATCH v2] i386: Emit vunpcklpd for register V4DF/V8DF
> > movddup [PR107057]
> >
> > These movddup patterns only accepted a memory source, so duplicating
> > the even lanes of a register value spilled it to the stack.  Add a
> > register alternative that emits vunpcklpd; a memory source still uses
> vmovddup.
>
> Ok.

I have committed to stage.

Regards,
Venkat.
>
> >
> > gcc/ChangeLog:
> >
> >       PR target/107057
> >       * config/i386/sse.md (avx512f_movddup512<mask_name>): Add a
> >       register source alternative that emits vunpcklpd.
> >       (avx_movddup256<mask_name>): Likewise.
> >
> > gcc/testsuite/ChangeLog:
> >
> >       PR target/107057
> >       * gcc.target/i386/avx512-movedup.c: New test.
> >
> > Co-authored-by: Ashwin Godbole <[email protected]>
> > Signed-off-by: Sarvesh Chandra <[email protected]>
> > ---
> > Bootstrapped and regression-tested on x86_64-pc-linux-gnu.
> >
> > v2: add a register alternative instead of reordering the patterns.
> >
> > Note: the register alternative is typed sselog1 rather than sselog, as
> > GCC uses the sselog1 type for single-source-operand SSE logical insns.
> >
> >  gcc/config/i386/sse.md                        | 20 +++++++++++--------
> >  .../gcc.target/i386/avx512-movedup.c          | 14 +++++++++++++
> >  2 files changed, 26 insertions(+), 8 deletions(-)  create mode 100644
> > gcc/testsuite/gcc.target/i386/avx512-movedup.c
> >
> > diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index
> > 5d9ab8b14eb..74078a772a7 100644
> > --- a/gcc/config/i386/sse.md
> > +++ b/gcc/config/i386/sse.md
> > @@ -13917,18 +13917,20 @@
> >     (set_attr "mode" "V2DF,V2DF,V1DF,V1DF,V1DF")])
> >
> >  (define_insn "avx512f_movddup512<mask_name>"
> > -  [(set (match_operand:V8DF 0 "register_operand" "=v")
> > +  [(set (match_operand:V8DF 0 "register_operand" "=v,v")
> >       (vec_select:V8DF
> >         (vec_concat:V16DF
> > -         (match_operand:V8DF 1 "nonimmediate_operand" "m")
> > +         (match_operand:V8DF 1 "nonimmediate_operand" "v,m")
> >           (match_dup 1))
> >         (parallel [(const_int 0) (const_int 8)
> >                    (const_int 2) (const_int 10)
> >                    (const_int 4) (const_int 12)
> >                    (const_int 6) (const_int 14)])))]
> >    "TARGET_AVX512F"
> > -  "vmovddup\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
> > -  [(set_attr "type" "ssemov")
> > +  "@
> > +
> > vunpcklpd\t{%1, %1, %0<mask_operand2>|%0<mask_operand2>, %1, %1}
> > +   vmovddup\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
> > +  [(set_attr "type" "sselog1,ssemov")
> >     (set_attr "prefix" "evex")
> >     (set_attr "mode" "V8DF")])
> >
> > @@ -13950,16 +13952,18 @@
> >
> >  ;; Recall that the 256-bit unpck insns only shuffle within their lanes.
> >  (define_insn "avx_movddup256<mask_name>"
> > -  [(set (match_operand:V4DF 0 "register_operand" "=v")
> > +  [(set (match_operand:V4DF 0 "register_operand" "=v,v")
> >       (vec_select:V4DF
> >         (vec_concat:V8DF
> > -         (match_operand:V4DF 1 "nonimmediate_operand" "m")
> > +         (match_operand:V4DF 1 "nonimmediate_operand" "v,m")
> >           (match_dup 1))
> >         (parallel [(const_int 0) (const_int 4)
> >                    (const_int 2) (const_int 6)])))]
> >    "TARGET_AVX && <mask_avx512vl_condition>"
> > -  "vmovddup\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
> > -  [(set_attr "type" "ssemov")
> > +  "@
> > +
> > vunpcklpd\t{%1, %1, %0<mask_operand2>|%0<mask_operand2>, %1, %1}
> > +   vmovddup\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
> > +  [(set_attr "type" "sselog1,ssemov")
> >     (set_attr "prefix" "<mask_prefix>")
> >     (set_attr "mode" "V4DF")])
> >
> > diff --git a/gcc/testsuite/gcc.target/i386/avx512-movedup.c
> > b/gcc/testsuite/gcc.target/i386/avx512-movedup.c
> > new file mode 100644
> > index 00000000000..3b2943bb67d
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/i386/avx512-movedup.c
> > @@ -0,0 +1,14 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-O2 -mavx512f" } */
> > +/* { dg-final { scan-assembler "vunpcklpd\[ \\t\]+%zmm\[0-9\]+,
> > +%zmm\[0-9\]+" } } */
> > +/* { dg-final { scan-assembler "vunpcklpd\[ \\t\]+%ymm\[0-9\]+,
> > +%ymm\[0-9\]+" } } */
> > +/* { dg-final { scan-assembler "vmovddup\[ \\t\]+\\(" } } */
> > +/* { dg-final { scan-assembler-not "vmovddup\[^\\n\]*\\(%\[er\]sp\\)"
> > +} } */
> > +
> > +#include <immintrin.h>
> > +
> > +__m512d dup512 (__m512d x) { return _mm512_movedup_pd (x); }
> > __m256d
> > +dup256 (__m256d x) { return _mm256_movedup_pd (x); } __m512d
> > +interleave512 (__m512d x) { return _mm512_unpacklo_pd (x, x); }
> > +__m256d
> > +interleave256 (__m256d x) { return _mm256_unpacklo_pd (x, x); }
> > +__m512d
> > +load512 (double *p) { return _mm512_movedup_pd (_mm512_loadu_pd
> > (p)); }
> > --
> > 2.34.1

Reply via email to