aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRoger Sayle <roger@nextmovesoftware.com>2022-04-06 07:15:31 +0100
committerRoger Sayle <roger@nextmovesoftware.com>2022-04-06 07:19:08 +0100
commit6d4bbee4f59c7102f8ed9b6774f0b2d9f6ff4365 (patch)
tree72195b452667579281249d309b0103e71d6e9990 /gcc
parentfc8d9e4497032dd295aac9414042163f92250b77 (diff)
downloadgcc-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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/i386/sse.md13
-rw-r--r--gcc/testsuite/gcc.target/i386/sse2-v1ti-andnot.c11
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" } } */