On Thu, Sep 16, 2021 at 8:27 AM liuhongt <hongtao....@intel.com> wrote: > > Ping. > > Bootstrapped and regtest on x86_64-linux-gnu{-m32,}, > aarch64-unknown-linux-gnu{-m32,} > Ok for trunk? > > gcc/ChangeLog: > > PR middle-end/102080 > * match.pd: Check mask type when doing cond_op related gimple > simplification. > * tree.c (is_truth_type_for): New function. > * tree.h (is_truth_type_for): New declaration. > > gcc/testsuite/ChangeLog: > > PR middle-end/102080 > * gcc.target/i386/pr102080.c: New test. > --- > gcc/match.pd | 8 +++---- > gcc/testsuite/gcc.target/i386/pr102080.c | 19 ++++++++++++++++ > gcc/tree.c | 29 ++++++++++++++++++++++++ > gcc/tree.h | 1 + > 4 files changed, 53 insertions(+), 4 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/i386/pr102080.c > > diff --git a/gcc/match.pd b/gcc/match.pd > index 008f7758c96..41f9e6d97f0 100644 > --- a/gcc/match.pd > +++ b/gcc/match.pd > @@ -7020,13 +7020,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (vec_cond @0 (view_convert? (uncond_op@4 @1 @2)) @3) > (with { tree op_type = TREE_TYPE (@4); } > (if (vectorized_internal_fn_supported_p (as_internal_fn (cond_op), > op_type) > - && element_precision (type) == element_precision (op_type)) > + && is_truth_type_for (op_type, TREE_TYPE (@0))) > (view_convert (cond_op @0 @1 @2 (view_convert:op_type @3)))))) > (simplify > (vec_cond @0 @1 (view_convert? (uncond_op@4 @2 @3))) > (with { tree op_type = TREE_TYPE (@4); } > (if (vectorized_internal_fn_supported_p (as_internal_fn (cond_op), > op_type) > - && element_precision (type) == element_precision (op_type)) > + && is_truth_type_for (op_type, TREE_TYPE (@0))) > (view_convert (cond_op (bit_not @0) @2 @3 (view_convert:op_type @1))))))) > > /* Same for ternary operations. */ > @@ -7036,13 +7036,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) > (vec_cond @0 (view_convert? (uncond_op@5 @1 @2 @3)) @4) > (with { tree op_type = TREE_TYPE (@5); } > (if (vectorized_internal_fn_supported_p (as_internal_fn (cond_op), > op_type) > - && element_precision (type) == element_precision (op_type)) > + && is_truth_type_for (op_type, TREE_TYPE (@0))) > (view_convert (cond_op @0 @1 @2 @3 (view_convert:op_type @4)))))) > (simplify > (vec_cond @0 @1 (view_convert? (uncond_op@5 @2 @3 @4))) > (with { tree op_type = TREE_TYPE (@5); } > (if (vectorized_internal_fn_supported_p (as_internal_fn (cond_op), > op_type) > - && element_precision (type) == element_precision (op_type)) > + && is_truth_type_for (op_type, TREE_TYPE (@0))) > (view_convert (cond_op (bit_not @0) @2 @3 @4 > (view_convert:op_type @1))))))) > #endif > diff --git a/gcc/testsuite/gcc.target/i386/pr102080.c > b/gcc/testsuite/gcc.target/i386/pr102080.c > new file mode 100644 > index 00000000000..4c5ee32ee63 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/pr102080.c > @@ -0,0 +1,19 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2" } */ > + > +#include<immintrin.h> > +typedef float __m256 __attribute__((__vector_size__(32))); > +__m256 _mm256_blendv_ps___Y, _mm256_blendv_ps___M, _mm256_mul_ps___A, > + _mm256_mul_ps___B, IfThenElse___trans_tmp_9; > + > +void > +__attribute__ ((target("avx"))) > +IfThenElse (__m256 no) { > + IfThenElse___trans_tmp_9 = _mm256_blendv_ps (no, _mm256_blendv_ps___Y, > _mm256_blendv_ps___M); > +} > +void > +__attribute__ ((target("avx512vl"))) > +EncodedFromDisplay() { > + __m256 __trans_tmp_11 = _mm256_mul_ps___A * _mm256_mul_ps___B; > + IfThenElse(__trans_tmp_11); > +} > diff --git a/gcc/tree.c b/gcc/tree.c > index 3d15948fd1a..994775d7314 100644 > --- a/gcc/tree.c > +++ b/gcc/tree.c > @@ -10737,6 +10737,35 @@ signed_type_for (tree type) > return signed_or_unsigned_type_for (0, type); > } > > +/* - For VECTOR_TYPEs: > + - The truth type must be a VECTOR_BOOLEAN_TYPE. > + - The number of elements must match (known_eq). > + - targetm.vectorize.get_mask_mode exists, and exactly > + the same mode as the truth type. > + - Otherwise, the truth type must be a BOOLEAN_TYPE > + or useless_type_conversion_p to BOOLEAN_TYPE. */ > +bool > +is_truth_type_for (tree type, tree truth_type) > +{ > + machine_mode mask_mode = TYPE_MODE (truth_type); > + machine_mode vmode = TYPE_MODE (type); > + machine_mode tmask_mode; > + > + if (TREE_CODE (type) == VECTOR_TYPE) > + { > + if (VECTOR_BOOLEAN_TYPE_P (truth_type) > + && known_eq (TYPE_VECTOR_SUBPARTS (type), > + TYPE_VECTOR_SUBPARTS (truth_type)) > + && targetm.vectorize.get_mask_mode (vmode).exists (&tmask_mode) > + && tmask_mode == mask_mode) > + return true; > + > + return false; > + } > + > + return useless_type_conversion_p (boolean_type_node, truth_type); > +} > + > /* If TYPE is a vector type, return a signed integer vector type with the > same width and number of subparts. Otherwise return boolean_type_node. */ > > diff --git a/gcc/tree.h b/gcc/tree.h > index 7274ba75f59..06c027da450 100644 > --- a/gcc/tree.h > +++ b/gcc/tree.h > @@ -4591,6 +4591,7 @@ extern tree build_string_literal (unsigned, const char > * = NULL, > extern tree signed_or_unsigned_type_for (int, tree); > extern tree signed_type_for (tree); > extern tree unsigned_type_for (tree); > +bool is_truth_type_for (tree, tree);
just for style add 'extern' to follow surrounding code. The patch looks OK to me with that change. Thanks, Richard. > extern tree truth_type_for (tree); > extern tree build_pointer_type_for_mode (tree, machine_mode, bool); > extern tree build_pointer_type (tree); > -- > 2.27.0 >