Hi, In over-widening pattern we expect the last statement to be a type demotion, but don't check this properly. The patch fixes the check, and also updates vect-widen-shift-u8.c to expect additional widening shift pattern instead of over-widening pattern.
Bootstrapped and tested on powerpc64-suse-linux and checked with cross for arm-linux-gnueabi. Committed. Ira ChangeLog: PR tree-optimization/51799 * tree-vect-patterns.c (vect_recog_over_widening_pattern): Check that the last operation is a type demotion. testsuite/ChangeLog: PR tree-optimization/51799 * gcc.dg/vect/pr51799.c: New test. * gcc.dg/vect/vect-widen-shift-u8.c: Expect two widening shift patterns. Index: testsuite/gcc.dg/vect/pr51799.c =================================================================== --- testsuite/gcc.dg/vect/pr51799.c (revision 0) +++ testsuite/gcc.dg/vect/pr51799.c (revision 0) @@ -0,0 +1,18 @@ +/* { dg-do compile } */ + +typedef signed char int8_t; +typedef unsigned char uint8_t; +typedef signed short int16_t; +typedef unsigned long uint32_t; +void +f0a (uint32_t * __restrict__ result, int8_t * __restrict__ arg1, + uint32_t * __restrict__ arg4, int8_t temp_6) +{ + int idx; + for (idx = 0; idx < 416; idx += 1) + { + result[idx] = (uint8_t)(((arg1[idx] << 7) + arg4[idx]) * temp_6); + } +} + +/* { dg-final { cleanup-tree-dump "vect" } } */ Index: testsuite/gcc.dg/vect/vect-widen-shift-u8.c =================================================================== --- testsuite/gcc.dg/vect/vect-widen-shift-u8.c (revision 183125) +++ testsuite/gcc.dg/vect/vect-widen-shift-u8.c (working copy) @@ -59,7 +59,6 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump-times "vect_recog_widen_shift_pattern: detected" 1 "vect" { target vect_widen_shift } } } */ +/* { dg-final { scan-tree-dump-times "vect_recog_widen_shift_pattern: detected" 2 "vect" { target vect_widen_shift } } } */ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ /* { dg-final { cleanup-tree-dump "vect" } } */ - Index: tree-vect-patterns.c =================================================================== --- tree-vect-patterns.c (revision 183125) +++ tree-vect-patterns.c (working copy) @@ -1186,13 +1186,15 @@ vect_recog_over_widening_pattern (VEC (gimple, hea { use_lhs = gimple_assign_lhs (use_stmt); use_type = TREE_TYPE (use_lhs); - /* Support only type promotion or signedess change. Check that USE_TYPE - is not bigger than the original type. */ + /* Support only type demotion or signedess change. */ if (!INTEGRAL_TYPE_P (use_type) - || TYPE_PRECISION (new_type) > TYPE_PRECISION (use_type) - || TYPE_PRECISION (type) < TYPE_PRECISION (use_type)) + || TYPE_PRECISION (type) <= TYPE_PRECISION (use_type)) return NULL; + /* Check that NEW_TYPE is not bigger than the conversion result. */ + if (TYPE_PRECISION (new_type) > TYPE_PRECISION (use_type)) + return NULL; + if (TYPE_UNSIGNED (new_type) != TYPE_UNSIGNED (use_type) || TYPE_PRECISION (new_type) != TYPE_PRECISION (use_type)) {