diff options
author | Roger Sayle <roger@nextmovesoftware.com> | 2022-04-06 07:15:31 +0100 |
---|---|---|
committer | Roger Sayle <roger@nextmovesoftware.com> | 2022-04-06 07:19:08 +0100 |
commit | 6d4bbee4f59c7102f8ed9b6774f0b2d9f6ff4365 (patch) | |
tree | 72195b452667579281249d309b0103e71d6e9990 | |
parent | fc8d9e4497032dd295aac9414042163f92250b77 (diff) | |
download | gcc-6d4bbee4f59c7102f8ed9b6774f0b2d9f6ff4365.zip gcc-6d4bbee4f59c7102f8ed9b6774f0b2d9f6ff4365.tar.gz gcc-6d4bbee4f59c7102f8ed9b6774f0b2d9f6ff4365.tar.bz2 |
Support pandn for V1TI mode (i.e. *andnotv1ti3).
This simple patch allows the i386 backend to generate pandn instructions
for V1TI mode. Currently, the testcase:
typedef unsigned __int128 v1ti __attribute__ ((__vector_size__ (16)));
v1ti andnot1(v1ti x, v1ti y) { return ~x & y; }
generates with -O2
pcmpeqd %xmm2, %xmm2
pxor %xmm2, %xmm0
pand %xmm1, %xmm0
ret
with this patch, we now generate:
pandn %xmm1, %xmm0
ret
It turns out that there are currently three (near) duplicates of the
logic for andn/pandn/vandn/vpandn in i386/sse.md: one for floating point
vectors (MODEF), one for integer vectors (VI) and a third for TFmode.
Rather than introduce a fourth copy, this patch introduces a new mode
iterator to share/reuse the TFmode define_insn to also handle V1TI.
2022-04-06 Roger Sayle <roger@nextmovesoftware.com>
gcc/ChangeLog
* config/i386/sse.md (ANDNOT_MODE): New mode iterator for TF and V1TI.
(*andnottf3): Replace with...
(*andnot<mode>3): New define_insn using ANDNOT_MODE.
gcc/testsuite/ChangeLog
* gcc.target/i386/sse2-v1ti-andnot.c: New test case.
-rw-r--r-- | gcc/config/i386/sse.md | 13 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/sse2-v1ti-andnot.c | 11 |
2 files changed, 19 insertions, 5 deletions
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index 1f9c496..a852c16 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -4923,11 +4923,14 @@ ] (const_string "<ssevecmode>")))]) -(define_insn "*andnottf3" - [(set (match_operand:TF 0 "register_operand" "=x,x,v,v") - (and:TF - (not:TF (match_operand:TF 1 "register_operand" "0,x,v,v")) - (match_operand:TF 2 "vector_operand" "xBm,xm,vm,v")))] +;; Modes for andnot3 not covered by VI and MODEF. +(define_mode_iterator ANDNOT_MODE [TF V1TI]) + +(define_insn "*andnot<mode>3" + [(set (match_operand:ANDNOT_MODE 0 "register_operand" "=x,x,v,v") + (and:ANDNOT_MODE + (not:ANDNOT_MODE (match_operand:ANDNOT_MODE 1 "register_operand" "0,x,v,v")) + (match_operand:ANDNOT_MODE 2 "vector_operand" "xBm,xm,vm,v")))] "TARGET_SSE" { char buf[128]; diff --git a/gcc/testsuite/gcc.target/i386/sse2-v1ti-andnot.c b/gcc/testsuite/gcc.target/i386/sse2-v1ti-andnot.c new file mode 100644 index 0000000..ae4cb02 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/sse2-v1ti-andnot.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2 -msse2" } */ + +typedef __int128 v1ti __attribute__ ((__vector_size__ (16))); + +v1ti andnot1(v1ti x, v1ti y) { return ~x & y; } +v1ti andnot2(v1ti x, v1ti y) { return x & ~y; } + +/* { dg-final { scan-assembler-times "pandn" 2 } } */ +/* { dg-final { scan-assembler-not "pcmpeqd" } } */ +/* { dg-final { scan-assembler-not "pxor" } } */ |