Hi, This patch disables two match.pd patterns which transform VEC_COND_EXPR into simple conversion in case it uses a scalar mask. The patch was bootstrapped and regtested on x86_64-pc-linux-gnu + separate check for new test on SDE. OK for trunk?
Thanks, Ilya -- gcc/ 2016-03-17 Ilya Enkovich <enkovich....@gmail.com> * match.pd (A + (B vcmp C ? 1 : 0) -> A - (B vcmp C)): Apply for boolean vector with vector mode only. (A - (B vcmp C ? 1 : 0) -> A + (B vcmp C)): Likewise. gcc/testsuite/ 2016-03-17 Ilya Enkovich <enkovich....@gmail.com> * gcc.target/i386/pr70251.c: New test. diff --git a/gcc/match.pd b/gcc/match.pd index 112deb3..7245ff4 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -1759,6 +1759,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (simplify (plus:c @3 (view_convert? (vec_cond @0 integer_each_onep@1 integer_zerop@2))) (if (VECTOR_TYPE_P (type) + && VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (@0))) && TYPE_VECTOR_SUBPARTS (type) == TYPE_VECTOR_SUBPARTS (TREE_TYPE (@0)) && (TYPE_MODE (TREE_TYPE (type)) == TYPE_MODE (TREE_TYPE (TREE_TYPE (@0))))) @@ -1768,6 +1769,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (simplify (minus @3 (view_convert? (vec_cond @0 integer_each_onep@1 integer_zerop@2))) (if (VECTOR_TYPE_P (type) + && VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (@0))) && TYPE_VECTOR_SUBPARTS (type) == TYPE_VECTOR_SUBPARTS (TREE_TYPE (@0)) && (TYPE_MODE (TREE_TYPE (type)) == TYPE_MODE (TREE_TYPE (TREE_TYPE (@0))))) diff --git a/gcc/testsuite/gcc.target/i386/pr70251.c b/gcc/testsuite/gcc.target/i386/pr70251.c new file mode 100644 index 0000000..97078cd --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr70251.c @@ -0,0 +1,52 @@ +/* { dg-do run } */ +/* { dg-options "-O3 -mavx512bw" } */ +/* { dg-require-effective-target avx512bw } */ + +#define AVX512BW +#include "avx512f-helper.h" + +unsigned long long int +hash(unsigned long long int seed, unsigned long long int v) +{ + return seed ^ (v + 0x9e3779b9 + (seed<<6) + (seed>>2)); +} + +unsigned int a [100]; +signed char b [100]; +signed char c [100]; + +void +init () +{ + for (int i = 0; i < 100; ++i) + { + a [i] = 1000L; + b [i] = 10; + c [i] = 5; + } +} + +void +foo () +{ + for (int i = 0; i < 100; ++i) + b [i] = (!b [i] ^ (a [i] >= b [i])) + c [i]; +} + +unsigned long long int +checksum () +{ + unsigned long long int seed = 0ULL; + for (int i = 0; i < 100; ++i) + seed = hash (seed, b[i]); + return seed; +} + +void +TEST () +{ + init (); + foo (); + if (checksum () != 5785906989299578598ULL) + __builtin_abort (); +}