diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/pr98302.c | 22 | ||||
-rw-r--r-- | gcc/tree-vect-patterns.c | 13 |
2 files changed, 33 insertions, 2 deletions
diff --git a/gcc/testsuite/gcc.dg/vect/pr98302.c b/gcc/testsuite/gcc.dg/vect/pr98302.c new file mode 100644 index 0000000..dec6016 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr98302.c @@ -0,0 +1,22 @@ +#include "tree-vect.h" + +int c = 1705; +char a; +long f = 50887638; +unsigned long long *h(unsigned long long *k, unsigned long long *l) { + return *k ? k : l; +} +void aa() {} +int main() { + check_vect (); + + long d = f; + for (char g = 0; g < (char)c - 10; g += 2) { + unsigned long long i = d, j = 4; + a = *h(&i, &j) << ((d ? 169392992 : 0) - 169392955LL); + } + if (a) + __builtin_abort(); + + return 0; +} diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index ff1358a..081ae80 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -4961,10 +4961,19 @@ vect_determine_precisions_from_users (stmt_vec_info stmt_info, gassign *stmt) unsigned int const_shift = TREE_INT_CST_LOW (shift); if (code == LSHIFT_EXPR) { + /* Avoid creating an undefined shift. + + ??? We could instead use min_output_precision as-is and + optimize out-of-range shifts to zero. However, only + degenerate testcases shift away all their useful input data, + and it isn't natural to drop input operations in the middle + of vectorization. This sort of thing should really be + handled before vectorization. */ + operation_precision = MAX (stmt_info->min_output_precision, + const_shift + 1); /* We need CONST_SHIFT fewer bits of the input. */ - operation_precision = stmt_info->min_output_precision; min_input_precision = (MAX (operation_precision, const_shift) - - const_shift); + - const_shift); } else { |