From patchwork Thu Nov 12 15:44:00 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Enkovich X-Patchwork-Id: 543408 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 6FCE4141409 for ; Fri, 13 Nov 2015 02:46:26 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=ZIdAlufs; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=F8wcPKBexQIcmxL0X5TsRVqY3zDoOoMEhKWICrlgNc6UkKOm0f0zU TIkW8Akn9pwgbJOOOq+x0GUaws1zis6vFGVUf01otY6yG3k6AgC6ao18zBxTvYhE LOo0b9fcJBqdRPMjycrcIgc6SjPgVBJinX8cJT5QKQZGLxy17lab/I= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=dcAmNflJET9mM3imV95LG8xq/uM=; b=ZIdAlufs6RzFaqWpSkqP W3TXDy4wncCj/L9HO3mZ2FSqgkL1WtF+AjYgf75QawEdD9LejzRciSJwp1vwh2zy YZ0d/kdosG8mWUQP0H3LXHWKgzv8CE3UB6M8dS8gBv4c74Kg0M5Bet5fbhYd7cxw GGgidu8qczZUV9q4ki3FblA= Received: (qmail 95116 invoked by alias); 12 Nov 2015 15:46:19 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 95103 invoked by uid 89); 12 Nov 2015 15:46:18 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-qg0-f48.google.com Received: from mail-qg0-f48.google.com (HELO mail-qg0-f48.google.com) (209.85.192.48) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Thu, 12 Nov 2015 15:46:17 +0000 Received: by qgea14 with SMTP id a14so49294443qge.0 for ; Thu, 12 Nov 2015 07:46:15 -0800 (PST) X-Received: by 10.140.172.3 with SMTP id s3mr17515830qhs.6.1447343175102; Thu, 12 Nov 2015 07:46:15 -0800 (PST) Received: from msticlxl57.ims.intel.com (jfdmzpr03-ext.jf.intel.com. [134.134.139.72]) by smtp.gmail.com with ESMTPSA id f129sm4147104qhe.45.2015.11.12.07.46.12 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 12 Nov 2015 07:46:14 -0800 (PST) Date: Thu, 12 Nov 2015 18:44:00 +0300 From: Ilya Enkovich To: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix ICE for boolean comparison Message-ID: <20151112154400.GE51435@msticlxl57.ims.intel.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes Hi, Currently compiler may ICE when loaded boolean is compared with vector invariant or another boolean value. This is because we don't detect mix of bool and non-bool vectypes and incorrectly determine vectype for boolean loop invariant for comparison. This was fixed for COND_EXP before but also needs to be fixed for comparison. This patch was bootstrapped and tested on x86_64-unknown-linux-gnu. OK for trunk? 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/testsuite/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-*-* x86_64-*-* } } } + +#define N 1024 + +double a[N]; +bool b[N]; +bool c; + +void test () +{ + int i; + + for (i = 0; i < N; i++) + if (b[i] != c) + a[i] = 0.0; + else + a[i] = 1.0; +} + +// { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { i?86-*-* x86_64-*-* } } } } diff --git a/gcc/testsuite/g++.dg/vect/simd-bool-comparison-2.cc b/gcc/testsuite/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-*-* x86_64-*-* } } } + +#define N 1024 + +double a[N]; +bool b[N]; +char c[N]; + +void test () +{ + int i; + + #pragma omp simd + for (i = 0; i < N; i++) + if ((c[i] > 0) && b[i]) + a[i] = 0.0; + else + a[i] = 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 loop_vinfo) } return false; } + else if (VECTOR_BOOLEAN_TYPE_P (mask_type) + != VECTOR_BOOLEAN_TYPE_P (vectype)) + { + if (dump_enabled_p ()) + { + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "not vectorized: mixed mask and " + "nonmask vector types in statement, "); + dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, + mask_type); + dump_printf (MSG_MISSED_OPTIMIZATION, " and "); + dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, + 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) == GIMPLE_ASSIGN + && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison) + mask_type = 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 = vinfo_for_stmt (stmt); + enum tree_code code = 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) == tcc_comparison) + { + if (opnum) + op = gimple_assign_rhs1 (stmt); + else + op = 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 == COND_EXPR) + { + tree cond = gimple_assign_rhs1 (stmt); + + if (TREE_CODE (cond) == SSA_NAME) + return false; + + if (opnum) + op = TREE_OPERAND (cond, 1); + else + op = 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_node, /* Check if vector type is a boolean vector. */ if (TREE_CODE (TREE_TYPE (op)) == BOOLEAN_TYPE - && (VECTOR_BOOLEAN_TYPE_P (STMT_VINFO_VECTYPE (stmt_vinfo)) - || (code == COND_EXPR && op_num < 2))) + && vect_mask_constant_operand_p (stmt, op_num)) vector_type = build_same_sized_truth_vector_type (STMT_VINFO_VECTYPE (stmt_vinfo)); 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 = vect_get_vec_def_for_operand (rhs1, stmt, NULL); - vec_rhs2 = vect_get_vec_def_for_operand (rhs2, stmt, NULL); + vec_rhs1 = vect_get_vec_def_for_operand (rhs1, stmt, vectype); + vec_rhs2 = vect_get_vec_def_for_operand (rhs2, stmt, vectype); } } else