This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix up AVX512F 128/256-bit shifts from using EVEX counts (PR target/84786)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Kirill Yukhin <kirill dot yukhin at gmail dot com>, Uros Bizjak <ubizjak at gmail dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Fri, 22 Jun 2018 23:47:18 +0200
- Subject: [PATCH] Fix up AVX512F 128/256-bit shifts from using EVEX counts (PR target/84786)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
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