From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1666) id 9B5303858C5F; Fri, 4 Aug 2023 11:15:16 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9B5303858C5F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1691147716; bh=i2uq8uyML6Zf+GtUE99zTyOydc3gei58Aya7bi8cL4c=; h=From:To:Subject:Date:From; b=qE+2Vob7BrLzlqZ/+mqOHrPo2PkOdIlGL8ag5+RIIu3H06dRZ/y3TlIqVdT9JpiLL maXjN6KWuzTK2vHCFHPgRDrGfe1gJcVGmcEllCxg8EQmbTEY6yTCjDXVljM1SmuzRd ntD+e0WrB46y+2r/1uvkt+jebcGQqLhXyUV8FYX0= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Richard Biener To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-2987] tree-optimization/110838 - vectorization of widened right shifts X-Act-Checkin: gcc X-Git-Author: Richard Biener X-Git-Refname: refs/heads/master X-Git-Oldrev: 0782b01c9ea43d43648071faa9c65a101f5068a2 X-Git-Newrev: 1a599caab86464006ea8c9501aff6c6638e891eb Message-Id: <20230804111516.9B5303858C5F@sourceware.org> Date: Fri, 4 Aug 2023 11:15:16 +0000 (GMT) List-Id: https://gcc.gnu.org/g:1a599caab86464006ea8c9501aff6c6638e891eb commit r14-2987-g1a599caab86464006ea8c9501aff6c6638e891eb Author: Richard Biener Date: Fri Aug 4 12:11:45 2023 +0200 tree-optimization/110838 - vectorization of widened right shifts The following fixes a problem with my last attempt of avoiding out-of-bound shift values for vectorized right shifts of widened operands. Instead of truncating the shift amount with a bitwise and we actually need to saturate it to the target precision. The following does that and adds test coverage for the constant and invariant but variable case that would previously have failed. PR tree-optimization/110838 * tree-vect-patterns.cc (vect_recog_over_widening_pattern): Fix right-shift value sanitizing. Properly emit external def mangling in the preheader rather than in the pattern def sequence where it will fail vectorizing. * gcc.dg/vect/pr110838.c: New testcase. Diff: --- gcc/testsuite/gcc.dg/vect/pr110838.c | 31 +++++++++++++++++++++++++++++++ gcc/tree-vect-patterns.cc | 22 +++++++++++++++++----- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/gcc/testsuite/gcc.dg/vect/pr110838.c b/gcc/testsuite/gcc.dg/vect/pr110838.c new file mode 100644 index 00000000000..cf8765be603 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr110838.c @@ -0,0 +1,31 @@ +/* { dg-do run } */ + +#include "tree-vect.h" + +short a[32], b[32]; + +void __attribute__((noipa)) foo () +{ + for (int i = 0; i < 32; ++i) + a[i] = b[i] >> 16; +} + +void __attribute__((noipa)) bar (int n) +{ + int np = n & 31; + for (int i = 0; i < 32; ++i) + a[i] = b[i] >> np; +} + +int main () +{ + check_vect (); + b[0] = -8; + foo (); + if (a[0] != -1) + abort (); + bar (16); + if (a[0] != -1) + abort (); + return 0; +} diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc index e4ab8c2d65b..2cedf238450 100644 --- a/gcc/tree-vect-patterns.cc +++ b/gcc/tree-vect-patterns.cc @@ -3109,8 +3109,8 @@ vect_recog_over_widening_pattern (vec_info *vinfo, wide_int min_value, max_value; if (TREE_CODE (ops[1]) == INTEGER_CST) ops[1] = wide_int_to_tree (op_type, - wi::bit_and (wi::to_wide (ops[1]), - new_precision - 1)); + wi::umin (wi::to_wide (ops[1]), + new_precision - 1)); else if (!vect_get_range_info (ops[1], &min_value, &max_value) || wi::ge_p (max_value, new_precision, TYPE_SIGN (op_type))) { @@ -3118,11 +3118,23 @@ vect_recog_over_widening_pattern (vec_info *vinfo, same argument widened shifts and it un-CSEs same arguments. */ tree new_var = vect_recog_temp_ssa_var (op_type, NULL); gimple *pattern_stmt - = gimple_build_assign (new_var, BIT_AND_EXPR, ops[1], + = gimple_build_assign (new_var, MIN_EXPR, ops[1], build_int_cst (op_type, new_precision - 1)); - ops[1] = new_var; gimple_set_location (pattern_stmt, gimple_location (last_stmt)); - append_pattern_def_seq (vinfo, last_stmt_info, pattern_stmt); + if (unprom[1].dt == vect_external_def) + { + if (edge e = vect_get_external_def_edge (vinfo, ops[1])) + { + basic_block new_bb + = gsi_insert_on_edge_immediate (e, pattern_stmt); + gcc_assert (!new_bb); + } + else + return NULL; + } + else + append_pattern_def_seq (vinfo, last_stmt_info, pattern_stmt); + ops[1] = new_var; } }