This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix up AVX512F 128/256-bit shifts from using EVEX counts (PR target/84786)


Hi!

The following testcase got fixed in 8/trunk with r253924 part of
PR82370 enhancements, but that is not IMHO something we should backport.
So instead the following patch adds something simpler, use Yv constraint
for the DImode shift count in instructions that need AVX512VL when EVEX
encoded if AVX512VL is not enabled instead of v.  Bootstrapped/regtested
on 7.x branch on x86_64-linux and i686-linux, ok for 7.x?

Is the testcase alone ok also for trunk/8.2?

2018-06-22  Jakub Jelinek  <jakub@redhat.com>

	PR target/84786
	* config/i386/sse.md (vshift_count): New mode attr.
	(<shift_insn><mode>3<mask_name>): Use <vshift_count>N instead of vN
	as last operand's constraint for VI2_AVX2_AVX512BW shifts.  Use YvN
	instead of vN as last operand's constraint for VI48_AVX2 shifts.

	* gcc.target/i386/avx512f-pr84786-3.c: New test.

--- gcc/config/i386/sse.md.jj	2018-06-22 16:26:34.960232598 +0200
+++ gcc/config/i386/sse.md	2018-06-22 18:04:12.948857074 +0200
@@ -10680,11 +10680,14 @@ (define_insn "ashr<mode>3<mask_name>"
        (const_string "0")))
    (set_attr "mode" "<sseinsnmode>")])
 
+(define_mode_attr vshift_count
+  [(V32HI "v") (V16HI "Yv") (V8HI "Yv")])
+
 (define_insn "<shift_insn><mode>3<mask_name>"
   [(set (match_operand:VI2_AVX2_AVX512BW 0 "register_operand" "=x,v")
 	(any_lshift:VI2_AVX2_AVX512BW
 	  (match_operand:VI2_AVX2_AVX512BW 1 "register_operand" "0,v")
-	  (match_operand:DI 2 "nonmemory_operand" "xN,vN")))]
+	  (match_operand:DI 2 "nonmemory_operand" "xN,<vshift_count>N")))]
   "TARGET_SSE2 && <mask_mode512bit_condition> && <mask_avx512bw_condition>"
   "@
    p<vshift><ssemodesuffix>\t{%2, %0|%0, %2}
@@ -10703,7 +10706,7 @@ (define_insn "<shift_insn><mode>3<mask_n
   [(set (match_operand:VI48_AVX2 0 "register_operand" "=x,x,v")
 	(any_lshift:VI48_AVX2
 	  (match_operand:VI48_AVX2 1 "register_operand" "0,x,v")
-	  (match_operand:DI 2 "nonmemory_operand" "xN,xN,vN")))]
+	  (match_operand:DI 2 "nonmemory_operand" "xN,xN,YvN")))]
   "TARGET_SSE2 && <mask_mode512bit_condition>"
   "@
    p<vshift><ssemodesuffix>\t{%2, %0|%0, %2}
--- gcc/testsuite/gcc.target/i386/avx512f-pr84786-3.c.jj	2018-06-22 18:05:06.267926542 +0200
+++ gcc/testsuite/gcc.target/i386/avx512f-pr84786-3.c	2018-06-22 17:39:23.445546062 +0200
@@ -0,0 +1,50 @@
+/* PR target/84786 */
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-mavx512f -mno-avx512vl -O2" } */
+
+#include <x86intrin.h>
+
+__m512i v;
+__m128i w;
+
+__m128i
+foo (__m128i x, int y)
+{
+  __m128i z;
+#define A(n) register __m512i zmm##n __asm ("zmm" #n);
+#define B A(1) A(2) A(3) A(4) A(5) A(6) A(7) \
+	  A(8) A(9) A(10) A(11) A(12) A(13) A(14)
+  B
+#undef A
+#define A(n) asm volatile ("" : "=v" (zmm##n) : "0" (v));
+  B
+  asm volatile ("" : "=x" (z) : "0" (w));
+  x = _mm_srli_epi16 (x, y);
+  asm volatile ("" : : "x" (z));
+#undef A
+#define A(n) asm volatile ("" : : "v" (zmm##n));
+  B
+  return x;
+}
+
+__m256i
+bar (__m256i x, int y)
+{
+  __m128i z;
+#undef A
+#define A(n) register __m512i zmm##n __asm ("zmm" #n);
+  B
+#undef A
+#define A(n) asm volatile ("" : "=v" (zmm##n) : "0" (v));
+  B
+  asm volatile ("" : "=x" (z) : "0" (w));
+  x = _mm256_slli_epi16 (x, y);
+  asm volatile ("" : : "x" (z));
+#undef A
+#define A(n) asm volatile ("" : : "v" (zmm##n));
+  B
+  return x;
+}
+
+/* { dg-final { scan-assembler-not "vpsrlw\[\^\n\r]*xmm(1\[6-9]|\[23]\[0-9])" } } */
+/* { dg-final { scan-assembler-not "vpsllw\[\^\n\r]*xmm(1\[6-9]|\[23]\[0-9])" } } */

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]