From 7eb5baff994b249c0fb5d913e6f7afa7b9fbbc63 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 17 Jul 2019 09:13:17 +0200 Subject: [PATCH] re PR tree-optimization/91157 (ICE: verify_gimple failed (error: position plus size exceeds size of referenced object in 'bit_field_ref')) PR tree-optimization/91157 * tree-vect-generic.c (expand_vector_comparison): Handle lhs being a vector boolean with scalar mode. (expand_vector_condition): Handle first operand being a vector boolean with scalar mode. (expand_vector_operations_1): For comparisons, don't bail out early if the return type is vector boolean with scalar mode, but comparison operand type is not. * gcc.target/i386/avx512f-pr91157.c: New test. * gcc.target/i386/avx512bw-pr91157.c: New test. From-SVN: r273543 --- gcc/ChangeLog | 11 +++ gcc/testsuite/ChangeLog | 6 ++ .../gcc.target/i386/avx512bw-pr91157.c | 6 ++ .../gcc.target/i386/avx512f-pr91157.c | 29 ++++++++ gcc/tree-vect-generic.c | 73 ++++++++++++++++++- 5 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/avx512bw-pr91157.c create mode 100644 gcc/testsuite/gcc.target/i386/avx512f-pr91157.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 36ebe6edfaa..df997772708 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2019-07-17 Jakub Jelinek + + PR tree-optimization/91157 + * tree-vect-generic.c (expand_vector_comparison): Handle lhs being + a vector boolean with scalar mode. + (expand_vector_condition): Handle first operand being a vector boolean + with scalar mode. + (expand_vector_operations_1): For comparisons, don't bail out early + if the return type is vector boolean with scalar mode, but comparison + operand type is not. + 2019-07-17 Richard Biener PR tree-optimization/91181 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9cf270f098f..5c156c7738f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2019-07-17 Jakub Jelinek + + PR tree-optimization/91157 + * gcc.target/i386/avx512f-pr91157.c: New test. + * gcc.target/i386/avx512bw-pr91157.c: New test. + 2019-07-17 Richard Biener PR tree-optimization/91181 diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-pr91157.c b/gcc/testsuite/gcc.target/i386/avx512bw-pr91157.c new file mode 100644 index 00000000000..602d922eda9 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512bw-pr91157.c @@ -0,0 +1,6 @@ +/* PR tree-optimization/91157 */ +/* { dg-do run { target { avx512bw && lp64 } } } */ +/* { dg-options "-O2 -mavx512bw -fexceptions -fnon-call-exceptions -fsignaling-nans" } */ + +#define AVX512BW +#include "avx512f-pr91157.c" diff --git a/gcc/testsuite/gcc.target/i386/avx512f-pr91157.c b/gcc/testsuite/gcc.target/i386/avx512f-pr91157.c new file mode 100644 index 00000000000..c7d0d8b4030 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/avx512f-pr91157.c @@ -0,0 +1,29 @@ +/* PR tree-optimization/91157 */ +/* { dg-do run { target { avx512f && lp64 } } } */ +/* { dg-options "-O2 -mavx512f -fexceptions -fnon-call-exceptions -fsignaling-nans" } */ + +#include "avx512f-helper.h" + +typedef long double V __attribute__ ((vector_size (4 * sizeof (long double)))); +typedef __int128 W __attribute__ ((vector_size (4 * sizeof (__int128)))); + +__attribute__((noipa)) W +foo (V x) +{ + return x == 0; +} + +static void +test_512 (void) +{ + V a = { 5.0L, 0.0L, -0.0L, -17.0L }; + V b = { -0.0L, 16.0L, 0.0L, 18.0L }; + V c = { 6.0L, 7.0L, 8.0L, 0.0L }; + W ar = foo (a); + W br = foo (b); + W cr = foo (c); + if (ar[0] != 0 || ar[1] != -1 || ar[2] != -1 || ar[3] != 0 + || br[0] != -1 || br[1] != 0 || br[2] != -1 || br[3] != 0 + || cr[0] != 0 || cr[1] != 0 || cr[2] != 0 || cr[3] != -1) + __builtin_abort (); +} diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c index 8389f5555e8..6fcd37c8a69 100644 --- a/gcc/tree-vect-generic.c +++ b/gcc/tree-vect-generic.c @@ -382,8 +382,48 @@ expand_vector_comparison (gimple_stmt_iterator *gsi, tree type, tree op0, tree t; if (!expand_vec_cmp_expr_p (TREE_TYPE (op0), type, code) && !expand_vec_cond_expr_p (type, TREE_TYPE (op0), code)) - t = expand_vector_piecewise (gsi, do_compare, type, - TREE_TYPE (TREE_TYPE (op0)), op0, op1, code); + { + if (VECTOR_BOOLEAN_TYPE_P (type) + && VECTOR_BOOLEAN_TYPE_P (type) + && SCALAR_INT_MODE_P (TYPE_MODE (type)) + && known_lt (GET_MODE_BITSIZE (TYPE_MODE (type)), + TYPE_VECTOR_SUBPARTS (type) + * GET_MODE_BITSIZE (SCALAR_TYPE_MODE + (TREE_TYPE (type))))) + { + tree inner_type = TREE_TYPE (TREE_TYPE (op0)); + tree part_width = TYPE_SIZE (inner_type); + tree index = bitsize_int (0); + int nunits = nunits_for_known_piecewise_op (TREE_TYPE (op0)); + int prec = GET_MODE_PRECISION (SCALAR_TYPE_MODE (type)); + tree ret_type = build_nonstandard_integer_type (prec, 1); + tree ret_inner_type = boolean_type_node; + int i; + location_t loc = gimple_location (gsi_stmt (*gsi)); + t = build_zero_cst (ret_type); + + if (TYPE_PRECISION (ret_inner_type) != 1) + ret_inner_type = build_nonstandard_integer_type (1, 1); + warning_at (loc, OPT_Wvector_operation_performance, + "vector operation will be expanded piecewise"); + for (i = 0; i < nunits; + i++, index = int_const_binop (PLUS_EXPR, index, part_width)) + { + tree a = tree_vec_extract (gsi, inner_type, op0, part_width, + index); + tree b = tree_vec_extract (gsi, inner_type, op1, part_width, + index); + tree result = gimplify_build2 (gsi, code, ret_inner_type, a, b); + t = gimplify_build3 (gsi, BIT_INSERT_EXPR, ret_type, t, result, + bitsize_int (i)); + } + t = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, type, t); + } + else + t = expand_vector_piecewise (gsi, do_compare, type, + TREE_TYPE (TREE_TYPE (op0)), op0, op1, + code); + } else t = NULL_TREE; @@ -879,6 +919,7 @@ expand_vector_condition (gimple_stmt_iterator *gsi) tree a1 = a; tree a2 = NULL_TREE; bool a_is_comparison = false; + bool a_is_scalar_bitmask = false; tree b = gimple_assign_rhs2 (stmt); tree c = gimple_assign_rhs3 (stmt); vec *v; @@ -942,6 +983,20 @@ expand_vector_condition (gimple_stmt_iterator *gsi) warning_at (loc, OPT_Wvector_operation_performance, "vector condition will be expanded piecewise"); + if (!a_is_comparison + && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (a)) + && SCALAR_INT_MODE_P (TYPE_MODE (TREE_TYPE (a))) + && known_lt (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (a))), + TYPE_VECTOR_SUBPARTS (TREE_TYPE (a)) + * GET_MODE_BITSIZE (SCALAR_TYPE_MODE + (TREE_TYPE (TREE_TYPE (a)))))) + { + a_is_scalar_bitmask = true; + int prec = GET_MODE_PRECISION (SCALAR_TYPE_MODE (TREE_TYPE (a))); + tree atype = build_nonstandard_integer_type (prec, 1); + a = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, atype, a); + } + int nunits = nunits_for_known_piecewise_op (type); vec_alloc (v, nunits); for (i = 0; i < nunits; i++) @@ -957,6 +1012,14 @@ expand_vector_condition (gimple_stmt_iterator *gsi) comp_width, comp_index); aa = fold_build2 (TREE_CODE (a), cond_type, aa1, aa2); } + else if (a_is_scalar_bitmask) + { + wide_int w = wi::set_bit_in_zero (i, TYPE_PRECISION (TREE_TYPE (a))); + result = gimplify_build2 (gsi, BIT_AND_EXPR, TREE_TYPE (a), + a, wide_int_to_tree (TREE_TYPE (a), w)); + aa = fold_build2 (NE_EXPR, boolean_type_node, result, + build_zero_cst (TREE_TYPE (a))); + } else aa = tree_vec_extract (gsi, cond_type, a, width, index); result = gimplify_build3 (gsi, COND_EXPR, inner_type, aa, bb, cc); @@ -1941,7 +2004,11 @@ expand_vector_operations_1 (gimple_stmt_iterator *gsi) /* A scalar operation pretending to be a vector one. */ if (VECTOR_BOOLEAN_TYPE_P (type) && !VECTOR_MODE_P (TYPE_MODE (type)) - && TYPE_MODE (type) != BLKmode) + && TYPE_MODE (type) != BLKmode + && (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) != tcc_comparison + || (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (rhs1)) + && !VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (rhs1))) + && TYPE_MODE (TREE_TYPE (rhs1)) != BLKmode))) return; /* If the vector operation is operating on all same vector elements -- 2.30.2