From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 130054 invoked by alias); 13 Nov 2015 10:38:36 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 130041 invoked by uid 89); 13 Nov 2015 10:38:35 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-yk0-f175.google.com Received: from mail-yk0-f175.google.com (HELO mail-yk0-f175.google.com) (209.85.160.175) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Fri, 13 Nov 2015 10:38:33 +0000 Received: by ykba77 with SMTP id a77so138912412ykb.2 for ; Fri, 13 Nov 2015 02:38:31 -0800 (PST) MIME-Version: 1.0 X-Received: by 10.13.202.141 with SMTP id m135mr19720222ywd.305.1447411111720; Fri, 13 Nov 2015 02:38:31 -0800 (PST) Received: by 10.37.93.11 with HTTP; Fri, 13 Nov 2015 02:38:31 -0800 (PST) In-Reply-To: <20151112154400.GE51435@msticlxl57.ims.intel.com> References: <20151112154400.GE51435@msticlxl57.ims.intel.com> Date: Fri, 13 Nov 2015 10:38:00 -0000 Message-ID: Subject: Re: [PATCH] Fix ICE for boolean comparison From: Richard Biener To: Ilya Enkovich Cc: GCC Patches Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes X-SW-Source: 2015-11/txt/msg01651.txt.bz2 On Thu, Nov 12, 2015 at 4:44 PM, Ilya Enkovich wro= te: > Hi, > > Currently compiler may ICE when loaded boolean is compared with vector in= variant or another boolean value. This is because we don't detect mix of b= ool and non-bool vectypes and incorrectly determine vectype for boolean loo= p invariant for comparison. This was fixed for COND_EXP before but also ne= eds to be fixed for comparison. This patch was bootstrapped and tested on = x86_64-unknown-linux-gnu. OK for trunk? Hmm, so this disables vectorization in these cases. Isn't this a regression? Shouldn't we simply "materialize" the non-bool vector from the boolean one say, with vec =3D boolvec ? {-1, -1 ... } : {0, 0, 0 ...} ? Thanks, Richard. > Thanks, > Ilya > -- > gcc/ > > 2015-11-12 Ilya Enkovich > > * tree-vect-loop.c (vect_determine_vectorization_factor): Check > mix of boolean and integer vectors in a single statement. > * tree-vect-slp.c (vect_mask_constant_operand_p): New. > (vect_get_constant_vectors): Use vect_mask_constant_operand_p to > determine constant type. > * tree-vect-stmts.c (vectorizable_comparison): Provide vectype > for loop invariants. > > gcc/testsuite/ > > 2015-11-12 Ilya Enkovich > > * g++.dg/vect/simd-bool-comparison-1.cc: New test. > * g++.dg/vect/simd-bool-comparison-2.cc: New test. > > > diff --git a/gcc/testsuite/g++.dg/vect/simd-bool-comparison-1.cc b/gcc/te= stsuite/g++.dg/vect/simd-bool-comparison-1.cc > new file mode 100644 > index 0000000..a08362f > --- /dev/null > +++ b/gcc/testsuite/g++.dg/vect/simd-bool-comparison-1.cc > @@ -0,0 +1,21 @@ > +// { dg-do compile } > +// { dg-additional-options "-mavx512bw -mavx512dq" { target { i?86-*-* x= 86_64-*-* } } } > + > +#define N 1024 > + > +double a[N]; > +bool b[N]; > +bool c; > + > +void test () > +{ > + int i; > + > + for (i =3D 0; i < N; i++) > + if (b[i] !=3D c) > + a[i] =3D 0.0; > + else > + a[i] =3D 1.0; > +} > + > +// { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { tar= get { i?86-*-* x86_64-*-* } } } } > diff --git a/gcc/testsuite/g++.dg/vect/simd-bool-comparison-2.cc b/gcc/te= stsuite/g++.dg/vect/simd-bool-comparison-2.cc > new file mode 100644 > index 0000000..4accf56 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/vect/simd-bool-comparison-2.cc > @@ -0,0 +1,20 @@ > +// { dg-do compile } > +// { dg-additional-options "-mavx512bw -mavx512dq" { target { i?86-*-* x= 86_64-*-* } } } > + > +#define N 1024 > + > +double a[N]; > +bool b[N]; > +char c[N]; > + > +void test () > +{ > + int i; > + > + #pragma omp simd > + for (i =3D 0; i < N; i++) > + if ((c[i] > 0) && b[i]) > + a[i] =3D 0.0; > + else > + a[i] =3D 1.0; > +} > diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c > index 55e5309..6b78b55 100644 > --- a/gcc/tree-vect-loop.c > +++ b/gcc/tree-vect-loop.c > @@ -649,7 +649,32 @@ vect_determine_vectorization_factor (loop_vec_info l= oop_vinfo) > } > return false; > } > + else if (VECTOR_BOOLEAN_TYPE_P (mask_type) > + !=3D VECTOR_BOOLEAN_TYPE_P (vectype)) > + { > + if (dump_enabled_p ()) > + { > + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_loca= tion, > + "not vectorized: mixed mask and " > + "nonmask vector types in statement= , "); > + dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLI= M, > + mask_type); > + dump_printf (MSG_MISSED_OPTIMIZATION, " and "); > + dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLI= M, > + vectype); > + dump_printf (MSG_MISSED_OPTIMIZATION, "\n"); > + } > + return false; > + } > } > + > + /* We may compare boolean value loaded as vector of integers. > + Fix mask_type in such case. */ > + if (mask_type > + && !VECTOR_BOOLEAN_TYPE_P (mask_type) > + && gimple_code (stmt) =3D=3D GIMPLE_ASSIGN > + && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) =3D=3D t= cc_comparison) > + mask_type =3D build_same_sized_truth_vector_type (mask_type); > } > > /* No mask_type should mean loop invariant predicate. > diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c > index 9d97140..f3acb04 100644 > --- a/gcc/tree-vect-slp.c > +++ b/gcc/tree-vect-slp.c > @@ -2589,6 +2589,57 @@ vect_slp_bb (basic_block bb) > } > > > +/* Return 1 if vector type of boolean constant which is OPNUM > + operand in statement STMT is a boolean vector. */ > + > +static bool > +vect_mask_constant_operand_p (gimple *stmt, int opnum) > +{ > + stmt_vec_info stmt_vinfo =3D vinfo_for_stmt (stmt); > + enum tree_code code =3D gimple_expr_code (stmt); > + tree op, vectype; > + gimple *def_stmt; > + enum vect_def_type dt; > + > + /* For comparison and COND_EXPR type is chosen depending > + on the other comparison operand. */ > + if (TREE_CODE_CLASS (code) =3D=3D tcc_comparison) > + { > + if (opnum) > + op =3D gimple_assign_rhs1 (stmt); > + else > + op =3D gimple_assign_rhs2 (stmt); > + > + if (!vect_is_simple_use (op, stmt_vinfo->vinfo, &def_stmt, > + &dt, &vectype)) > + gcc_unreachable (); > + > + return !vectype || VECTOR_BOOLEAN_TYPE_P (vectype); > + } > + > + if (code =3D=3D COND_EXPR) > + { > + tree cond =3D gimple_assign_rhs1 (stmt); > + > + if (TREE_CODE (cond) =3D=3D SSA_NAME) > + return false; > + > + if (opnum) > + op =3D TREE_OPERAND (cond, 1); > + else > + op =3D TREE_OPERAND (cond, 0); > + > + if (!vect_is_simple_use (op, stmt_vinfo->vinfo, &def_stmt, > + &dt, &vectype)) > + gcc_unreachable (); > + > + return !vectype || VECTOR_BOOLEAN_TYPE_P (vectype); > + } > + > + return VECTOR_BOOLEAN_TYPE_P (STMT_VINFO_VECTYPE (stmt_vinfo)); > +} > + > + > /* For constant and loop invariant defs of SLP_NODE this function returns > (vector) defs (VEC_OPRNDS) that will be used in the vectorized stmts. > OP_NUM determines if we gather defs for operand 0 or operand 1 of the= RHS of > @@ -2625,8 +2676,7 @@ vect_get_constant_vectors (tree op, slp_tree slp_no= de, > > /* Check if vector type is a boolean vector. */ > if (TREE_CODE (TREE_TYPE (op)) =3D=3D BOOLEAN_TYPE > - && (VECTOR_BOOLEAN_TYPE_P (STMT_VINFO_VECTYPE (stmt_vinfo)) > - || (code =3D=3D COND_EXPR && op_num < 2))) > + && vect_mask_constant_operand_p (stmt, op_num)) > vector_type > =3D build_same_sized_truth_vector_type (STMT_VINFO_VECTYPE (stmt_v= info)); > else > diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c > index cfe30e0..c990dfa 100644 > --- a/gcc/tree-vect-stmts.c > +++ b/gcc/tree-vect-stmts.c > @@ -7642,8 +7642,8 @@ vectorizable_comparison (gimple *stmt, gimple_stmt_= iterator *gsi, > } > else > { > - vec_rhs1 =3D vect_get_vec_def_for_operand (rhs1, stmt, NULL= ); > - vec_rhs2 =3D vect_get_vec_def_for_operand (rhs2, stmt, NULL= ); > + vec_rhs1 =3D vect_get_vec_def_for_operand (rhs1, stmt, vect= ype); > + vec_rhs2 =3D vect_get_vec_def_for_operand (rhs2, stmt, vect= ype); > } > } > else