re PR target/63594 (ICE: in ix86_vector_duplicate_value, at config/i386/i386.c:39831 with -mavx512f)
PR target/63594 * config/i386/i386.c (ix86_expand_vector_init_duplicate): For V{8HI,16QI,16HI,32QI}mode call ix86_vector_duplicate_value even for just TARGET_AVX2, not only for TARGET_AVX512VL && TARGET_AVX512BW. For V{32HI,64QI}mode, call ix86_vector_duplicate_value only if TARGET_AVX512BW, otherwise build it using concatenation of 256-bit broadcast. * config/i386/sse.md (AVX_VEC_DUP_MODE): Moved after avx512 broadcast patterns. (vec_dup<mode>): Likewise. For avx2 use v<sseintprefix>broadcast<bcstscalarsuff> instead of vbroadcast<ssescalarmodesuffix>. (AVX2_VEC_DUP_MODE): New mode iterator. (*vec_dup<mode>): New TARGET_AVX2 define_insn with AVX2_VEC_DUP_MODE iterator, add a splitter for that. * gcc.dg/pr63594-1.c: New test. * gcc.dg/pr63594-2.c: New test. * gcc.target/i386/sse2-pr63594-1.c: New test. * gcc.target/i386/sse2-pr63594-2.c: New test. * gcc.target/i386/avx-pr63594-1.c: New test. * gcc.target/i386/avx-pr63594-2.c: New test. * gcc.target/i386/avx2-pr63594-1.c: New test. * gcc.target/i386/avx2-pr63594-2.c: New test. * gcc.target/i386/avx512f-pr63594-1.c: New test. * gcc.target/i386/avx512f-pr63594-2.c: New test. * gcc.target/i386/avx512f-vec-init.c: Adjust expected insn counts. From-SVN: r216541
This commit is contained in:
parent
793dbadc8d
commit
7d9f1cd276
|
@ -1,5 +1,22 @@
|
|||
2014-10-22 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR target/63594
|
||||
* config/i386/i386.c (ix86_expand_vector_init_duplicate): For
|
||||
V{8HI,16QI,16HI,32QI}mode call ix86_vector_duplicate_value
|
||||
even for just TARGET_AVX2, not only for
|
||||
TARGET_AVX512VL && TARGET_AVX512BW. For V{32HI,64QI}mode,
|
||||
call ix86_vector_duplicate_value only if TARGET_AVX512BW,
|
||||
otherwise build it using concatenation of 256-bit
|
||||
broadcast.
|
||||
* config/i386/sse.md (AVX_VEC_DUP_MODE): Moved after
|
||||
avx512 broadcast patterns.
|
||||
(vec_dup<mode>): Likewise. For avx2 use
|
||||
v<sseintprefix>broadcast<bcstscalarsuff> instead of
|
||||
vbroadcast<ssescalarmodesuffix>.
|
||||
(AVX2_VEC_DUP_MODE): New mode iterator.
|
||||
(*vec_dup<mode>): New TARGET_AVX2 define_insn with
|
||||
AVX2_VEC_DUP_MODE iterator, add a splitter for that.
|
||||
|
||||
PR target/63542
|
||||
* config/i386/i386.c (ix86_pic_register_p): Also return
|
||||
true if x is a hard register with ORIGINAL_REGNO equal to
|
||||
|
|
|
@ -39870,8 +39870,6 @@ ix86_expand_vector_init_duplicate (bool mmx_ok, enum machine_mode mode,
|
|||
case V8SFmode:
|
||||
case V8SImode:
|
||||
case V2DFmode:
|
||||
case V64QImode:
|
||||
case V32HImode:
|
||||
case V2DImode:
|
||||
case V4SFmode:
|
||||
case V4SImode:
|
||||
|
@ -39902,8 +39900,8 @@ ix86_expand_vector_init_duplicate (bool mmx_ok, enum machine_mode mode,
|
|||
goto widen;
|
||||
|
||||
case V8HImode:
|
||||
if (TARGET_AVX512VL && TARGET_AVX512BW)
|
||||
return ix86_vector_duplicate_value (mode, target, val);
|
||||
if (TARGET_AVX2)
|
||||
return ix86_vector_duplicate_value (mode, target, val);
|
||||
|
||||
if (TARGET_SSE2)
|
||||
{
|
||||
|
@ -39935,8 +39933,8 @@ ix86_expand_vector_init_duplicate (bool mmx_ok, enum machine_mode mode,
|
|||
goto widen;
|
||||
|
||||
case V16QImode:
|
||||
if (TARGET_AVX512VL && TARGET_AVX512BW)
|
||||
return ix86_vector_duplicate_value (mode, target, val);
|
||||
if (TARGET_AVX2)
|
||||
return ix86_vector_duplicate_value (mode, target, val);
|
||||
|
||||
if (TARGET_SSE2)
|
||||
goto permute;
|
||||
|
@ -39967,8 +39965,8 @@ ix86_expand_vector_init_duplicate (bool mmx_ok, enum machine_mode mode,
|
|||
|
||||
case V16HImode:
|
||||
case V32QImode:
|
||||
if (TARGET_AVX512VL && TARGET_AVX512BW)
|
||||
return ix86_vector_duplicate_value (mode, target, val);
|
||||
if (TARGET_AVX2)
|
||||
return ix86_vector_duplicate_value (mode, target, val);
|
||||
else
|
||||
{
|
||||
enum machine_mode hvmode = (mode == V16HImode ? V8HImode : V16QImode);
|
||||
|
@ -39982,6 +39980,23 @@ ix86_expand_vector_init_duplicate (bool mmx_ok, enum machine_mode mode,
|
|||
}
|
||||
return true;
|
||||
|
||||
case V64QImode:
|
||||
case V32HImode:
|
||||
if (TARGET_AVX512BW)
|
||||
return ix86_vector_duplicate_value (mode, target, val);
|
||||
else
|
||||
{
|
||||
enum machine_mode hvmode = (mode == V32HImode ? V16HImode : V32QImode);
|
||||
rtx x = gen_reg_rtx (hvmode);
|
||||
|
||||
ok = ix86_expand_vector_init_duplicate (false, hvmode, x, val);
|
||||
gcc_assert (ok);
|
||||
|
||||
x = gen_rtx_VEC_CONCAT (mode, x, x);
|
||||
emit_insn (gen_rtx_SET (VOIDmode, target, x));
|
||||
}
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -16523,25 +16523,6 @@
|
|||
(set_attr "prefix" "vex")
|
||||
(set_attr "mode" "V4DF")])
|
||||
|
||||
;; Modes handled by AVX vec_dup patterns.
|
||||
(define_mode_iterator AVX_VEC_DUP_MODE
|
||||
[V8SI V8SF V4DI V4DF])
|
||||
|
||||
(define_insn "vec_dup<mode>"
|
||||
[(set (match_operand:AVX_VEC_DUP_MODE 0 "register_operand" "=x,v,x")
|
||||
(vec_duplicate:AVX_VEC_DUP_MODE
|
||||
(match_operand:<ssescalarmode> 1 "nonimmediate_operand" "m,v,?x")))]
|
||||
"TARGET_AVX"
|
||||
"@
|
||||
vbroadcast<ssescalarmodesuffix>\t{%1, %0|%0, %1}
|
||||
vbroadcast<ssescalarmodesuffix>\t{%x1, %0|%0, %x1}
|
||||
#"
|
||||
[(set_attr "type" "ssemov")
|
||||
(set_attr "prefix_extra" "1")
|
||||
(set_attr "prefix" "maybe_evex")
|
||||
(set_attr "isa" "*,avx2,noavx2")
|
||||
(set_attr "mode" "V8SF")])
|
||||
|
||||
(define_insn "<avx512>_vec_dup<mode><mask_name>"
|
||||
[(set (match_operand:V48_AVX512VL 0 "register_operand" "=v")
|
||||
(vec_duplicate:V48_AVX512VL
|
||||
|
@ -16644,6 +16625,59 @@
|
|||
(set_attr "prefix" "vex")
|
||||
(set_attr "mode" "OI")])
|
||||
|
||||
;; Modes handled by AVX vec_dup patterns.
|
||||
(define_mode_iterator AVX_VEC_DUP_MODE
|
||||
[V8SI V8SF V4DI V4DF])
|
||||
;; Modes handled by AVX2 vec_dup patterns.
|
||||
(define_mode_iterator AVX2_VEC_DUP_MODE
|
||||
[V32QI V16QI V16HI V8HI V8SI V4SI])
|
||||
|
||||
(define_insn "*vec_dup<mode>"
|
||||
[(set (match_operand:AVX2_VEC_DUP_MODE 0 "register_operand" "=x,x,x")
|
||||
(vec_duplicate:AVX2_VEC_DUP_MODE
|
||||
(match_operand:<ssescalarmode> 1 "nonimmediate_operand" "m,x,!r")))]
|
||||
"TARGET_AVX2"
|
||||
"@
|
||||
v<sseintprefix>broadcast<bcstscalarsuff>\t{%1, %0|%0, %1}
|
||||
v<sseintprefix>broadcast<bcstscalarsuff>\t{%x1, %0|%0, %x1}
|
||||
#"
|
||||
[(set_attr "type" "ssemov")
|
||||
(set_attr "prefix_extra" "1")
|
||||
(set_attr "prefix" "maybe_evex")
|
||||
(set_attr "mode" "<sseinsnmode>")])
|
||||
|
||||
(define_insn "vec_dup<mode>"
|
||||
[(set (match_operand:AVX_VEC_DUP_MODE 0 "register_operand" "=x,x,v,x")
|
||||
(vec_duplicate:AVX_VEC_DUP_MODE
|
||||
(match_operand:<ssescalarmode> 1 "nonimmediate_operand" "m,m,v,?x")))]
|
||||
"TARGET_AVX"
|
||||
"@
|
||||
v<sseintprefix>broadcast<bcstscalarsuff>\t{%1, %0|%0, %1}
|
||||
vbroadcast<ssescalarmodesuffix>\t{%1, %0|%0, %1}
|
||||
v<sseintprefix>broadcast<bcstscalarsuff>\t{%x1, %0|%0, %x1}
|
||||
#"
|
||||
[(set_attr "type" "ssemov")
|
||||
(set_attr "prefix_extra" "1")
|
||||
(set_attr "prefix" "maybe_evex")
|
||||
(set_attr "isa" "avx2,noavx2,avx2,noavx2")
|
||||
(set_attr "mode" "<sseinsnmode>,V8SF,<sseinsnmode>,V8SF")])
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:AVX2_VEC_DUP_MODE 0 "register_operand")
|
||||
(vec_duplicate:AVX2_VEC_DUP_MODE
|
||||
(match_operand:<ssescalarmode> 1 "register_operand")))]
|
||||
"TARGET_AVX2 && reload_completed && GENERAL_REG_P (operands[1])"
|
||||
[(const_int 0)]
|
||||
{
|
||||
emit_insn (gen_vec_setv4si_0 (gen_lowpart (V4SImode, operands[0]),
|
||||
CONST0_RTX (V4SImode),
|
||||
gen_lowpart (SImode, operands[1])));
|
||||
emit_insn (gen_avx2_pbroadcast<mode> (operands[0],
|
||||
gen_lowpart (<ssexmmmode>mode,
|
||||
operands[0])));
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:AVX_VEC_DUP_MODE 0 "register_operand")
|
||||
(vec_duplicate:AVX_VEC_DUP_MODE
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
2014-10-22 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR target/63594
|
||||
* gcc.dg/pr63594-1.c: New test.
|
||||
* gcc.dg/pr63594-2.c: New test.
|
||||
* gcc.target/i386/sse2-pr63594-1.c: New test.
|
||||
* gcc.target/i386/sse2-pr63594-2.c: New test.
|
||||
* gcc.target/i386/avx-pr63594-1.c: New test.
|
||||
* gcc.target/i386/avx-pr63594-2.c: New test.
|
||||
* gcc.target/i386/avx2-pr63594-1.c: New test.
|
||||
* gcc.target/i386/avx2-pr63594-2.c: New test.
|
||||
* gcc.target/i386/avx512f-pr63594-1.c: New test.
|
||||
* gcc.target/i386/avx512f-pr63594-2.c: New test.
|
||||
* gcc.target/i386/avx512f-vec-init.c: Adjust expected
|
||||
insn counts.
|
||||
|
||||
PR target/63542
|
||||
* gcc.target/i386/pr63542-1.c: New test.
|
||||
* gcc.target/i386/pr63542-2.c: New test.
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
/* PR target/63594 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -Wno-psabi" } */
|
||||
/* { dg-additional-options "-mno-mmx" { target i?86-*-linux* x86_64-*-linux* } } */
|
||||
|
||||
#define C1 c
|
||||
#define C2 C1, C1
|
||||
#define C4 C2, C2
|
||||
#define C8 C4, C4
|
||||
#define C16 C8, C8
|
||||
#define C32 C16, C16
|
||||
#define C64 C32, C32
|
||||
#define C_(n) n
|
||||
#define C(n) C_(C##n)
|
||||
|
||||
#define T(t,s) \
|
||||
typedef t v##t##s __attribute__ ((__vector_size__ (s * sizeof (t)))); \
|
||||
v##t##s \
|
||||
test1##t##s (t c) \
|
||||
{ \
|
||||
v##t##s v = { C(s) }; \
|
||||
return v; \
|
||||
} \
|
||||
\
|
||||
v##t##s \
|
||||
test2##t##s (t *p) \
|
||||
{ \
|
||||
t c = *p; \
|
||||
v##t##s v = { C(s) }; \
|
||||
return v; \
|
||||
}
|
||||
|
||||
typedef long long llong;
|
||||
|
||||
T(char, 64)
|
||||
T(char, 32)
|
||||
T(char, 16)
|
||||
T(char, 8)
|
||||
T(char, 4)
|
||||
T(char, 2)
|
||||
T(char, 1)
|
||||
T(short, 32)
|
||||
T(short, 16)
|
||||
T(short, 8)
|
||||
T(short, 4)
|
||||
T(short, 2)
|
||||
T(short, 1)
|
||||
T(int, 16)
|
||||
T(int, 8)
|
||||
T(int, 4)
|
||||
T(int, 2)
|
||||
T(int, 1)
|
||||
T(float, 16)
|
||||
T(float, 8)
|
||||
T(float, 4)
|
||||
T(float, 2)
|
||||
T(float, 1)
|
||||
T(llong, 8)
|
||||
T(llong, 4)
|
||||
T(llong, 2)
|
||||
T(llong, 1)
|
||||
T(double, 8)
|
||||
T(double, 4)
|
||||
T(double, 2)
|
||||
T(double, 1)
|
|
@ -0,0 +1,92 @@
|
|||
/* PR target/63594 */
|
||||
/* { dg-do run } */
|
||||
/* { dg-options "-O2 -Wno-psabi" } */
|
||||
/* { dg-additional-options "-mno-mmx" { target i?86-*-linux* x86_64-*-linux* } } */
|
||||
|
||||
#define C1 c
|
||||
#define C2 C1, C1
|
||||
#define C4 C2, C2
|
||||
#define C8 C4, C4
|
||||
#define C16 C8, C8
|
||||
#define C32 C16, C16
|
||||
#define C64 C32, C32
|
||||
#define C_(n) n
|
||||
#define C(n) C_(C##n)
|
||||
|
||||
#define T(t,s) \
|
||||
typedef t v##t##s __attribute__ ((__vector_size__ (s * sizeof (t)))); \
|
||||
__attribute__((noinline, noclone)) v##t##s \
|
||||
test1##t##s (t c) \
|
||||
{ \
|
||||
v##t##s v = { C(s) }; \
|
||||
return v; \
|
||||
} \
|
||||
\
|
||||
__attribute__((noinline, noclone)) v##t##s \
|
||||
test2##t##s (t *p) \
|
||||
{ \
|
||||
t c = *p; \
|
||||
v##t##s v = { C(s) }; \
|
||||
return v; \
|
||||
} \
|
||||
\
|
||||
void \
|
||||
test3##t##s (void) \
|
||||
{ \
|
||||
t c = 17; \
|
||||
int i; \
|
||||
v##t##s a = test1##t##s (c); \
|
||||
for (i = 0; i < s; i++) \
|
||||
if (a[i] != 17) \
|
||||
__builtin_abort (); \
|
||||
v##t##s b = test2##t##s (&c); \
|
||||
for (i = 0; i < s; i++) \
|
||||
if (a[i] != 17) \
|
||||
__builtin_abort (); \
|
||||
}
|
||||
|
||||
typedef long long llong;
|
||||
|
||||
#define TESTS \
|
||||
T(char, 64) \
|
||||
T(char, 32) \
|
||||
T(char, 16) \
|
||||
T(char, 8) \
|
||||
T(char, 4) \
|
||||
T(char, 2) \
|
||||
T(char, 1) \
|
||||
T(short, 32) \
|
||||
T(short, 16) \
|
||||
T(short, 8) \
|
||||
T(short, 4) \
|
||||
T(short, 2) \
|
||||
T(short, 1) \
|
||||
T(int, 16) \
|
||||
T(int, 8) \
|
||||
T(int, 4) \
|
||||
T(int, 2) \
|
||||
T(int, 1) \
|
||||
T(float, 16) \
|
||||
T(float, 8) \
|
||||
T(float, 4) \
|
||||
T(float, 2) \
|
||||
T(float, 1) \
|
||||
T(llong, 8) \
|
||||
T(llong, 4) \
|
||||
T(llong, 2) \
|
||||
T(llong, 1) \
|
||||
T(double, 8) \
|
||||
T(double, 4) \
|
||||
T(double, 2) \
|
||||
T(double, 1)
|
||||
|
||||
TESTS
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
#undef T
|
||||
#define T(t,s) test3##t##s ();
|
||||
TESTS
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
/* PR target/63594 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -mavx -mno-mmx -Wno-psabi" } */
|
||||
|
||||
#include "../../gcc.dg/pr63594-1.c"
|
|
@ -0,0 +1,18 @@
|
|||
/* PR target/63594 */
|
||||
/* { dg-do run { target avx } } */
|
||||
/* { dg-options "-O2 -mavx -mno-mmx -Wno-psabi" } */
|
||||
|
||||
#include "avx-check.h"
|
||||
|
||||
int do_main (void);
|
||||
|
||||
static void
|
||||
avx_test (void)
|
||||
{
|
||||
do_main ();
|
||||
}
|
||||
|
||||
#undef main
|
||||
#define main() do_main ()
|
||||
|
||||
#include "../../gcc.dg/pr63594-2.c"
|
|
@ -0,0 +1,5 @@
|
|||
/* PR target/63594 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -mavx2 -mno-mmx -Wno-psabi" } */
|
||||
|
||||
#include "../../gcc.dg/pr63594-1.c"
|
|
@ -0,0 +1,18 @@
|
|||
/* PR target/63594 */
|
||||
/* { dg-do run { target avx2 } } */
|
||||
/* { dg-options "-O2 -mavx2 -mno-mmx -Wno-psabi" } */
|
||||
|
||||
#include "avx2-check.h"
|
||||
|
||||
int do_main (void);
|
||||
|
||||
static void
|
||||
avx2_test (void)
|
||||
{
|
||||
do_main ();
|
||||
}
|
||||
|
||||
#undef main
|
||||
#define main() do_main ()
|
||||
|
||||
#include "../../gcc.dg/pr63594-2.c"
|
|
@ -0,0 +1,5 @@
|
|||
/* PR target/63594 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -mavx512f -mno-mmx -Wno-psabi" } */
|
||||
|
||||
#include "../../gcc.dg/pr63594-1.c"
|
|
@ -0,0 +1,18 @@
|
|||
/* PR target/63594 */
|
||||
/* { dg-do run { target avx512f } } */
|
||||
/* { dg-options "-O2 -mavx512f -mno-mmx -Wno-psabi" } */
|
||||
|
||||
#include "avx512f-check.h"
|
||||
|
||||
int do_main (void);
|
||||
|
||||
static void
|
||||
avx512f_test (void)
|
||||
{
|
||||
do_main ();
|
||||
}
|
||||
|
||||
#undef main
|
||||
#define main() do_main ()
|
||||
|
||||
#include "../../gcc.dg/pr63594-2.c"
|
|
@ -1,12 +1,12 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O3 -mavx512f" } */
|
||||
/* { dg-final { scan-assembler-times "vmovdqa64\[ \\t\]+%zmm" 2 } } */
|
||||
/* { dg-final { scan-assembler-times "vpbroadcastd" 1 } } */
|
||||
/* { dg-final { scan-assembler-times "vpbroadcastq" 1 } } */
|
||||
/* { dg-final { scan-assembler-times "vpbroadcastb" 2 } } */
|
||||
/* { dg-final { scan-assembler-times "vpbroadcastw" 2 } } */
|
||||
/* { dg-final { scan-assembler-times "vbroadcastss" 1 } } */
|
||||
/* { dg-final { scan-assembler-times "vbroadcastsd" 1 } } */
|
||||
/* { dg-final { scan-assembler-times "vmovdqa64\[ \\t\]+%zmm" 0 } } */
|
||||
/* { dg-final { scan-assembler-times "vpbroadcastd" 2 } } */
|
||||
/* { dg-final { scan-assembler-times "vpbroadcastq" 2 } } */
|
||||
/* { dg-final { scan-assembler-times "vpbroadcastb" 3 } } */
|
||||
/* { dg-final { scan-assembler-times "vpbroadcastw" 3 } } */
|
||||
/* { dg-final { scan-assembler-times "vbroadcastss" 0 } } */
|
||||
/* { dg-final { scan-assembler-times "vbroadcastsd" 0 } } */
|
||||
|
||||
#include <x86intrin.h>
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
/* PR target/63594 */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -msse2 -mno-mmx -Wno-psabi" } */
|
||||
|
||||
#include "../../gcc.dg/pr63594-1.c"
|
|
@ -0,0 +1,18 @@
|
|||
/* PR target/63594 */
|
||||
/* { dg-do run { target sse2 } } */
|
||||
/* { dg-options "-O2 -msse2 -mno-mmx -Wno-psabi" } */
|
||||
|
||||
#include "sse2-check.h"
|
||||
|
||||
int do_main (void);
|
||||
|
||||
static void
|
||||
sse2_test (void)
|
||||
{
|
||||
do_main ();
|
||||
}
|
||||
|
||||
#undef main
|
||||
#define main() do_main ()
|
||||
|
||||
#include "../../gcc.dg/pr63594-2.c"
|
Loading…
Reference in New Issue