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

Jakub Jelinek jakub@redhat.com
Fri Jun 22 21:47:00 GMT 2018


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



More information about the Gcc-patches mailing list