diff --git a/gcc/testsuite/gcc.dg/pr108692.c b/gcc/testsuite/gcc.dg/pr108692.c new file mode 100644 index 0000000000000000000000000000000000000000..fc25bf54e45d929295b0ccdaf4c3823697ad7fb9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr108692.c @@ -0,0 +1,31 @@ +/* PR tree-optimization/108692 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize" } */ + +__attribute__((noipa)) int +foo (signed char *x, signed char *y, int n) +{ + int i, r = 0; + signed char a, b; + for (i = 0; i < n; i++) + { + a = x[i]; + b = y[i]; + int c = (unsigned char) a - (unsigned char) b; + r = r + (c < 0 ? -c : c); + } + return r; +} + +int +main () +{ + signed char x[64] = {}, y[64] = {}; + if (__CHAR_BIT__ != 8 || __SIZEOF_INT__ != 4) + return 0; + x[32] = -128; + y[32] = 1; + if (foo (x, y, 64) != 127) + __builtin_abort (); + return 0; +} diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc index 6934aebc69f231af24668f0a1c3d140e97f55487..cefe331620f7166fa478de4bb3b66723206ec182 100644 --- a/gcc/tree-vect-patterns.cc +++ b/gcc/tree-vect-patterns.cc @@ -601,7 +601,25 @@ vect_widened_op_tree (vec_info *vinfo, stmt_vec_info stmt_info, tree_code code, if (shift_p && i == 1) return 0; - if (!vect_look_through_possible_promotion (vinfo, op, this_unprom)) + if (rhs_code != code) + { + /* If rhs_code is widened_code, don't look through further + possible promotions, there is a promotion already embedded + in the WIDEN_*_EXPR. */ + if (TREE_CODE (op) != SSA_NAME + || !INTEGRAL_TYPE_P (TREE_TYPE (op))) + return 0; + + stmt_vec_info def_stmt_info; + gimple *def_stmt; + vect_def_type dt; + if (!vect_is_simple_use (op, vinfo, &dt, &def_stmt_info, + &def_stmt)) + return 0; + this_unprom->set_op (op, dt, NULL); + } + else if (!vect_look_through_possible_promotion (vinfo, op, + this_unprom)) return 0; if (TYPE_PRECISION (this_unprom->type) == TYPE_PRECISION (type))